|
|
1.1.1.2 ! root 1: /* Copyright (C) 2004 TrueCrypt Foundation 1.1 root 2: This product uses components written by Paul Le Roux <[email protected]> */ 3: 4: /* WARNING: The code for unmounting volumes is ugly for all Windows versions; 5: becarefull what you change here as there might be unintended side effects 6: in the device drivers */ 7: 8: /* For Windows NT the part of the system that actually unmounts drives is the 9: TrueCryptService, this is because of NT security. Users don't normally have 10: enough access to open raw partitions, but services do, TrueCryptService still 11: calls this code however. */ 12: 13: #include "TCdefs.h" 14: #include "crypto.h" 15: #include "apidrvr.h" 16: 17: #include "dismount.h" 18: 19: extern HANDLE hDriver; 20: 21: #ifdef NTSERVICE 22: extern void handleWin32Error (HWND dummy); 23: #else 24: #include "dlgcode.h" 25: #endif 26: 27: /* NT support routines -----------------------------------> */ 28: 29: BOOL 30: UnmountAllVolumes (HWND hwndDlg, DWORD * os_error, int *err) 31: { 32: MOUNT_LIST_STRUCT driver; 33: DWORD dwResult; 34: BOOL bResult, bOK = TRUE; 35: int i; 36: 37: *os_error = 0; 38: *err = 0; 39: 40: bResult = DeviceIoControl (hDriver, MOUNT_LIST, &driver, sizeof (driver), &driver, 41: sizeof (driver), &dwResult, NULL); 42: 43: if (bResult == FALSE) 44: { 45: *os_error = GetLastError (); 46: *err = ERR_OS_ERROR; 47: return FALSE; 48: } 49: 50: for (i = 0; i < 26; i++) 51: { 52: if ((driver.ulMountedDrives & 1 << i)) 53: { 54: UnmountVolume (i, os_error, err); 55: 56: if (*err != 0) 57: bOK = FALSE; 58: 59: if (*err != 0 && *err == ERR_OS_ERROR) 60: handleWin32Error (hwndDlg); 61: } 62: } 63: 64: return bOK; 65: } 66: 67: BOOL 68: UnmountVolume (int nDosDriveNo, DWORD * os_error, int *err) 69: { 70: UNMOUNT_STRUCT tcUnmount; 71: char volMountName[32]; 72: char dosName[3]; 73: DWORD dwResult; 74: BOOL bResult; 75: 76: *os_error = 0; 77: *err = 0; 78: 79: tcUnmount.nDosDriveNo = nDosDriveNo; 80: 81: dosName[0] = (char) (tcUnmount.nDosDriveNo + 'A'); 82: dosName[1] = ':'; 83: dosName[2] = 0; 84: 85: sprintf (volMountName, "\\\\.\\%s", dosName); 86: 87: if (DismountVolume (volMountName, os_error, err) == FALSE) 88: return FALSE; 89: 90: bResult = DeviceIoControl (hDriver, UNMOUNT, &tcUnmount, 91: sizeof (tcUnmount), &tcUnmount, sizeof (tcUnmount), &dwResult, NULL); 92: 93: if (bResult == FALSE) 94: { 95: *os_error = GetLastError (); 96: *err = ERR_OS_ERROR; 97: return FALSE; 98: } 99: 100: if (tcUnmount.nReturnCode == 0) 101: { 102: bResult = DefineDosDevice (DDD_REMOVE_DEFINITION, dosName, NULL); 103: 104: if (bResult == FALSE) 105: { 106: *os_error = GetLastError (); 107: *err = ERR_OS_ERROR; 108: return FALSE; 109: } 110: } 111: else 112: *err = tcUnmount.nReturnCode; 113: 114: return TRUE; 115: } 116: 117: BOOL 118: DismountVolume (char *lpszVolMountName, DWORD * os_error, int *err) 119: { 120: HANDLE hVolume = INVALID_HANDLE_VALUE; 121: BOOL bRetry = FALSE; 122: DWORD dwResult; 123: int i; 124: 125: *os_error = 0; 126: *err = 0; 127: 128: retry: 129: 130: #ifdef _DEBUG 131: OutputDebugString ("mount: dismount volume ----------------->...\n"); 132: #endif 133: 134: for (i = 0; i < 16; i++) 135: { 136: BOOL bResult; 137: 138: #ifdef _DEBUG 139: OutputDebugString ("mount: trying to open the volume...\n"); 140: #endif 141: /* Try to open a handle to the mounted volume */ 142: hVolume = CreateFile (lpszVolMountName, GENERIC_READ | GENERIC_WRITE, 143: FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 144: if (hVolume == INVALID_HANDLE_VALUE) 145: { 146: *os_error = GetLastError (); 147: *err = ERR_OS_ERROR; 148: return FALSE; 149: } 150: 151: #ifdef _DEBUG 152: OutputDebugString ("mount: trying to lock the volume...\n"); 153: #endif 154: bResult = DeviceIoControl (hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwResult, NULL); 155: if (bResult == FALSE) 156: { 157: DWORD dwError = GetLastError (); 158: if (dwError != ERROR_ACCESS_DENIED) 159: { 160: *os_error = GetLastError (); 161: *err = ERR_OS_ERROR; 162: CloseHandle (hVolume); 163: return FALSE; 164: } 165: else 166: { 167: CloseHandle (hVolume); 168: hVolume = INVALID_HANDLE_VALUE; 169: } 170: } 171: else 172: break; 173: } 174: 175: if (hVolume == INVALID_HANDLE_VALUE) 176: { 177: if (bRetry == FALSE) 178: { 179: bRetry = TRUE; 180: Sleep (1000); 181: goto retry; 182: } 183: 184: *err = ERR_FILES_OPEN_LOCK; 185: 186: return FALSE; 187: } 188: 189: #ifdef _DEBUG 190: OutputDebugString ("mount: trying to dismount the volume...\n"); 191: #endif 192: DeviceIoControl (hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwResult, NULL); 193: #ifdef _DEBUG 194: OutputDebugString ("mount: trying to unmount the volume...\n"); 195: #endif 196: 197: DeviceIoControl (hVolume, UNMOUNT_PENDING, NULL, 0, NULL, 0, &dwResult, NULL); 198: CloseHandle (hVolume); 199: 200: #ifdef _DEBUG 201: OutputDebugString ("<-------------------------------- mount: dismount volume!\n"); 202: #endif 203: 204: return TRUE; 205: } 206: 207: 208: /* Windows 9x support routines -----------------------------------> */ 209: 210: typedef struct _DIOC_REGISTERS 211: { 212: DWORD reg_EBX; 213: DWORD reg_EDX; 214: DWORD reg_ECX; 215: DWORD reg_EAX; 216: DWORD reg_EDI; 217: DWORD reg_ESI; 218: DWORD reg_Flags; 219: } DIOC_REGISTERS, *PDIOC_REGISTERS; 220: 221: #define VWIN32_DIOC_DOS_IOCTL 1 222: 223: typedef struct PARAMBLOCK 224: { 225: char Operation; 226: char NumLocks; 227: } PARAMBLOCK; 228: 229: 230: BOOL 231: DoDeviceClose (int slot, int *err) 232: { 233: MOUNT_LIST_N_STRUCT mount_list; 234: UNMOUNT_STRUCT unmount; 235: int tries; 236: int c; 237: 238: mount_list.nDosDriveNo = slot; 239: if (DeviceIoControl (hDriver, MOUNT_LIST_N, &mount_list, sizeof (mount_list), NULL, 0, NULL, NULL) == FALSE) 240: { 241: *err = ERR_OS_ERROR; 242: return FALSE; 243: } 244: else 245: { 246: if (mount_list.nReturnCode != 0) 247: { 248: *err = mount_list.nReturnCode; 249: return TRUE; 250: } 251: } 252: 253: if (mount_list.mountfilehandle) 254: EjectStop ((char)toupper(*((char *) mount_list.wszVolume)), FALSE); 255: 256: unmount.nDosDriveNo = slot; 257: if (DeviceIoControl (hDriver, UNMOUNT_PENDING, &unmount, sizeof (unmount), NULL, 0, NULL, NULL) == FALSE) 258: { 259: *err = ERR_OS_ERROR; 260: return FALSE; 261: } 262: else 263: { 264: if (mount_list.nReturnCode != 0) 265: { 266: *err = mount_list.nReturnCode; 267: return TRUE; 268: } 269: } 270: 271: for (c = 0; c < 20; c++) 272: { 273: DeviceIoControl (hDriver, RELEASE_TIME_SLICE, NULL, 0, NULL, 0, NULL, NULL); 274: } 275: 276: for (tries=0;tries<32;tries++) 277: { 278: DeviceIoControl (hDriver, RELEASE_TIME_SLICE, NULL, 0, NULL, 0, NULL, NULL); 279: if (DeviceIoControl (hDriver, UNMOUNT, &unmount, sizeof (UNMOUNT), NULL, 0, NULL, NULL) == FALSE) 280: { 281: *err = ERR_OS_ERROR; 282: return FALSE; 283: } 284: else 285: { 286: if (mount_list.nReturnCode == 0) 287: { 288: *err = 0; 289: return TRUE; 290: } 291: } 292: } 293: 294: *err = ERR_FILES_OPEN_LOCK; 295: return TRUE; 296: } 297: 298: int 299: ioctllock (unsigned int nDrive, int permissions, int function) 300: { 301: HANDLE hDevice; 302: DIOC_REGISTERS reg; 303: BOOL fResult; 304: DWORD cb; 305: int lockfunc; 306: 307: if (function) 308: lockfunc = 0x4a; 309: else 310: lockfunc = 0x6a; 311: 312: hDevice = CreateFile ("\\\\.\\vwin32", 313: 0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL); 314: 315: reg.reg_EAX = 0x440D; 316: reg.reg_EBX = nDrive; 317: reg.reg_ECX = 0x0800 | lockfunc; 318: reg.reg_EDX = permissions; 319: reg.reg_Flags = 0x0001; 320: 321: fResult = DeviceIoControl (hDevice, 322: VWIN32_DIOC_DOS_IOCTL, 323: ®, sizeof (reg), 324: ®, sizeof (reg), 325: &cb, 0); 326: 327: CloseHandle (hDevice); 328: 329: return reg.reg_Flags & 1; /* error if carry flag is set */ 330: } 331: 332: int 333: locklogdrive (int drivenum, int mode) /* error if true returned.... */ 334: { 335: int a; 336: 337: if (mode) 338: { 339: a = ioctllock (drivenum, 0, 1); 340: a = ioctllock (drivenum, 4, 1); 341: } 342: else 343: { 344: a = 0; 345: ioctllock (drivenum, 0, 0); 346: ioctllock (drivenum, 0, 0); 347: } 348: 349: return a; 350: } 351: 352: 353: 354: int 355: ld (char *d, int mode) 356: { 357: int drivelett = d[0]; 358: int a = 1; 359: 360: drivelett -= 'A'; 361: drivelett += 1; 362: 363: if ((drivelett > 1) && drivelett < 27) 364: a = (locklogdrive (drivelett, mode)); 365: 366: return a; 367: 368: } 369: 370: BOOL 371: CloseSlot (int slot, int brutal, int *err) 372: { 373: char dr[3]; 374: BOOL bResult; 375: 376: if (brutal); /* Remove warning */ 377: 378: dr[0] = (char) (slot + 'A'); 379: dr[1] = ':'; 380: dr[2] = 0; 381: 382: if (ld (dr, 1)) 383: { 384: bResult = TRUE; 385: *err = ERR_FILES_OPEN_LOCK; 386: } 387: else 388: { 389: bResult = DoDeviceClose (slot, err); 390: ld (dr, 0); 391: } 392: 393: return bResult; 394: } 395: 396: 397: int 398: EjectStop (char Driveletter, BOOL function) 399: { 400: HANDLE hDevice; 401: DIOC_REGISTERS reg; 402: BOOL fResult; 403: DWORD cb; 404: int lockfunc; 405: PARAMBLOCK p; 406: 407: if (Driveletter == 0) 408: return 0; 409: 410: Driveletter -= 'A'; 411: Driveletter++; 412: 413: lockfunc = 0x48; 414: 415: if (function == TRUE) 416: p.Operation = 0;/* lock */ 417: else 418: p.Operation = 1; 419: 420: hDevice = CreateFile ("\\\\.\\vwin32", 0, 0, NULL, 0, 421: FILE_FLAG_DELETE_ON_CLOSE, NULL); 422: 423: reg.reg_EAX = 0x440D; 424: reg.reg_EBX = Driveletter; 425: reg.reg_ECX = 0x0800 | lockfunc; 426: reg.reg_EDX = (unsigned long) &p; 427: reg.reg_Flags = 0x0001; 428: 429: fResult = DeviceIoControl (hDevice, 430: VWIN32_DIOC_DOS_IOCTL, 431: ®, sizeof (reg), 432: ®, sizeof (reg), 433: &cb, 0); 434: 435: CloseHandle (hDevice); 436: 437: return reg.reg_Flags & 1; /* error if carry flag is set */ 438: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.