Reactos
at master 1150 lines 29 kB view raw
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 8ULONG LockMode = 0; 9BOOLEAN opt_invalidate_volume = FALSE; 10#endif //UDF_FORMAT_MEDIA 11 12#ifndef CDRW_W32 13#ifndef UDF_FORMAT_MEDIA 14BOOLEAN open_as_device = FALSE; 15#endif //UDF_FORMAT_MEDIA 16#ifdef USE_SKIN_MODEL 17 18PSKIN_API SkinAPI = NULL; 19 20PSKIN_API 21SkinLoad( 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 51extern 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 65NTSTATUS 66UDFPhSendIOCTL( 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 105NTSTATUS 106UDFPhReadSynchronous( 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 150NTSTATUS 151UDFPhWriteSynchronous( 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 206NTSTATUS 207UDFPhWriteVerifySynchronous( 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 246VOID 247set_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 261int64 262get_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 273int64 274set_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 292ULONG 293write( 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 320BOOL 321Privilege( 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 372extern "C" 373ULONG 374MyLockVolume( 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 399extern "C" 400ULONG 401MyUnlockVolume( 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 418void 419my_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 453extern "C" 454HANDLE 455my_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 687try_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 758uint64 759udf_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 774BOOLEAN 775udf_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 797ULONG 798UDFGetDevType( 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 810ULONG 811UDFGetDevType( 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 829CHAR dbg_print_tmp_buff[2048]; 830 831BOOLEAN was_enter = TRUE; 832 833extern "C" 834VOID 835PrintDbgConsole( 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 865VOID 866PrintDbgConsole( 867 PCHAR DebugMessage, 868 ... 869 ) 870{ 871} // end ClassDebugPrint() 872#endif //PRINT_DBG_CONSOLE 873 874BOOLEAN 875RtlTimeFieldsToTime( 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 894BOOLEAN 895RtlTimeToTimeFields( 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 921HANDLE MemLock = NULL; 922 923VOID 924ExInitThreadPools() 925{ 926 MemLock = CreateMutex(NULL, 0, NULL); 927} 928 929VOID 930ExDeInitThreadPools() 931{ 932 if(MemLock) 933 CloseHandle(MemLock); 934} 935 936#define MAX_THREADS_WITH_OWN_POOL 128 937 938typedef struct _THREAD_POOL_LIST_ITEM { 939 HANDLE HeapHandle; 940 ULONG ThreadId; 941} THREAD_POOL_LIST_ITEM, *PTHREAD_POOL_LIST_ITEM; 942 943ULONG LastThreadPool = -1; 944THREAD_POOL_LIST_ITEM ThreadPoolList[MAX_THREADS_WITH_OWN_POOL]; 945 946extern "C" 947PVOID 948#ifdef KERNEL_MODE_MM_BEHAVIOR 949_ExAllocatePool_( 950#else 951ExAllocatePool( 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 999extern "C" 1000VOID 1001#ifdef KERNEL_MODE_MM_BEHAVIOR 1002_ExFreePool_( 1003#else 1004ExFreePool( 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 1030extern "C" 1031VOID 1032ExFreeThreadPool() 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) 1059extern "C" 1060PVOID 1061ExAllocatePool( 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 1092extern "C" 1093VOID 1094ExFreePool( 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 1117extern "C" 1118BOOLEAN 1119ProbeMemory( 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