mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[core] improved error and cancellation handling
* return standard Windows error codes where possible * add custom error codes that follow the Windows error format * automatically close cancel MessageBox if the process completes
This commit is contained in:
		
							parent
							
								
									23b1f55338
								
							
						
					
					
						commit
						d6c66e0d09
					
				
					 2 changed files with 51 additions and 44 deletions
				
			
		
							
								
								
									
										84
									
								
								rufus.c
									
										
									
									
									
								
							
							
						
						
									
										84
									
								
								rufus.c
									
										
									
									
									
								
							|  | @ -84,7 +84,7 @@ struct { | ||||||
| static HWND hDeviceList, hCapacity, hFileSystem, hLabel; | static HWND hDeviceList, hCapacity, hFileSystem, hLabel; | ||||||
| static HWND hDeviceTooltip = NULL, hFSTooltip = NULL; | static HWND hDeviceTooltip = NULL, hFSTooltip = NULL; | ||||||
| static StrArray DriveID, DriveLabel; | static StrArray DriveID, DriveLabel; | ||||||
| static DWORD FormatErr; | static DWORD FormatStatus; | ||||||
| 
 | 
 | ||||||
| #ifdef RUFUS_DEBUG | #ifdef RUFUS_DEBUG | ||||||
| void _uprintf(const char *format, ...) | void _uprintf(const char *format, ...) | ||||||
|  | @ -209,7 +209,7 @@ static BOOL GetDriveHandle(DWORD DriveIndex, HANDLE* hDrive, char* DriveLetter, | ||||||
| 					safe_closehandle(*hDrive); | 					safe_closehandle(*hDrive); | ||||||
| 					return FALSE; | 					return FALSE; | ||||||
| 				} | 				} | ||||||
| 				uprintf("Warning: Opening %s drive for write access\n", drive_name); | 				uprintf("Caution: Opened %s drive for write access\n", drive_name); | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  | @ -217,7 +217,7 @@ static BOOL GetDriveHandle(DWORD DriveIndex, HANDLE* hDrive, char* DriveLetter, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (DriveLetter != NULL) { | 	if (DriveLetter != NULL) { | ||||||
| 		*DriveLetter = *drive?*drive:' ';	// TODO: handle NUL char upstream
 | 		*DriveLetter = *drive?*drive:' '; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return (*hDrive != INVALID_HANDLE_VALUE); | 	return (*hDrive != INVALID_HANDLE_VALUE); | ||||||
|  | @ -293,6 +293,7 @@ static BOOL GetDriveInfo(void) | ||||||
| 				if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { | 				if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { | ||||||
| 					uprintf("Partition #%d:\n", ++nb_partitions); | 					uprintf("Partition #%d:\n", ++nb_partitions); | ||||||
| 					if (hFSTooltip == NULL) { | 					if (hFSTooltip == NULL) { | ||||||
|  | 						// TODO: provide all partitions FS on tooltip, not just the one
 | ||||||
| 						safe_sprintf(tmp, sizeof(tmp), "Current file system: %s (0x%02x)", | 						safe_sprintf(tmp, sizeof(tmp), "Current file system: %s (0x%02x)", | ||||||
| 							GetPartitionType(DriveLayout->PartitionEntry[i].Mbr.PartitionType), | 							GetPartitionType(DriveLayout->PartitionEntry[i].Mbr.PartitionType), | ||||||
| 							DriveLayout->PartitionEntry[i].Mbr.PartitionType); | 							DriveLayout->PartitionEntry[i].Mbr.PartitionType); | ||||||
|  | @ -508,7 +509,8 @@ static BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, | ||||||
| 	DWORD* percent; | 	DWORD* percent; | ||||||
| 	int task_number = 0; | 	int task_number = 0; | ||||||
| 
 | 
 | ||||||
| 	if (FormatErr != 0) return FALSE; | 	if (IS_ERROR(FormatStatus)) | ||||||
|  | 		return FALSE; | ||||||
| 
 | 
 | ||||||
| 	switch(Command) { | 	switch(Command) { | ||||||
| 	case FCC_PROGRESS: | 	case FCC_PROGRESS: | ||||||
|  | @ -517,65 +519,60 @@ static BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, | ||||||
| 		uprintf("%d percent completed.\n", *percent); | 		uprintf("%d percent completed.\n", *percent); | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_STRUCTURE_PROGRESS:	// No progress on quick format
 | 	case FCC_STRUCTURE_PROGRESS:	// No progress on quick format
 | ||||||
| 		uprintf("format task %d/n completed.\n", ++task_number); | 		uprintf("Format task %d/? completed.\n", ++task_number); | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_DONE: | 	case FCC_DONE: | ||||||
| 		if(*(BOOLEAN*)Data == FALSE) { | 		if(*(BOOLEAN*)Data == FALSE) { | ||||||
| 			uprintf("Error while formatting.\n"); | 			uprintf("Error while formatting.\n"); | ||||||
| 			FormatErr = FCC_DONE; | 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_GEN_FAILURE; | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_INCOMPATIBLE_FILE_SYSTEM: | 	case FCC_INCOMPATIBLE_FILE_SYSTEM: | ||||||
| 		uprintf("Incompatible File System\n"); | 		uprintf("Incompatible File System\n"); | ||||||
| 		FormatErr = Command; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INCOMPATIBLE_FS; | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_ACCESS_DENIED: | 	case FCC_ACCESS_DENIED: | ||||||
| 		uprintf("Access denied\n"); | 		uprintf("Access denied\n"); | ||||||
| 		FormatErr = Command; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED; | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_MEDIA_WRITE_PROTECTED: | 	case FCC_MEDIA_WRITE_PROTECTED: | ||||||
| 		uprintf("Media is write protected\n"); | 		uprintf("Media is write protected\n"); | ||||||
| 		FormatErr = Command; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_PROTECT; | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_VOLUME_IN_USE: | 	case FCC_VOLUME_IN_USE: | ||||||
| 		uprintf("Volume is in use\n"); | 		uprintf("Volume is in use\n"); | ||||||
| 		FormatErr = Command; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_DEVICE_IN_USE; | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_CANT_QUICK_FORMAT: | 	case FCC_CANT_QUICK_FORMAT: | ||||||
| 		uprintf("Cannot quick format this volume\n"); | 		uprintf("Cannot quick format this volume\n"); | ||||||
| 		FormatErr = Command; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANT_QUICK_FORMAT; | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_BAD_LABEL: | 	case FCC_BAD_LABEL: | ||||||
| 		uprintf("Bad label\n"); | 		uprintf("Bad label\n"); | ||||||
|  | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INVALID_LABEL; | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_OUTPUT: | 	case FCC_OUTPUT: | ||||||
| 		uprintf("%s\n", ((PTEXTOUTPUT)Data)->Output); | 		uprintf("%s\n", ((PTEXTOUTPUT)Data)->Output); | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_CLUSTER_SIZE_TOO_SMALL: |  | ||||||
| 		uprintf("Allocation unit size is too small\n"); |  | ||||||
| 		FormatErr = Command; |  | ||||||
| 		break; |  | ||||||
| 	case FCC_CLUSTER_SIZE_TOO_BIG: | 	case FCC_CLUSTER_SIZE_TOO_BIG: | ||||||
| 		uprintf("Allocation unit size is too big\n"); | 	case FCC_CLUSTER_SIZE_TOO_SMALL: | ||||||
| 		FormatErr = Command; | 		uprintf("Allocation unit size is too %s\n", FCC_CLUSTER_SIZE_TOO_BIG?"big":"small"); | ||||||
| 		break; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INVALID_CLUSTER_SIZE; | ||||||
| 	case FCC_VOLUME_TOO_SMALL: |  | ||||||
| 		uprintf("Volume is too small\n"); |  | ||||||
| 		FormatErr = Command; |  | ||||||
| 		break; | 		break; | ||||||
| 	case FCC_VOLUME_TOO_BIG: | 	case FCC_VOLUME_TOO_BIG: | ||||||
| 		uprintf("Volume is too big\n"); | 	case FCC_VOLUME_TOO_SMALL: | ||||||
| 		FormatErr = Command; | 		uprintf("Volume is too %s\n", FCC_VOLUME_TOO_BIG?"big":"small"); | ||||||
| 		break; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INVALID_VOLUME_SIZE; | ||||||
| 	case FCC_NO_MEDIA_IN_DRIVE: | 	case FCC_NO_MEDIA_IN_DRIVE: | ||||||
| 		uprintf("No media\n"); | 		uprintf("No media in drive\n"); | ||||||
| 		FormatErr = Command; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NO_MEDIA_IN_DRIVE; | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		uprintf("FormatExCallback: received unhandled command %X\n", Command); | 		uprintf("FormatExCallback: received unhandled command %X\n", Command); | ||||||
|  | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED; | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 	return (FormatErr == 0); | 	return (!IS_ERROR(FormatStatus)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -594,17 +591,14 @@ static BOOL FormatDrive(char DriveLetter) | ||||||
| 	PF_INIT_OR_OUT(FormatEx, fmifs); | 	PF_INIT_OR_OUT(FormatEx, fmifs); | ||||||
| 
 | 
 | ||||||
| 	// TODO: properly set MediaType
 | 	// TODO: properly set MediaType
 | ||||||
| 	FormatErr = 0; |  | ||||||
| 	GetWindowTextW(hFileSystem, wFSType, ARRAYSIZE(wFSType)); | 	GetWindowTextW(hFileSystem, wFSType, ARRAYSIZE(wFSType)); | ||||||
| 	GetWindowTextW(hLabel, wLabel, ARRAYSIZE(wLabel)); | 	GetWindowTextW(hLabel, wLabel, ARRAYSIZE(wLabel)); | ||||||
| 	// TODO set sector size
 | 	// TODO set sector size
 | ||||||
| 	pfFormatEx(wDriveRoot, RemovableMedia, wFSType, wLabel, | 	pfFormatEx(wDriveRoot, RemovableMedia, wFSType, wLabel, | ||||||
| 		IsChecked(IDC_QUICKFORMAT), 4096, FormatExCallback); | 		IsChecked(IDC_QUICKFORMAT), 4096, FormatExCallback); | ||||||
| 	if (FormatErr == 0) { | 	if (!IS_ERROR(FormatStatus)) { | ||||||
| 		uprintf("Format completed.\n"); | 		uprintf("Format completed.\n"); | ||||||
| 		r = TRUE; | 		r = TRUE; | ||||||
| 	} else { |  | ||||||
| 		uprintf("Format error: 0x%02x\n", FormatErr); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| out: | out: | ||||||
|  | @ -623,14 +617,14 @@ static void __cdecl FormatThread(void* param) | ||||||
| 	int i; | 	int i; | ||||||
| 
 | 
 | ||||||
| 	if (!GetDriveHandle(num, &hDrive, NULL, TRUE)) { | 	if (!GetDriveHandle(num, &hDrive, NULL, TRUE)) { | ||||||
| 		// TODO: use FormatErr to report an error
 | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	r = CreatePartition(hDrive); | 	r = CreatePartition(hDrive); | ||||||
| 	safe_closehandle(hDrive); | 	safe_closehandle(hDrive); | ||||||
| 	if (!r) { | 	if (!r) { | ||||||
| 		// TODO: use FormatErr to report an error
 | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE; | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -643,12 +637,14 @@ static void __cdecl FormatThread(void* param) | ||||||
| 	} | 	} | ||||||
| 	if (i >= 10) { | 	if (i >= 10) { | ||||||
| 		uprintf("Unable to reopen drive post partitioning\n"); | 		uprintf("Unable to reopen drive post partitioning\n"); | ||||||
| 		// TODO: use FormatErr to report an error
 | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	safe_closehandle(hDrive); | 	safe_closehandle(hDrive); | ||||||
| 
 | 
 | ||||||
| 	if (!FormatDrive(drive_name[0])) { | 	if (!FormatDrive(drive_name[0])) { | ||||||
|  | 		// Error will be set by FormatDrive() in FormatStatus
 | ||||||
|  | 		uprintf("Format error: 0x%08X\n", FormatStatus); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -855,13 +851,12 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 		case IDOK:			// close application
 | 		case IDOK:			// close application
 | ||||||
| 		case IDCANCEL: | 		case IDCANCEL: | ||||||
| 			if (format_thid != -1L) { | 			if (format_thid != -1L) { | ||||||
| 				// TODO: destroy MessageBox if operation completed while waiting
 |  | ||||||
| 				if (MessageBoxA(hMainDialog, "Cancelling may leave the device in an UNUSABLE state.\r\n" | 				if (MessageBoxA(hMainDialog, "Cancelling may leave the device in an UNUSABLE state.\r\n" | ||||||
| 					"If you are sure you want to cancel, click YES. Otherwise, click NO.", | 					"If you are sure you want to cancel, click YES. Otherwise, click NO.", | ||||||
| 					"Do you want to cancel?", MB_YESNO|MB_ICONWARNING) == IDYES) { | 					RUFUS_CANCELBOX_TITLE, MB_YESNO|MB_ICONWARNING) == IDYES) { | ||||||
| 					// Operation may have completed
 | 					// Operation may have completed in the meantime
 | ||||||
| 					if (format_thid != -1L) { | 					if (format_thid != -1L) { | ||||||
| 						FormatErr = -1; | 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED; | ||||||
| 						StatusPrintf("Cancelling - please wait..."); | 						StatusPrintf("Cancelling - please wait..."); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | @ -886,7 +881,6 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		case IDC_START: | 		case IDC_START: | ||||||
| 			// TODO: disable all controls and replace Close with Cancel
 |  | ||||||
| 			if (format_thid != -1L) { | 			if (format_thid != -1L) { | ||||||
| 				return (INT_PTR)TRUE; | 				return (INT_PTR)TRUE; | ||||||
| 			} | 			} | ||||||
|  | @ -904,10 +898,12 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 						SendMessage(hProgress, PBM_SETMARQUEE, TRUE, 0); | 						SendMessage(hProgress, PBM_SETMARQUEE, TRUE, 0); | ||||||
| 					} | 					} | ||||||
| 					DeviceNum =  (DWORD)ComboBox_GetItemData(hDeviceList, nDeviceIndex); | 					DeviceNum =  (DWORD)ComboBox_GetItemData(hDeviceList, nDeviceIndex); | ||||||
|  | 					FormatStatus = 0; | ||||||
| 					format_thid = _beginthread(FormatThread, 0, (void*)(uintptr_t)DeviceNum); | 					format_thid = _beginthread(FormatThread, 0, (void*)(uintptr_t)DeviceNum); | ||||||
| 					if (format_thid == -1L) { | 					if (format_thid == -1L) { | ||||||
| 						// TODO: handle error
 |  | ||||||
| 						uprintf("Unable to start formatting thread"); | 						uprintf("Unable to start formatting thread"); | ||||||
|  | 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANT_START_THREAD; | ||||||
|  | 						PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | @ -930,6 +926,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 
 | 
 | ||||||
| 	case UM_FORMAT_COMPLETED: | 	case UM_FORMAT_COMPLETED: | ||||||
| 		format_thid = -1L; | 		format_thid = -1L; | ||||||
|  | 		// Close the cancel MessageBox if active
 | ||||||
|  | 		SendMessage(FindWindowA(MAKEINTRESOURCEA(32770), RUFUS_CANCELBOX_TITLE), WM_COMMAND, IDNO, 0); | ||||||
| 		if (IsChecked(IDC_QUICKFORMAT)) { | 		if (IsChecked(IDC_QUICKFORMAT)) { | ||||||
| 			SendMessage(hProgress, PBM_SETMARQUEE, FALSE, 0); | 			SendMessage(hProgress, PBM_SETMARQUEE, FALSE, 0); | ||||||
| 			SetWindowLongPtr(hProgress, GWL_STYLE, ProgressStyle); | 			SetWindowLongPtr(hProgress, GWL_STYLE, ProgressStyle); | ||||||
|  | @ -938,9 +936,9 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 			SendMessage(hProgress, PBM_SETPOS, 101, 0); | 			SendMessage(hProgress, PBM_SETPOS, 101, 0); | ||||||
| 			SendMessage(hProgress, PBM_SETRANGE, 0, 100<<16); | 			SendMessage(hProgress, PBM_SETRANGE, 0, 100<<16); | ||||||
| 		} | 		} | ||||||
| 		SendMessage(hProgress, PBM_SETPOS, FormatErr?0:100, 0); | 		SendMessage(hProgress, PBM_SETPOS, FormatStatus?0:100, 0); | ||||||
| 		// TODO: report cancelled status
 | 		StatusPrintf(!IS_ERROR(FormatStatus)?"DONE": | ||||||
| 		StatusPrintf(FormatErr?"FAILED":"DONE"); | 			((SCODE_CODE(FormatStatus)==ERROR_CANCELLED)?"Cancelled":"FAILED")); | ||||||
| 		EnableControls(TRUE); | 		EnableControls(TRUE); | ||||||
| 		return (INT_PTR)TRUE; | 		return (INT_PTR)TRUE; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								rufus.h
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								rufus.h
									
										
									
									
									
								
							|  | @ -15,7 +15,7 @@ | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| #include <winioctl.h>	// for MEDIA_TYPE | #include <winioctl.h>				// for MEDIA_TYPE | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | @ -23,6 +23,7 @@ | ||||||
| 
 | 
 | ||||||
| #define APP_VERSION                 "Rufus v1.0.0.1" | #define APP_VERSION                 "Rufus v1.0.0.1" | ||||||
| #define STR_NO_LABEL                "NO_LABEL" | #define STR_NO_LABEL                "NO_LABEL" | ||||||
|  | #define RUFUS_CANCELBOX_TITLE       "Rufus - Cancellation" | ||||||
| #define DRIVE_INDEX_MIN             0x80 | #define DRIVE_INDEX_MIN             0x80 | ||||||
| #define DRIVE_INDEX_MAX             0xC0 | #define DRIVE_INDEX_MAX             0xC0 | ||||||
| #define MAX_DRIVES                  16 | #define MAX_DRIVES                  16 | ||||||
|  | @ -213,3 +214,11 @@ typedef BOOLEAN (WINAPI* EnableVolumeCompression_t)( | ||||||
| 	WCHAR*          DriveRoot, | 	WCHAR*          DriveRoot, | ||||||
| 	ULONG           CompressionFlags	// FILE_SYSTEM_PROP_FLAG
 | 	ULONG           CompressionFlags	// FILE_SYSTEM_PROP_FLAG
 | ||||||
| ); | ); | ||||||
|  | 
 | ||||||
|  | /* Custom application errors */ | ||||||
|  | #define FAC(f)                         (f<<16) | ||||||
|  | #define ERROR_INCOMPATIBLE_FS          (APPLICATION_ERROR_MASK|0x1201) | ||||||
|  | #define ERROR_CANT_QUICK_FORMAT        (APPLICATION_ERROR_MASK|0x1202) | ||||||
|  | #define ERROR_INVALID_CLUSTER_SIZE     (APPLICATION_ERROR_MASK|0x1203) | ||||||
|  | #define ERROR_INVALID_VOLUME_SIZE      (APPLICATION_ERROR_MASK|0x1204) | ||||||
|  | #define ERROR_CANT_START_THREAD        (APPLICATION_ERROR_MASK|0x1205) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue