1 //////////////////////////////////////////////////////////////////// 2 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine 3 // All rights reserved 4 // This file was released under the GPLv2 on June 2015. 5 //////////////////////////////////////////////////////////////////// 6 7 #ifndef UDF_FORMAT_MEDIA 8 ULONG LockMode = 0; 9 BOOLEAN opt_invalidate_volume = FALSE; 10 #endif //UDF_FORMAT_MEDIA 11 12 #ifndef CDRW_W32 13 #ifndef UDF_FORMAT_MEDIA 14 BOOLEAN open_as_device = FALSE; 15 #endif //UDF_FORMAT_MEDIA 16 #ifdef USE_SKIN_MODEL 17 18 PSKIN_API SkinAPI = NULL; 19 20 PSKIN_API 21 SkinLoad( 22 PWCHAR path, 23 HINSTANCE hInstance, // handle to current instance 24 HINSTANCE hPrevInstance, // handle to previous instance 25 int nCmdShow // show state 26 ) 27 { 28 HMODULE hm; 29 PSKIN_API Skin; 30 PSKIN_API (__stdcall *SkinInit) (VOID); 31 32 hm = LoadLibraryW(path); 33 if(!hm) 34 return NULL; 35 SkinInit = (PSKIN_API(__stdcall *)(void))GetProcAddress(hm, "SkinInit"); 36 if(!SkinInit) 37 return NULL; 38 Skin = SkinInit(); 39 if(!Skin) 40 return NULL; 41 Skin->Init(hInstance, hPrevInstance, nCmdShow); 42 return Skin; 43 } 44 45 46 #endif //USE_SKIN_MODEL 47 48 #ifdef _BROWSE_UDF_ 49 #ifndef LIBUDF 50 51 extern PVCB Vcb; 52 53 #endif // LIBUDF 54 #endif //_BROWSE_UDF_ 55 56 #ifdef LIBUDF 57 #define _lphUdf ((PUDF_VOL_HANDLE_I)(DeviceObject->lpContext)) 58 #endif //LIBUDF 59 #ifdef LIBUDFFMT 60 #define _lphUdf (DeviceObject->cbio) 61 #endif //LIBUDFFMT 62 63 #ifndef CDRW_W32 64 65 NTSTATUS 66 UDFPhSendIOCTL( 67 IN ULONG IoControlCode, 68 IN PDEVICE_OBJECT DeviceObject, 69 IN PVOID InputBuffer , 70 IN ULONG InputBufferLength, 71 OUT PVOID OutputBuffer , 72 IN ULONG OutputBufferLength, 73 IN BOOLEAN OverrideVerify, 74 OUT PVOID Iosb OPTIONAL 75 ) 76 { 77 ULONG real_read; 78 #if !defined(LIBUDF) && !defined(LIBUDFFMT) 79 ULONG ret; 80 81 ULONG RC = DeviceIoControl(DeviceObject->h,IoControlCode, 82 InputBuffer,InputBufferLength, 83 OutputBuffer,OutputBufferLength, 84 &real_read,NULL); 85 86 if (!RC) { 87 ret = GetLastError(); 88 } 89 return RC ? 1 : -1; 90 91 #else // LIBUDF 92 93 ULONG RC = _lphUdf->lpIOCtlFunc(_lphUdf->lpParameter,IoControlCode, 94 InputBuffer,InputBufferLength, 95 OutputBuffer,OutputBufferLength, 96 &real_read); 97 98 return RC; 99 100 #endif // LIBUDF 101 102 } // end UDFPhSendIOCTL() 103 104 105 NTSTATUS 106 UDFPhReadSynchronous( 107 PDEVICE_OBJECT DeviceObject, // the physical device object 108 PVOID Buffer, 109 ULONG Length, 110 LONGLONG Offset, 111 PULONG ReadBytes, 112 ULONG Flags 113 ) 114 { 115 116 #if !defined(LIBUDF) && !defined(LIBUDFFMT) 117 118 NTSTATUS RC; 119 // UDFPrint(("UDFPhRead: Length: %x Lba: %lx\n",Length>>0xb,Offset>>0xb)); 120 LONG HiOffs = (ULONG)(Offset >> 32); 121 122 RC = SetFilePointer(DeviceObject->h,(ULONG)Offset,&HiOffs,FILE_BEGIN); 123 if(RC == INVALID_SET_FILE_POINTER) { 124 if(GetLastError() != NO_ERROR) { 125 UDFPrint(("UDFPhReadSynchronous: error %x\n", GetLastError())); 126 return STATUS_END_OF_FILE; 127 } 128 } 129 RC = ReadFile(DeviceObject->h,Buffer,Length,ReadBytes,NULL); 130 if(NT_SUCCESS(RC) && 131 (!(*ReadBytes))) { 132 RC = GetLastError(); 133 return STATUS_END_OF_FILE; 134 } 135 return STATUS_SUCCESS; 136 137 #else // LIBUDF 138 139 return _lphUdf->lpReadFunc(_lphUdf->lpParameter, 140 Buffer, 141 Length, 142 Offset, 143 ReadBytes); 144 145 #endif //defined LIBUDF || defined LIBUDFFMT 146 147 } // end UDFPhReadSynchronous() 148 149 150 NTSTATUS 151 UDFPhWriteSynchronous( 152 PDEVICE_OBJECT DeviceObject, // the physical device object 153 PVOID Buffer, 154 ULONG Length, 155 LONGLONG Offset, 156 PULONG WrittenBytes, 157 ULONG Flags 158 ) 159 { 160 #if !defined(LIBUDF) && !defined(LIBUDFFMT) 161 162 NTSTATUS RC = STATUS_SUCCESS; 163 LONG HiOffs = (ULONG)(Offset >> 32); 164 PVOID Buffer2 = NULL; 165 PVOID Buffer3 = NULL; 166 167 RC = SetFilePointer(DeviceObject->h,(ULONG)Offset,&HiOffs,FILE_BEGIN); 168 if(RC == INVALID_SET_FILE_POINTER) { 169 if(GetLastError() != NO_ERROR) { 170 UDFPrint(("UDFPhWriteSynchronous: error %x\n", GetLastError())); 171 return STATUS_END_OF_FILE; 172 } 173 } 174 175 Buffer2 = ExAllocatePool(NonPagedPool, Length+0x10000); 176 Buffer3 = (PVOID)( ((ULONG)Buffer2 + 0xffff) & ~0xffff); 177 RtlCopyMemory(Buffer3, Buffer, Length); 178 179 RC = WriteFile(DeviceObject->h,Buffer3,Length,WrittenBytes,NULL); 180 if(!RC || 181 !(*WrittenBytes)) { 182 RC = GetLastError(); 183 UDFPrint(("UDFPhWriteSynchronous: EOF, error %x\n", RC)); 184 RC = STATUS_END_OF_FILE; 185 } else { 186 RC = STATUS_SUCCESS; 187 } 188 189 if(Buffer2) ExFreePool(Buffer2); 190 191 return RC; 192 193 #else // LIBUDF 194 195 return _lphUdf->lpWriteFunc(_lphUdf->lpParameter, 196 Buffer, 197 Length, 198 Offset, 199 WrittenBytes); 200 201 #endif // LIBUDF 202 203 } // end UDFPhWriteSynchronous() 204 205 #if 0 206 NTSTATUS 207 UDFPhWriteVerifySynchronous( 208 PDEVICE_OBJECT DeviceObject, // the physical device object 209 PVOID Buffer, 210 ULONG Length, 211 LONGLONG Offset, 212 PULONG WrittenBytes, 213 ULONG Flags 214 ) 215 { 216 NTSTATUS RC; 217 PUCHAR v_buff = NULL; 218 ULONG ReadBytes; 219 220 RC = UDFPhWriteSynchronous(DeviceObject, Buffer, Length, Offset, WrittenBytes, 0); 221 if(!Verify) 222 return RC; 223 v_buff = (PUCHAR)DbgAllocatePool(NonPagedPool, Length); 224 if(!v_buff) 225 return RC; 226 227 RC = UDFPhSendIOCTL( IOCTL_CDRW_SYNC_CACHE, DeviceObject, 228 NULL,0, NULL,0, FALSE, NULL); 229 230 RC = UDFPhReadSynchronous(DeviceObject, v_buff, Length, Offset, &ReadBytes, 0); 231 if(!NT_SUCCESS(RC)) { 232 BrutePoint(); 233 DbgFreePool(v_buff); 234 return RC; 235 } 236 if(RtlCompareMemory(v_buff, Buffer, ReadBytes) == Length) { 237 DbgFreePool(v_buff); 238 return RC; 239 } 240 BrutePoint(); 241 DbgFreePool(v_buff); 242 return STATUS_LOST_WRITEBEHIND_DATA; 243 } // end UDFPhWriteVerifySynchronous() 244 #endif 245 246 VOID 247 set_image_size( 248 HANDLE h, 249 // ULONG LBA) 250 int64 len) 251 { 252 LONG offh = (ULONG)(len >> 32); 253 //( (LONGLONG)LBA >> (32-Vcb->BlockSizeBits) ); 254 255 SetFilePointer((HANDLE)h, (ULONG)(len /*(LBA << Vcb->BlockSizeBits)*/ ), &offh, FILE_BEGIN); 256 SetEndOfFile(h); 257 offh = 0; 258 SetFilePointer((HANDLE)h, 0, &offh, FILE_BEGIN); 259 } // end set_image_size() 260 261 int64 262 get_file_size( 263 HANDLE h 264 ) 265 { 266 LONG hsz = 0; 267 LONG lsz; 268 269 lsz = SetFilePointer(h, 0, &hsz, FILE_END); 270 return (((int64)hsz) << 32) | lsz; 271 } // end get_file_size() 272 273 int64 274 set_file_pointer( 275 HANDLE h, 276 int64 sz 277 ) 278 { 279 ULONG hsz = (ULONG)(sz >> 32); 280 ULONG lsz = (ULONG)sz; 281 282 lsz = SetFilePointer(h, lsz, (PLONG)&hsz, FILE_BEGIN); 283 return (((int64)hsz) << 32) | lsz; 284 } // end set_file_pointer() 285 286 #endif //CDRW_W32 287 288 #ifndef LIBUDF 289 290 #ifndef UDF_FORMAT_MEDIA 291 292 ULONG 293 write( 294 PVCB Vcb, 295 HANDLE h, 296 PCHAR buff, 297 ULONG len) 298 { 299 ULONG written; 300 LONG offh = 0; 301 ULONG offl = SetFilePointer((HANDLE)h, 0, &offh, FILE_CURRENT); 302 // ULONG Lba = (ULONG)((((LONGLONG)offh << 32) + offl) >> Vcb->BlockSizeBits); 303 304 UDFWriteData(Vcb, FALSE, (((LONGLONG)offh)<<32)+offl, len, FALSE, buff, &written); 305 306 SetFilePointer((HANDLE)h, offl, &offh, FILE_BEGIN); 307 offh = 0; 308 SetFilePointer((HANDLE)h, written, &offh, FILE_CURRENT); 309 310 return written; 311 } // end write() 312 #endif //UDF_FORMAT_MEDIA 313 314 #endif // LIBUDF 315 316 #endif //CDRW_W32 317 318 #ifdef NT_NATIVE_MODE 319 320 BOOL 321 Privilege( 322 LPTSTR pszPrivilege, 323 BOOL bEnable 324 ) 325 { 326 #ifndef NT_NATIVE_MODE 327 HANDLE hToken; 328 TOKEN_PRIVILEGES tp; 329 330 // obtain the token, first check the thread and then the process 331 if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, TRUE, &hToken)) { 332 if (GetLastError() == ERROR_NO_TOKEN) { 333 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { 334 return FALSE; 335 } 336 } else { 337 return FALSE; 338 } 339 } 340 341 // get the luid for the privilege 342 if (!LookupPrivilegeValue(NULL, pszPrivilege, &tp.Privileges[0].Luid)) { 343 CloseHandle(hToken); 344 return FALSE; 345 } 346 347 tp.PrivilegeCount = 1; 348 349 if (bEnable) 350 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 351 else 352 tp.Privileges[0].Attributes = 0; 353 354 // enable or disable the privilege 355 if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0)) { 356 CloseHandle(hToken); 357 return FALSE; 358 } 359 360 if (!CloseHandle(hToken)) 361 return FALSE; 362 363 #endif //NT_NATIVE_MODE 364 365 return TRUE; 366 367 } // end Privilege() 368 #endif //NT_NATIVE_MODE 369 370 #ifndef LIBUDF 371 372 extern "C" 373 ULONG 374 MyLockVolume( 375 HANDLE h, 376 ULONG* pLockMode // OUT 377 ) 378 { 379 ULONG RC; 380 ULONG returned; 381 382 (*pLockMode) = -1; 383 #ifndef CDRW_W32 384 RC = DeviceIoControl(h,IOCTL_UDF_LOCK_VOLUME_BY_PID,NULL,0,NULL,0,&returned,NULL); 385 if(RC) { 386 (*pLockMode) = IOCTL_UDF_LOCK_VOLUME_BY_PID; 387 return STATUS_SUCCESS; 388 } 389 #endif //CDRW_W32 390 391 RC = DeviceIoControl(h,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&returned,NULL); 392 if(RC) { 393 (*pLockMode) = FSCTL_LOCK_VOLUME; 394 return STATUS_SUCCESS; 395 } 396 return STATUS_UNSUCCESSFUL; 397 } // MyLockVolume() 398 399 extern "C" 400 ULONG 401 MyUnlockVolume( 402 HANDLE h, 403 ULONG* pLockMode // IN 404 ) 405 { 406 ULONG returned; 407 408 #ifndef CDRW_W32 409 if((*pLockMode) == IOCTL_UDF_LOCK_VOLUME_BY_PID) { 410 return DeviceIoControl(h,IOCTL_UDF_UNLOCK_VOLUME_BY_PID,NULL,0,NULL,0,&returned,NULL); 411 } 412 #endif //CDRW_W32 413 414 return DeviceIoControl(h,FSCTL_UNLOCK_VOLUME,NULL,0,NULL,0,&returned,NULL); 415 416 } // MyUnlockVolume() 417 418 void 419 my_retrieve_vol_type( 420 #ifndef CDRW_W32 421 PVCB Vcb, 422 #endif 423 PWCHAR fn 424 ) 425 { 426 #ifndef CDRW_W32 427 if(wcslen(fn) == 2 && fn[1] == ':') { 428 ULONG DevType = GetDriveTypeW(fn); 429 UDFPrint((" DevType %x\n", DevType)); 430 switch(DevType) { 431 case DRIVE_CDROM: 432 Vcb->PhDeviceType = FILE_DEVICE_CD_ROM; 433 break; 434 default: 435 Vcb->PhDeviceType = FILE_DEVICE_DISK; 436 break; 437 } 438 } 439 if(wcslen(fn) == 2 && fn[1] == ';') { 440 UserPrint(("Warrning: File name is similar to drive letter.\n" 441 " Don't you type semicolon ';' instead of colon ':' ?\n")); 442 } 443 #endif //CDRW_W32 444 } // end my_retrieve_vol_type() 445 446 447 #ifdef NT_NATIVE_MODE 448 #define GetLastError() ((ULONG)(-1)) 449 #endif //NT_NATIVE_MODE 450 451 #define MAX_INVALIDATE_VOLUME_RETRY 8 452 453 extern "C" 454 HANDLE 455 my_open( 456 #ifndef CDRW_W32 457 PVCB Vcb, 458 #endif 459 PWCHAR fn 460 ) 461 { 462 HANDLE h/*, h2*/; 463 WCHAR deviceNameBuffer[0x200]; 464 WCHAR FSNameBuffer[0x200]; 465 // CCHAR RealDeviceName[0x200]; 466 // WCHAR DeviceName[MAX_PATH+1]; 467 ULONG RC; 468 ULONG retry; 469 ULONG i; 470 BOOLEAN CantLock = FALSE; 471 PULONG pLockMode; 472 #ifdef NT_NATIVE_MODE 473 IO_STATUS_BLOCK ioStatus; 474 OBJECT_ATTRIBUTES ObjectAttributes; 475 UNICODE_STRING uniFilename; 476 #endif //NT_NATIVE_MODE 477 ULONG returned; 478 479 #ifndef CDRW_W32 480 #ifdef UDF_FORMAT_MEDIA 481 PUDFFmtState fms = Vcb->fms; 482 fms-> 483 #endif 484 open_as_device = TRUE; 485 #endif //CDRW_W32 486 487 pLockMode = & 488 #ifdef UDF_FORMAT_MEDIA 489 fms-> 490 #endif 491 LockMode; 492 493 // make several retries to workaround smart applications, 494 // those attempts to work with volume immediately after arrival 495 retry = 1 + 496 #ifdef UDF_FORMAT_MEDIA 497 fms-> 498 #endif 499 opt_invalidate_volume ? 0 : MAX_INVALIDATE_VOLUME_RETRY; 500 501 #ifndef NT_NATIVE_MODE 502 swprintf(deviceNameBuffer, L"%ws\\", fn); 503 UDFPrint(("my_open: %S\n", fn)); 504 i = sizeof(FSNameBuffer)/sizeof(FSNameBuffer[0]); 505 if(GetVolumeInformationW(deviceNameBuffer, NULL, 0, 506 &returned, &returned, &returned, FSNameBuffer, i)) { 507 UDFPrint(("my_open: FS: %S\n", FSNameBuffer)); 508 if(!wcscmp(FSNameBuffer, L"Unknown")) { 509 retry++; 510 } 511 } else { 512 UDFPrint(("my_open: FS: ???\n")); 513 } 514 UDFPrint(("my_open: retry %d times\n", retry)); 515 516 #endif //NT_NATIVE_MODE 517 518 do { 519 // open as device 520 #ifndef NT_NATIVE_MODE 521 swprintf(deviceNameBuffer, L"\\\\.\\%ws", fn); 522 if(wcslen(fn) == 2 && fn[1] == ';') { 523 UserPrint(("Warrning: File name is similar to drive letter.\n" 524 " Don't you type semicolon ';' instead of colon ':' ?\n")); 525 } 526 h = (HANDLE)(-1); 527 for(i=0; i<4; i++) { 528 if(h == ((HANDLE)-1)) { 529 h = CreateFileW(deviceNameBuffer, GENERIC_READ | GENERIC_WRITE, 530 ((i & 1) ? 0 : FILE_SHARE_READ) | ((i & 2) ? 0 : FILE_SHARE_WRITE), 531 NULL, 532 OPEN_EXISTING, 533 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL); 534 if(h != ((HANDLE)-1)) { 535 UDFPrint((" opened i=%x\n", i)); 536 } 537 } 538 } 539 #else //NT_NATIVE_MODE 540 uniFilename.Length = swprintf(deviceNameBuffer, L"\\??\\%ws", fn); 541 uniFilename.Buffer = deviceNameBuffer; 542 uniFilename.Length *= sizeof(WCHAR); 543 uniFilename.MaximumLength = uniFilename.Length + sizeof(WCHAR); 544 545 h = (HANDLE)(-1); 546 for(i=0; i<4; i++) { 547 InitializeObjectAttributes(&ObjectAttributes, &uniFilename, OBJ_CASE_INSENSITIVE, NULL, NULL); 548 if(h == ((HANDLE)-1)) { 549 RC = NtCreateFile(&h, 550 GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE | FILE_READ_ATTRIBUTES, 551 &ObjectAttributes, 552 &ioStatus, 553 NULL, 554 FILE_ATTRIBUTE_NORMAL, 555 ((i & 1) ? 0 : FILE_SHARE_READ) | ((i & 2) ? 0 : FILE_SHARE_WRITE), 556 FILE_OPEN, 557 FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED | FILE_WRITE_THROUGH | FILE_NO_INTERMEDIATE_BUFFERING, 558 NULL, 559 0); 560 if(!NT_SUCCESS(RC)) { 561 UDFPrint((" opened i2=%x\n", i)); 562 h = ((HANDLE)-1); 563 } 564 } 565 } 566 #endif //NT_NATIVE_MODE 567 if(h != ((HANDLE)-1)) { 568 #ifndef CDRW_W32 569 #ifdef UDF_FORMAT_MEDIA 570 if(fms->opt_flush || fms->opt_probe) { 571 return h; 572 } 573 #endif //UDF_FORMAT_MEDIA 574 my_retrieve_vol_type(Vcb, fn); 575 #else 576 my_retrieve_vol_type(fn); 577 #endif //CDRW_W32 578 if(!NT_SUCCESS(MyLockVolume(h,pLockMode))) { 579 #ifndef CDRW_W32 580 if(retry < MAX_INVALIDATE_VOLUME_RETRY) { 581 retry++; 582 if(!Privilege(SE_TCB_NAME, TRUE)) { 583 UDFPrint(("SE_TCB privilege not held\n")); 584 } else 585 if(DeviceIoControl(h,FSCTL_INVALIDATE_VOLUMES,&h,sizeof(h),NULL,0,&returned,NULL) ) { 586 UDFPrint((" FSCTL_INVALIDATE_VOLUMES ok, status %x\n", GetLastError())); 587 CloseHandle(h); 588 continue; 589 } else { 590 //#ifndef CDRW_W32 591 UDFPrint((" FSCTL_INVALIDATE_VOLUMES failed, error %x\n", GetLastError())); 592 RC = GetLastError(); 593 if(DeviceIoControl(h,IOCTL_UDF_INVALIDATE_VOLUMES,&h,sizeof(h),NULL,0,&returned,NULL) ) { 594 UDFPrint((" IOCTL_UDF_INVALIDATE_VOLUMES ok, status %x\n", GetLastError())); 595 CloseHandle(h); 596 continue; 597 } 598 UDFPrint((" IOCTL_UDF_INVALIDATE_VOLUMES, error %x\n", GetLastError())); 599 //#endif //CDRW_W32 600 } 601 UserPrint(("can't lock volume, retry\n")); 602 CloseHandle(h); 603 continue; 604 } 605 #endif //CDRW_W32 606 UserPrint(("can't lock volume\n")); 607 #ifndef NT_NATIVE_MODE 608 // In native mode the volume can be not mounted yet !!! 609 CantLock = TRUE; 610 CloseHandle(h); 611 h = NULL; 612 goto try_as_file; 613 #endif //NT_NATIVE_MODE 614 } 615 //#ifndef CDRW_W32 616 if(!DeviceIoControl(h,FSCTL_ALLOW_EXTENDED_DASD_IO,NULL,0,NULL,0,&returned,NULL)) { 617 UDFPrint(("Warning: can't allow extended DASD i/o\n")); 618 } 619 //#endif //CDRW_W32 620 621 UDFPrint((" opened, h=%x\n", h)); 622 return h; 623 } 624 RC = GetLastError(); 625 626 #ifndef NT_NATIVE_MODE 627 h = CreateFileW(deviceNameBuffer, GENERIC_READ, 628 FILE_SHARE_READ, 629 NULL, 630 OPEN_EXISTING, 631 FILE_ATTRIBUTE_NORMAL, NULL); 632 #else //NT_NATIVE_MODE 633 RC = NtCreateFile(&h, 634 GENERIC_READ | SYNCHRONIZE | FILE_READ_ATTRIBUTES, 635 &ObjectAttributes, 636 &ioStatus, 637 NULL, 638 FILE_ATTRIBUTE_NORMAL, 639 FILE_SHARE_READ, 640 FILE_OPEN, 641 FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED | FILE_WRITE_THROUGH, 642 NULL, 643 0); 644 if(!NT_SUCCESS(RC)) { 645 h = ((HANDLE)-1); 646 } 647 #endif //NT_NATIVE_MODE 648 if(h != ((HANDLE)-1)) { 649 650 UDFPrint((" opened R/O, h=%x\n", h)); 651 #ifndef CDRW_W32 652 my_retrieve_vol_type(Vcb, fn); 653 #else 654 my_retrieve_vol_type(fn); 655 #endif 656 657 UserPrint(("read-only open\n")); 658 if(!NT_SUCCESS(MyLockVolume(h,pLockMode))) { 659 #ifndef CDRW_W32 660 if(retry < MAX_INVALIDATE_VOLUME_RETRY) { 661 retry++; 662 if(!Privilege(SE_TCB_NAME, TRUE)) { 663 UDFPrint(("SE_TCB privilege not held\n")); 664 } else 665 if(DeviceIoControl(h,FSCTL_INVALIDATE_VOLUMES,&h,sizeof(h),NULL,0,&returned,NULL) ) { 666 CloseHandle(h); 667 continue; 668 } 669 UserPrint(("can't lock read-only volumem retry")); 670 CloseHandle(h); 671 continue; 672 } 673 #endif //CDRW_W32 674 UserPrint(("can't lock read-only volume")); 675 #ifndef NT_NATIVE_MODE 676 CantLock = TRUE; 677 CloseHandle(h); 678 h = NULL; 679 goto try_as_file; 680 #endif //NT_NATIVE_MODE 681 } 682 // write_cdfs = TRUE; 683 // DeviceIoControl(h,FSCTL_DISMOUNT_VOLUME,NULL,0,NULL,0,&returned,NULL); 684 return h; 685 } 686 #ifndef NT_NATIVE_MODE 687 try_as_file: 688 #endif //NT_NATIVE_MODE 689 690 #ifndef CDRW_W32 691 #ifdef UDF_FORMAT_MEDIA 692 fms-> 693 #endif 694 open_as_device = FALSE; 695 // open as plain file 696 Vcb->PhDeviceType = FILE_DEVICE_DISK; 697 #endif //CDRW_W32 698 699 UserPrint(("try image file\n")); 700 #ifndef NT_NATIVE_MODE 701 h = CreateFileW(fn, GENERIC_READ | GENERIC_WRITE, 702 FILE_SHARE_READ, 703 NULL, 704 CREATE_ALWAYS, 705 FILE_ATTRIBUTE_NORMAL, NULL); 706 #else //NT_NATIVE_MODE 707 RC = NtCreateFile(&h, 708 GENERIC_READ | SYNCHRONIZE, 709 &ObjectAttributes, 710 &ioStatus, 711 NULL, 712 FILE_ATTRIBUTE_NORMAL, 713 FILE_SHARE_READ, 714 FILE_OPEN, 715 FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED | FILE_WRITE_THROUGH, 716 NULL, 717 0); 718 if(!NT_SUCCESS(RC)) { 719 h = ((HANDLE)-1); 720 } 721 #endif //NT_NATIVE_MODE 722 if(h == ((HANDLE)-1)) { 723 724 RC = GetLastError(); 725 if(CantLock) { 726 #ifndef CDRW_W32 727 my_exit( 728 #ifdef UDF_FORMAT_MEDIA 729 fms, 730 #endif 731 MKUDF_CANT_LOCK_VOL); 732 #else 733 return NULL; 734 #endif //CDRW_W32 735 } 736 #ifndef CDRW_W32 737 UserPrint(("error opening device or image file")); 738 my_exit( 739 #ifdef UDF_FORMAT_MEDIA 740 fms, 741 #endif 742 MKUDF_CANT_OPEN_FILE); 743 #else 744 return NULL; 745 #endif //CDRW_W32 746 } 747 UDFPrint((" opened as file, h=%x\n", h)); 748 break; 749 750 } while(TRUE); 751 return h; 752 } // end my_open() 753 754 #endif //LIBUDF 755 756 #ifndef CDRW_W32 757 758 uint64 759 udf_lseek64( 760 HANDLE fd, 761 uint64 offset, 762 int whence) 763 { 764 LONG offh = (ULONG)(offset>>32); 765 LONG offl; 766 offl = SetFilePointer(fd, (ULONG)offset, &offh, whence); 767 if(offl == -1 && offh == -1) { 768 return -1; 769 } 770 return (((uint64)offh) << 32) | (uint64)offl; 771 } // end udf_lseek64() 772 773 #ifdef LIBUDFFMT 774 BOOLEAN 775 udf_get_sizes( 776 IN PDEVICE_OBJECT DeviceObject, 777 IN ULONG* blocks 778 ) 779 { 780 ULONG bs; 781 int64 sz; 782 ULONG RC; 783 784 RC = _lphUdf->lpGetSizeFunc(_lphUdf->lpParameter, &sz, &bs); 785 786 (*blocks) = (ULONG)(sz/bs); 787 788 return(OS_SUCCESS(RC)); 789 } 790 #endif //LIBUDFFMT 791 792 #include "string_lib.cpp" 793 794 #ifdef _BROWSE_UDF_ 795 #ifndef LIBUDF 796 797 ULONG 798 UDFGetDevType( 799 PDEVICE_OBJECT DeviceObject 800 ) 801 { 802 if(DeviceObject && DeviceObject == Vcb->TargetDeviceObject) { 803 return Vcb->PhDeviceType; 804 } 805 return FILE_DEVICE_DISK; 806 } // end UDFGetDevType() 807 808 #else // LIBUDF 809 810 ULONG 811 UDFGetDevType( 812 PDEVICE_OBJECT DeviceObject 813 ) 814 { 815 #define lphUdf ((PUDF_VOL_HANDLE_I)(DeviceObject->lpContext)) 816 return lphUdf->bHddDevice ? FILE_DEVICE_DISK : FILE_DEVICE_CD_ROM; 817 #undef lphUdf 818 } // end UDFGetDevType() 819 820 #endif // LIBUDF 821 822 #endif //_BROWSE_UDF_ 823 824 #endif //CDRW_W32 825 826 #ifndef NT_NATIVE_MODE 827 828 #ifdef PRINT_DBG_CONSOLE 829 CHAR dbg_print_tmp_buff[2048]; 830 831 BOOLEAN was_enter = TRUE; 832 833 extern "C" 834 VOID 835 PrintDbgConsole( 836 PCHAR DebugMessage, 837 ... 838 ) 839 { 840 int len; 841 va_list ap; 842 va_start(ap, DebugMessage); 843 844 if(was_enter) { 845 strcpy(&dbg_print_tmp_buff[0], JS_DBG_PREFIX); 846 len = _vsnprintf(&dbg_print_tmp_buff[sizeof(JS_DBG_PREFIX)-1], 2047-sizeof(JS_DBG_PREFIX), DebugMessage, ap); 847 } else { 848 len = _vsnprintf(&dbg_print_tmp_buff[0], 2047, DebugMessage, ap); 849 } 850 dbg_print_tmp_buff[2047] = 0; 851 if(len > 0 && 852 (dbg_print_tmp_buff[len-1] == '\n' || 853 dbg_print_tmp_buff[len-1] == '\r') ) { 854 was_enter = TRUE; 855 } else { 856 was_enter = FALSE; 857 } 858 859 OutputDebugString(&dbg_print_tmp_buff[0]); 860 861 va_end(ap); 862 863 } // end PrintDbgConsole() 864 #else // PRINT_DBG_CONSOLE 865 VOID 866 PrintDbgConsole( 867 PCHAR DebugMessage, 868 ... 869 ) 870 { 871 } // end ClassDebugPrint() 872 #endif //PRINT_DBG_CONSOLE 873 874 BOOLEAN 875 RtlTimeFieldsToTime( 876 IN PTIME_FIELDS TimeFields, 877 IN PLARGE_INTEGER Time 878 ) 879 { 880 SYSTEMTIME st; 881 882 st.wYear = TimeFields->Year; 883 st.wMonth = TimeFields->Month; 884 st.wDayOfWeek = 0; 885 st.wDay = TimeFields->Day; 886 st.wHour = TimeFields->Hour; 887 st.wMinute = TimeFields->Minute; 888 st.wSecond = TimeFields->Second; 889 st.wMilliseconds = TimeFields->Milliseconds; 890 891 return SystemTimeToFileTime(&st, (PFILETIME)Time); 892 } // end RtlTimeFieldsToTime() 893 894 BOOLEAN 895 RtlTimeToTimeFields( 896 IN PLARGE_INTEGER Time, 897 IN PTIME_FIELDS TimeFields 898 ) 899 { 900 SYSTEMTIME st; 901 BOOLEAN retval; 902 903 retval = FileTimeToSystemTime((PFILETIME)Time, &st); 904 905 TimeFields->Year = st.wYear; 906 TimeFields->Month = st.wMonth; 907 TimeFields->Weekday = st.wDayOfWeek; 908 TimeFields->Day = st.wDay; 909 TimeFields->Hour = st.wHour; 910 TimeFields->Minute = st.wMinute; 911 TimeFields->Second = st.wSecond; 912 TimeFields->Milliseconds = st.wMilliseconds; 913 914 return retval; 915 } // end () 916 917 #endif //NT_NATIVE_MODE 918 919 #ifdef USE_THREAD_HEAPS 920 921 HANDLE MemLock = NULL; 922 923 VOID 924 ExInitThreadPools() 925 { 926 MemLock = CreateMutex(NULL, 0, NULL); 927 } 928 929 VOID 930 ExDeInitThreadPools() 931 { 932 if(MemLock) 933 CloseHandle(MemLock); 934 } 935 936 #define MAX_THREADS_WITH_OWN_POOL 128 937 938 typedef struct _THREAD_POOL_LIST_ITEM { 939 HANDLE HeapHandle; 940 ULONG ThreadId; 941 } THREAD_POOL_LIST_ITEM, *PTHREAD_POOL_LIST_ITEM; 942 943 ULONG LastThreadPool = -1; 944 THREAD_POOL_LIST_ITEM ThreadPoolList[MAX_THREADS_WITH_OWN_POOL]; 945 946 extern "C" 947 PVOID 948 #ifdef KERNEL_MODE_MM_BEHAVIOR 949 _ExAllocatePool_( 950 #else 951 ExAllocatePool( 952 #endif 953 ULONG MemoryType, 954 ULONG Size 955 ) 956 { 957 ULONG i; 958 ULONG ThreadId = GetCurrentThreadId(); 959 BOOLEAN found = FALSE; 960 961 WaitForSingleObject(MemLock,-1); 962 963 for(i=0; i<(LastThreadPool+1); i++) { 964 if(ThreadPoolList[i].ThreadId == ThreadId) { 965 found = TRUE; 966 break; 967 } 968 } 969 if(found) { 970 ReleaseMutex(MemLock); 971 return HeapAlloc(ThreadPoolList[i].HeapHandle, HEAP_NO_SERIALIZE, Size); 972 } 973 for(i=0; i<(LastThreadPool+1); i++) { 974 if(ThreadPoolList[i].ThreadId == -1) { 975 break; 976 } 977 } 978 if(i>=MAX_THREADS_WITH_OWN_POOL) { 979 ReleaseMutex(MemLock); 980 return NULL; 981 } 982 ThreadPoolList[i].ThreadId = ThreadId; 983 ThreadPoolList[i].HeapHandle = HeapCreate(HEAP_NO_SERIALIZE, 128*PAGE_SIZE, 0); 984 if(!ThreadPoolList[i].HeapHandle) { 985 ThreadPoolList[i].ThreadId = -1; 986 ReleaseMutex(MemLock); 987 return NULL; 988 } 989 990 if(i+1 > LastThreadPool+1) 991 LastThreadPool = i; 992 993 ReleaseMutex(MemLock); 994 995 return HeapAlloc(ThreadPoolList[i].HeapHandle, HEAP_NO_SERIALIZE, Size); 996 997 } // end ExAllocatePool() 998 999 extern "C" 1000 VOID 1001 #ifdef KERNEL_MODE_MM_BEHAVIOR 1002 _ExFreePool_( 1003 #else 1004 ExFreePool( 1005 #endif 1006 PVOID Addr 1007 ) 1008 { 1009 ULONG ThreadId = GetCurrentThreadId(); 1010 ULONG i; 1011 1012 WaitForSingleObject(MemLock,-1); 1013 for(i=0; i<(LastThreadPool+1); i++) { 1014 if(ThreadPoolList[i].ThreadId == ThreadId) { 1015 break; 1016 } 1017 } 1018 if(i+1 > LastThreadPool+1) { 1019 // Not found 1020 BrutePoint(); 1021 //__asm int 3; 1022 return; 1023 } 1024 HeapFree(ThreadPoolList[i].HeapHandle, HEAP_NO_SERIALIZE, Addr); 1025 1026 ReleaseMutex(MemLock); 1027 1028 } // end ExFreePool() 1029 1030 extern "C" 1031 VOID 1032 ExFreeThreadPool() 1033 { 1034 ULONG ThreadId = GetCurrentThreadId(); 1035 ULONG i; 1036 1037 WaitForSingleObject(MemLock,-1); 1038 for(i=0; i<(LastThreadPool+1); i++) { 1039 if(ThreadPoolList[i].ThreadId == ThreadId) { 1040 break; 1041 } 1042 } 1043 if(i+1 > LastThreadPool+1) { 1044 // Not found 1045 BrutePoint(); 1046 //__asm int 3; 1047 return; 1048 } 1049 HeapDestroy(ThreadPoolList[i].HeapHandle); 1050 ThreadPoolList[i].HeapHandle = INVALID_HANDLE_VALUE; 1051 ThreadPoolList[i].ThreadId = -1; 1052 1053 ReleaseMutex(MemLock); 1054 } 1055 1056 #endif //USE_THREAD_HEAPS 1057 1058 #if defined(KERNEL_MODE_MM_BEHAVIOR) 1059 extern "C" 1060 PVOID 1061 ExAllocatePool( 1062 ULONG MemoryType, 1063 ULONG Size 1064 ) 1065 { 1066 PVOID Addr; 1067 PVOID uAddr; 1068 if(Size < PAGE_SIZE) { 1069 #ifdef USE_THREAD_HEAPS 1070 Addr = _ExAllocatePool_(MemoryType, Size+8); 1071 #else 1072 Addr = GlobalAlloc(GMEM_DISCARDABLE, Size+8); 1073 #endif 1074 if(!Addr) 1075 return NULL; 1076 uAddr = ((PCHAR)Addr)+8; 1077 } else { 1078 #ifdef USE_THREAD_HEAPS 1079 Addr = _ExAllocatePool_(MemoryType, Size+PAGE_SIZE*2); 1080 #else 1081 Addr = GlobalAlloc(GMEM_DISCARDABLE, Size+PAGE_SIZE*2); 1082 #endif 1083 if(!Addr) 1084 return NULL; 1085 uAddr = (PVOID)(((ULONG)(((PCHAR)Addr)+PAGE_SIZE)) & ~(PAGE_SIZE-1)); 1086 } 1087 *(((PULONG)uAddr)-2) = (ULONG)Addr; 1088 *(((PULONG)uAddr)-1) = 0xFEDCBA98; 1089 return uAddr; 1090 } // end ExAllocatePool() 1091 1092 extern "C" 1093 VOID 1094 ExFreePool( 1095 PVOID uAddr 1096 ) 1097 { 1098 PVOID Addr; 1099 1100 if(*(((PULONG)uAddr)-1) == 0xFEDCBA98) { 1101 Addr = (PVOID)(*(((PULONG)uAddr)-2)); 1102 #ifdef USE_THREAD_HEAPS 1103 _ExFreePool_(Addr); 1104 #else 1105 GlobalFree(Addr); 1106 #endif 1107 return; 1108 } 1109 BrutePoint(); 1110 } // end ExFreePool() 1111 #endif //defined(KERNEL_MODE_MM_BEHAVIOR) || defined(NT_NATIVE_MODE) 1112 1113 #ifdef _lphUdf 1114 #undef _lphUdf 1115 #endif //_lphUdf 1116 1117 extern "C" 1118 BOOLEAN 1119 ProbeMemory( 1120 PVOID MemPtr, 1121 ULONG Length, 1122 BOOLEAN ForWrite 1123 ) 1124 { 1125 ULONG i; 1126 UCHAR a; 1127 if(!MemPtr && !Length) 1128 return TRUE; 1129 if(!MemPtr || !Length) 1130 return FALSE; 1131 _SEH2_TRY { 1132 a = ((PCHAR)MemPtr)[Length-1]; 1133 if(ForWrite) { 1134 ((PCHAR)MemPtr)[Length-1] = a; 1135 } 1136 for(i=0; i<Length; i+=PAGE_SIZE) { 1137 a = ((PCHAR)MemPtr)[i]; 1138 if(ForWrite) { 1139 ((PCHAR)MemPtr)[i] = a; 1140 } 1141 } 1142 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { 1143 return FALSE; 1144 } _SEH2_END; 1145 return TRUE; 1146 } // end ProbeMemory() 1147 1148 #ifdef NT_NATIVE_MODE 1149 #include "env_spec_nt.cpp" 1150 #endif //NT_NATIVE_MODE 1151