|
|
1.1.1.10 root 1: /* 1.1.1.12! root 2: Legal Notice: Some portions of the source code contained in this file were ! 3: derived from the source code of Encryption for the Masses 2.02a, which is ! 4: Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License ! 5: Agreement for Encryption for the Masses'. Modifications and additions to ! 6: the original source code (contained in this file) and all other portions of ! 7: this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed ! 8: by the TrueCrypt License 2.4 the full text of which is contained in the ! 9: file License.txt included in TrueCrypt binary and source code distribution 1.1.1.10 root 10: packages. */ 1.1 root 11: 12: #include "TCdefs.h" 1.1.1.6 root 13: #include "Crypto.h" 14: #include "Volumes.h" 1.1 root 15: 1.1.1.6 root 16: #include "Apidrvr.h" 17: #include "Ntdriver.h" 18: #include "Ntvol.h" 1.1 root 19: 1.1.1.6 root 20: #include "Cache.h" 1.1 root 21: 1.1.1.10 root 22: #if 0 && _DEBUG 23: #define EXTRA_INFO 1 24: #endif 1.1 root 25: 26: #pragma warning( disable : 4127 ) 27: 28: NTSTATUS 29: TCOpenVolume (PDEVICE_OBJECT DeviceObject, 30: PEXTENSION Extension, 1.1.1.6 root 31: MOUNT_STRUCT *mount, 1.1 root 32: PWSTR pwszMountVolume, 33: BOOL bRawDevice) 34: { 35: FILE_STANDARD_INFORMATION FileStandardInfo; 36: FILE_BASIC_INFORMATION FileBasicInfo; 37: OBJECT_ATTRIBUTES oaFileAttributes; 38: UNICODE_STRING FullFileName; 39: IO_STATUS_BLOCK IoStatusBlock; 1.1.1.6 root 40: PCRYPTO_INFO cryptoInfoPtr = NULL; 41: PCRYPTO_INFO tmpCryptoInfo = NULL; 1.1 root 42: LARGE_INTEGER lDiskLength; 1.1.1.6 root 43: LARGE_INTEGER hiddenVolHeaderOffset; 44: int volumeType; 1.1.1.4 root 45: char *readBuffer = 0; 1.1.1.5 root 46: NTSTATUS ntStatus = 0; 1.1 root 47: 48: Extension->pfoDeviceFile = NULL; 49: Extension->hDeviceFile = NULL; 1.1.1.6 root 50: Extension->bTimeStampValid = FALSE; 1.1 root 51: 1.1.1.4 root 52: RtlInitUnicodeString (&FullFileName, pwszMountVolume); 53: InitializeObjectAttributes (&oaFileAttributes, &FullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); 54: KeInitializeEvent (&Extension->keVolumeEvent, NotificationEvent, FALSE); 55: 56: // If we are opening a device, query its size first 57: if (bRawDevice) 1.1 root 58: { 1.1.1.5 root 59: PARTITION_INFORMATION pi; 1.1.1.10 root 60: PARTITION_INFORMATION_EX pix; 1.1.1.4 root 61: DISK_GEOMETRY dg; 1.1 root 62: 1.1.1.4 root 63: ntStatus = IoGetDeviceObjectPointer (&FullFileName, 64: FILE_READ_DATA, 65: &Extension->pfoDeviceFile, 66: &Extension->pFsdDevice); 67: 68: if (!NT_SUCCESS (ntStatus)) 69: goto error; 70: 1.1.1.12! root 71: if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY, (char *) &dg, sizeof (dg)))) 1.1.1.4 root 72: { 1.1.1.10 root 73: lDiskLength.QuadPart = dg.Cylinders.QuadPart * dg.SectorsPerTrack * dg.TracksPerCylinder * dg.BytesPerSector; 74: mount->BytesPerSector = dg.BytesPerSector; 1.1.1.4 root 75: } 1.1.1.5 root 76: else 1.1.1.10 root 77: lDiskLength.QuadPart = 0; 1.1.1.4 root 78: 1.1.1.10 root 79: // Drive geometry is used only when IOCTL_DISK_GET_PARTITION_INFO fails 1.1.1.12! root 80: if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO_EX, (char *) &pix, sizeof (pix)))) 1.1.1.10 root 81: lDiskLength.QuadPart = pix.PartitionLength.QuadPart; 82: // Windows 2000 does not support IOCTL_DISK_GET_PARTITION_INFO_EX 1.1.1.12! root 83: else if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO, (char *) &pi, sizeof (pi)))) 1.1.1.10 root 84: lDiskLength.QuadPart = pi.PartitionLength.QuadPart; 1.1 root 85: 1.1.1.12! root 86: if (!mount->bMountReadOnly && TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_IS_WRITABLE, NULL, 0) == STATUS_MEDIA_WRITE_PROTECTED) 1.1.1.10 root 87: { 88: mount->bMountReadOnly = TRUE; 89: DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE; 1.1.1.4 root 90: } 91: } 1.1 root 92: 1.1.1.10 root 93: if (mount->BytesPerSector == 0) 94: mount->BytesPerSector = SECTOR_SIZE; 95: 96: Extension->HostBytesPerSector = mount->BytesPerSector; 97: 1.1.1.4 root 98: // Open the volume hosting file/device 99: if (!mount->bMountReadOnly) 100: { 101: ntStatus = ZwCreateFile (&Extension->hDeviceFile, 102: GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 103: &oaFileAttributes, 104: &IoStatusBlock, 105: NULL, 106: FILE_ATTRIBUTE_NORMAL | 107: FILE_ATTRIBUTE_SYSTEM, 108: mount->bExclusiveAccess ? 0 : FILE_SHARE_READ | FILE_SHARE_WRITE, 109: FILE_OPEN, 1.1.1.10 root 110: FILE_RANDOM_ACCESS | 1.1.1.4 root 111: FILE_WRITE_THROUGH | 1.1.1.10 root 112: (Extension->HostBytesPerSector == SECTOR_SIZE ? FILE_NO_INTERMEDIATE_BUFFERING : 0) | 1.1.1.4 root 113: FILE_SYNCHRONOUS_IO_NONALERT, 114: NULL, 115: 0); 116: } 1.1 root 117: 1.1.1.10 root 118: /* 26-4-99 NT for some partitions returns this code, it is really a access denied */ 1.1 root 119: if (ntStatus == 0xc000001b) 120: ntStatus = STATUS_ACCESS_DENIED; 1.1.1.6 root 121: 1.1.1.4 root 122: if (mount->bMountReadOnly || ntStatus == STATUS_ACCESS_DENIED) 1.1 root 123: { 124: ntStatus = ZwCreateFile (&Extension->hDeviceFile, 1.1.1.4 root 125: GENERIC_READ | SYNCHRONIZE, 126: &oaFileAttributes, 127: &IoStatusBlock, 128: NULL, 129: FILE_ATTRIBUTE_NORMAL | 130: FILE_ATTRIBUTE_SYSTEM, 1.1.1.8 root 131: mount->bExclusiveAccess ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE, 1.1.1.4 root 132: FILE_OPEN, 1.1.1.10 root 133: FILE_RANDOM_ACCESS | 1.1.1.4 root 134: FILE_WRITE_THROUGH | 1.1.1.11 root 135: (Extension->HostBytesPerSector == SECTOR_SIZE ? FILE_NO_INTERMEDIATE_BUFFERING : 0) | 1.1.1.4 root 136: FILE_SYNCHRONOUS_IO_NONALERT, 137: NULL, 138: 0); 1.1.1.11 root 139: 1.1 root 140: Extension->bReadOnly = TRUE; 1.1.1.11 root 141: DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE; 1.1 root 142: } 143: else 144: Extension->bReadOnly = FALSE; 145: 146: /* 26-4-99 NT for some partitions returns this code, it is really a 1.1.1.4 root 147: access denied */ 1.1 root 148: if (ntStatus == 0xc000001b) 149: { 150: /* Partitions which return this code can still be opened with 1.1.1.4 root 151: FILE_SHARE_READ but this causes NT problems elsewhere in 152: particular if you do FILE_SHARE_READ NT will die later if 1.1.1.12! root 153: anyone even tries to open the partition (or file for that 1.1.1.4 root 154: matter...) */ 1.1 root 155: ntStatus = STATUS_SHARING_VIOLATION; 156: } 157: 158: if (!NT_SUCCESS (ntStatus)) 159: { 160: goto error; 161: } 162: 1.1.1.4 root 163: // If we have opened a file, query its size now 1.1 root 164: if (bRawDevice == FALSE) 165: { 166: ntStatus = ZwQueryInformationFile (Extension->hDeviceFile, 1.1.1.4 root 167: &IoStatusBlock, 168: &FileBasicInfo, 169: sizeof (FileBasicInfo), 170: FileBasicInformation); 1.1 root 171: 172: if (NT_SUCCESS (ntStatus)) 1.1.1.4 root 173: { 1.1.1.6 root 174: if (mount->bPreserveTimestamp) 175: { 176: /* Remember the container timestamp. (Used to reset access/modification file date/time 177: of file-hosted volumes upon dismount or after unsuccessful mount attempt to preserve 178: plausible deniability of hidden volumes.) */ 179: Extension->fileCreationTime = FileBasicInfo.CreationTime; 180: Extension->fileLastAccessTime = FileBasicInfo.LastAccessTime; 181: Extension->fileLastWriteTime = FileBasicInfo.LastWriteTime; 182: Extension->fileLastChangeTime = FileBasicInfo.ChangeTime; 183: Extension->bTimeStampValid = TRUE; 184: } 1.1.1.4 root 185: 1.1 root 186: ntStatus = ZwQueryInformationFile (Extension->hDeviceFile, 1.1.1.4 root 187: &IoStatusBlock, 188: &FileStandardInfo, 189: sizeof (FileStandardInfo), 190: FileStandardInformation); 191: } 1.1 root 192: 193: if (!NT_SUCCESS (ntStatus)) 194: { 195: Dump ("ZwQueryInformationFile failed while opening file: NTSTATUS 0x%08x\n", 1.1.1.4 root 196: ntStatus); 1.1 root 197: goto error; 198: } 1.1.1.4 root 199: 200: lDiskLength.QuadPart = FileStandardInfo.EndOfFile.QuadPart; 1.1 root 201: 202: if (FileBasicInfo.FileAttributes & FILE_ATTRIBUTE_COMPRESSED) 203: { 204: Dump ("File \"%ls\" is marked as compressed - not supported!\n", pwszMountVolume); 205: mount->nReturnCode = ERR_COMPRESSION_NOT_SUPPORTED; 206: ntStatus = STATUS_SUCCESS; 207: goto error; 208: } 209: 210: ntStatus = ObReferenceObjectByHandle (Extension->hDeviceFile, 1.1.1.4 root 211: FILE_ALL_ACCESS, 212: *IoFileObjectType, 213: KernelMode, 214: &Extension->pfoDeviceFile, 215: 0); 1.1 root 216: 217: if (!NT_SUCCESS (ntStatus)) 218: { 219: goto error; 220: } 221: 1.1.1.4 root 222: /* Get the FSD device for the file (probably either NTFS or FAT) */ 1.1 root 223: Extension->pFsdDevice = IoGetRelatedDeviceObject (Extension->pfoDeviceFile); 224: } 225: 1.1.1.4 root 226: // Check volume size 227: if (lDiskLength.QuadPart < MIN_VOLUME_SIZE || lDiskLength.QuadPart > MAX_VOLUME_SIZE) 228: { 229: mount->nReturnCode = ERR_VOL_SIZE_WRONG; 230: ntStatus = STATUS_SUCCESS; 231: goto error; 232: } 1.1.1.6 root 233: 1.1.1.4 root 234: Extension->DiskLength = lDiskLength.QuadPart; 1.1 root 235: 1.1.1.6 root 236: hiddenVolHeaderOffset.QuadPart = lDiskLength.QuadPart - HIDDEN_VOL_HEADER_OFFSET; 237: 1.1.1.4 root 238: readBuffer = TCalloc (HEADER_SIZE); 239: if (readBuffer == NULL) 240: { 241: ntStatus = STATUS_INSUFFICIENT_RESOURCES; 242: goto error; 243: } 1.1 root 244: 1.1.1.6 root 245: // Go through all volume types (e.g., normal, hidden) 246: for (volumeType = VOLUME_TYPE_NORMAL; 247: volumeType < NBR_VOLUME_TYPES; 248: volumeType++) 1.1.1.4 root 249: { 1.1.1.6 root 250: /* Read the volume header */ 1.1 root 251: 1.1.1.6 root 252: ntStatus = ZwReadFile (Extension->hDeviceFile, 253: NULL, 254: NULL, 255: NULL, 256: &IoStatusBlock, 257: readBuffer, 258: HEADER_SIZE, 259: volumeType == VOLUME_TYPE_HIDDEN ? &hiddenVolHeaderOffset : NULL, 260: NULL); 261: 262: if (!NT_SUCCESS (ntStatus)) 1.1 root 263: { 1.1.1.6 root 264: Dump ("Read failed: NTSTATUS 0x%08x\n", ntStatus); 265: } 266: else if (IoStatusBlock.Information != HEADER_SIZE) 267: { 268: Dump ("Read didn't read enough data in: %lu / %lu\n", IoStatusBlock.Information, HEADER_SIZE); 269: ntStatus = STATUS_UNSUCCESSFUL; 1.1 root 270: } 271: 1.1.1.6 root 272: if (!NT_SUCCESS (ntStatus)) 273: { 274: goto error; 275: } 1.1 root 276: 1.1.1.6 root 277: /* Attempt to recognize the volume (decrypt the header) */ 1.1 root 278: 1.1.1.6 root 279: if (volumeType == VOLUME_TYPE_HIDDEN && mount->bProtectHiddenVolume) 280: { 281: mount->nReturnCode = VolumeReadHeaderCache ( 282: mount->bCache, 283: readBuffer, 284: &mount->ProtectedHidVolPassword, 285: &tmpCryptoInfo); 286: } 287: else 288: { 289: mount->nReturnCode = VolumeReadHeaderCache ( 290: mount->bCache, 291: readBuffer, 292: &mount->VolumePassword, 293: &Extension->cryptoInfo); 294: } 1.1.1.4 root 295: 1.1.1.6 root 296: if (mount->nReturnCode == 0 || mount->nReturnCode == ERR_CIPHER_INIT_WEAK_KEY) 297: { 298: /* Volume header successfully decrypted */ 1.1 root 299: 1.1.1.6 root 300: Extension->cryptoInfo->bProtectHiddenVolume = FALSE; 301: Extension->cryptoInfo->bHiddenVolProtectionAction = FALSE; 1.1 root 302: 1.1.1.6 root 303: switch (volumeType) 304: { 305: case VOLUME_TYPE_NORMAL: 1.1 root 306: 1.1.1.6 root 307: // Correct the volume size for this volume type. Later on, this must be undone 308: // if Extension->DiskLength is used in deriving hidden volume offset 309: Extension->DiskLength -= HEADER_SIZE; 310: Extension->cryptoInfo->hiddenVolume = FALSE; 311: 312: break; 313: 314: case VOLUME_TYPE_HIDDEN: 315: 316: cryptoInfoPtr = mount->bProtectHiddenVolume ? tmpCryptoInfo : Extension->cryptoInfo; 317: 318: // Validate the size of the hidden volume specified in the header 319: if (Extension->DiskLength < (__int64) cryptoInfoPtr->hiddenVolumeSize + HIDDEN_VOL_HEADER_OFFSET + HEADER_SIZE 320: || cryptoInfoPtr->hiddenVolumeSize <= 0) 321: { 322: mount->nReturnCode = ERR_VOL_SIZE_WRONG; 323: ntStatus = STATUS_SUCCESS; 324: goto error; 325: } 326: 327: // Determine the offset of the hidden volume 328: Extension->cryptoInfo->hiddenVolumeOffset = Extension->DiskLength - cryptoInfoPtr->hiddenVolumeSize - HIDDEN_VOL_HEADER_OFFSET; 329: 330: Dump("Hidden volume size = %I64d", cryptoInfoPtr->hiddenVolumeSize); 331: Dump("Hidden volume offset = %I64d", Extension->cryptoInfo->hiddenVolumeOffset); 332: 333: // Validate the offset 1.1.1.12! root 334: if (Extension->cryptoInfo->hiddenVolumeOffset % ENCRYPTION_DATA_UNIT_SIZE != 0) 1.1.1.6 root 335: { 336: mount->nReturnCode = ERR_VOL_SIZE_WRONG; 337: ntStatus = STATUS_SUCCESS; 338: goto error; 339: } 340: 341: // If we are supposed to actually mount the hidden volume (not just to protect it) 342: if (!mount->bProtectHiddenVolume) 343: { 344: Extension->DiskLength = cryptoInfoPtr->hiddenVolumeSize; 345: Extension->cryptoInfo->hiddenVolume = TRUE; 346: } 347: else 348: { 349: // Hidden volume protection 350: Extension->cryptoInfo->hiddenVolume = FALSE; 351: Extension->cryptoInfo->bProtectHiddenVolume = TRUE; 352: Extension->cryptoInfo->hiddenVolumeOffset += HEADER_SIZE; // Offset was incorrect due to loop processing 353: Dump("Hidden volume protection active (offset = %I64d)", Extension->cryptoInfo->hiddenVolumeOffset); 354: } 1.1.1.4 root 355: 1.1.1.6 root 356: break; 357: } 1.1.1.4 root 358: 1.1.1.6 root 359: // If this is a hidden volume, make sure we are supposed to actually 360: // mount it (i.e. not just to protect it) 361: if (!(volumeType == VOLUME_TYPE_HIDDEN && mount->bProtectHiddenVolume)) 1.1.1.4 root 362: { 1.1.1.6 root 363: // Calculate virtual volume geometry 364: Extension->TracksPerCylinder = 1; 365: Extension->SectorsPerTrack = 1; 1.1.1.10 root 366: Extension->BytesPerSector = SECTOR_SIZE; 367: Extension->NumberOfCylinders = Extension->DiskLength / SECTOR_SIZE; 1.1.1.6 root 368: Extension->PartitionType = 0; 369: 370: Extension->bRawDevice = bRawDevice; 1.1.1.7 root 371: 1.1.1.8 root 372: memset (Extension->wszVolume, 0, sizeof (Extension->wszVolume)); 1.1.1.7 root 373: if (wcsstr (pwszMountVolume, WIDE ("\\??\\UNC\\")) == pwszMountVolume) 374: { 375: /* UNC path */ 376: _snwprintf (Extension->wszVolume, 377: sizeof (Extension->wszVolume) / sizeof (WCHAR) - 1, 378: WIDE ("\\??\\\\%s"), 379: pwszMountVolume + 7); 380: } 1.1.1.6 root 381: else 382: { 1.1.1.7 root 383: wcsncpy (Extension->wszVolume, pwszMountVolume, sizeof (Extension->wszVolume) / sizeof (WCHAR) - 1); 1.1.1.6 root 384: } 1.1.1.4 root 385: } 386: 1.1.1.6 root 387: // If we are to protect a hidden volume we cannot exit yet, for we must also 388: // decrypt the hidden volume header. 389: if (!(volumeType == VOLUME_TYPE_NORMAL && mount->bProtectHiddenVolume)) 1.1.1.4 root 390: { 1.1.1.6 root 391: TCfree (readBuffer); 1.1.1.4 root 392: 1.1.1.6 root 393: if (tmpCryptoInfo != NULL) 394: crypto_close (tmpCryptoInfo); 395: 396: return STATUS_SUCCESS; 397: } 1.1.1.4 root 398: } 1.1.1.6 root 399: else if (mount->bProtectHiddenVolume 400: || mount->nReturnCode != ERR_PASSWORD_WRONG) 1.1.1.4 root 401: { 1.1.1.6 root 402: /* If we are not supposed to protect a hidden volume, the only error that is 403: tolerated is ERR_PASSWORD_WRONG (to allow mounting a possible hidden volume). 1.1.1.4 root 404: 1.1.1.6 root 405: If we _are_ supposed to protect a hidden volume, we do not tolerate any error 406: (both volume headers must be successfully decrypted). */ 1.1 root 407: 1.1.1.6 root 408: break; 1.1 root 409: } 410: } 411: 412: /* Failed due to some non-OS reason so we drop through and return NT 413: SUCCESS then nReturnCode is checked later in user-mode */ 414: 415: if (mount->nReturnCode == ERR_OUTOFMEMORY) 416: ntStatus = STATUS_INSUFFICIENT_RESOURCES; 417: else 418: ntStatus = STATUS_SUCCESS; 419: 1.1.1.4 root 420: error: 1.1.1.6 root 421: if (Extension->bTimeStampValid) 1.1.1.4 root 422: { 423: /* Restore the container timestamp to preserve plausible deniability of possible hidden volume. */ 424: RestoreTimeStamp (Extension); 425: } 1.1 root 426: 427: /* Close the hDeviceFile */ 428: if (Extension->hDeviceFile != NULL) 429: ZwClose (Extension->hDeviceFile); 430: 431: /* The cryptoInfo pointer is deallocated if the readheader routines 432: fail so there is no need to deallocate here */ 433: 434: /* Dereference the user-mode file object */ 435: if (Extension->pfoDeviceFile != NULL) 436: ObDereferenceObject (Extension->pfoDeviceFile); 437: 1.1.1.4 root 438: /* Free the tmp IO buffers */ 1.1 root 439: if (readBuffer != NULL) 440: TCfree (readBuffer); 441: 442: return ntStatus; 443: } 444: 445: void 446: TCCloseVolume (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) 447: { 448: if (DeviceObject); /* Remove compiler warning */ 449: 450: if (Extension->hDeviceFile != NULL) 1.1.1.4 root 451: { 1.1.1.6 root 452: if (Extension->bRawDevice == FALSE 453: && Extension->bTimeStampValid) 1.1.1.4 root 454: { 455: /* Restore the container timestamp to preserve plausible deniability of possible hidden volume. */ 456: RestoreTimeStamp (Extension); 457: } 1.1.1.6 root 458: ZwClose (Extension->hDeviceFile); 1.1.1.4 root 459: } 1.1 root 460: ObDereferenceObject (Extension->pfoDeviceFile); 461: crypto_close (Extension->cryptoInfo); 462: } 463: 464: 465: NTSTATUS 1.1.1.12! root 466: TCSendHostDeviceIoControlRequest (PDEVICE_OBJECT DeviceObject, 1.1 root 467: PEXTENSION Extension, 468: ULONG IoControlCode, 469: char *OutputBuffer, 470: int OutputBufferSize) 471: { 472: IO_STATUS_BLOCK IoStatusBlock; 473: NTSTATUS ntStatus; 474: PIRP Irp; 475: 476: if (DeviceObject); /* Remove compiler warning */ 477: 478: KeClearEvent (&Extension->keVolumeEvent); 479: 480: Irp = IoBuildDeviceIoControlRequest (IoControlCode, 481: Extension->pFsdDevice, 482: NULL, 0, 483: OutputBuffer, OutputBufferSize, 484: FALSE, 485: &Extension->keVolumeEvent, 486: &IoStatusBlock); 487: 488: if (Irp == NULL) 489: { 490: Dump ("IRP allocation failed\n"); 491: return STATUS_INSUFFICIENT_RESOURCES; 492: } 493: 1.1.1.5 root 494: // Disk device may be used by filesystem driver which needs file object 495: IoGetNextIrpStackLocation (Irp) -> FileObject = Extension->pfoDeviceFile; 496: 1.1 root 497: ntStatus = IoCallDriver (Extension->pFsdDevice, Irp); 498: if (ntStatus == STATUS_PENDING) 499: { 1.1.1.12! root 500: KeWaitForSingleObject (&Extension->keVolumeEvent, Executive, KernelMode, FALSE, NULL); 1.1 root 501: ntStatus = IoStatusBlock.Status; 502: } 503: 504: return ntStatus; 505: } 506: 507: NTSTATUS 508: COMPLETE_IRP (PDEVICE_OBJECT DeviceObject, 509: PIRP Irp, 510: NTSTATUS IrpStatus, 1.1.1.4 root 511: ULONG_PTR IrpInformation) 1.1 root 512: { 513: Irp->IoStatus.Status = IrpStatus; 514: Irp->IoStatus.Information = IrpInformation; 515: 516: if (DeviceObject); /* Remove compiler warning */ 517: 1.1.1.10 root 518: #if EXTRA_INFO 519: if (!NT_SUCCESS (IrpStatus)) 520: { 521: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); 522: Dump ("COMPLETE_IRP FAILING IRP %ls Flags 0x%08x vpb 0x%08x NTSTATUS 0x%08x\n", TCTranslateCode (irpSp->MajorFunction), 523: (ULONG) DeviceObject->Flags, (ULONG) DeviceObject->Vpb->Flags, IrpStatus); 524: } 525: else 526: { 527: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); 528: Dump ("COMPLETE_IRP SUCCESS IRP %ls Flags 0x%08x vpb 0x%08x NTSTATUS 0x%08x\n", TCTranslateCode (irpSp->MajorFunction), 529: (ULONG) DeviceObject->Flags, (ULONG) DeviceObject->Vpb->Flags, IrpStatus); 530: } 1.1 root 531: #endif 532: IoCompleteRequest (Irp, IO_NO_INCREMENT); 533: return IrpStatus; 534: } 1.1.1.4 root 535: 536: // Restores the container timestamp to preserve plausible deniability of possible hidden volume. 537: static void RestoreTimeStamp (PEXTENSION Extension) 538: { 539: NTSTATUS ntStatus; 540: FILE_BASIC_INFORMATION FileBasicInfo; 541: IO_STATUS_BLOCK IoStatusBlock; 542: 1.1.1.6 root 543: if (Extension->hDeviceFile != NULL 544: && Extension->bRawDevice == FALSE 545: && Extension->bReadOnly == FALSE 546: && Extension->bTimeStampValid) 1.1.1.4 root 547: { 548: ntStatus = ZwQueryInformationFile (Extension->hDeviceFile, 549: &IoStatusBlock, 550: &FileBasicInfo, 551: sizeof (FileBasicInfo), 552: FileBasicInformation); 553: 554: if (!NT_SUCCESS (ntStatus)) 555: { 556: Dump ("ZwQueryInformationFile failed in RestoreTimeStamp: NTSTATUS 0x%08x\n", 557: ntStatus); 558: } 559: else 560: { 561: FileBasicInfo.CreationTime = Extension->fileCreationTime; 562: FileBasicInfo.LastAccessTime = Extension->fileLastAccessTime; 563: FileBasicInfo.LastWriteTime = Extension->fileLastWriteTime; 564: FileBasicInfo.ChangeTime = Extension->fileLastChangeTime; 565: 566: ntStatus = ZwSetInformationFile( 567: Extension->hDeviceFile, 568: &IoStatusBlock, 569: &FileBasicInfo, 570: sizeof (FileBasicInfo), 571: FileBasicInformation); 572: 573: if (!NT_SUCCESS (ntStatus)) 574: Dump ("ZwSetInformationFile failed in RestoreTimeStamp: NTSTATUS 0x%08x\n",ntStatus); 575: } 576: } 577: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.