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