|
|
1.1 ! root 1: /* Copyright (C) 2004 TrueCrypt Team, truecrypt.org ! 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.