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
SkinLoad(PWCHAR path,HINSTANCE hInstance,HINSTANCE hPrevInstance,int nCmdShow)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
UDFPhSendIOCTL(IN ULONG IoControlCode,IN PDEVICE_OBJECT DeviceObject,IN PVOID InputBuffer,IN ULONG InputBufferLength,OUT PVOID OutputBuffer,IN ULONG OutputBufferLength,IN BOOLEAN OverrideVerify,OUT PVOID Iosb OPTIONAL)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
UDFPhReadSynchronous(PDEVICE_OBJECT DeviceObject,PVOID Buffer,ULONG Length,LONGLONG Offset,PULONG ReadBytes,ULONG Flags)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
UDFPhWriteSynchronous(PDEVICE_OBJECT DeviceObject,PVOID Buffer,ULONG Length,LONGLONG Offset,PULONG WrittenBytes,ULONG Flags)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
set_image_size(HANDLE h,int64 len)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
get_file_size(HANDLE h)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
set_file_pointer(HANDLE h,int64 sz)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
write(PVCB Vcb,HANDLE h,PCHAR buff,ULONG len)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
Privilege(LPTSTR pszPrivilege,BOOL bEnable)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
MyLockVolume(HANDLE h,ULONG * pLockMode)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
MyUnlockVolume(HANDLE h,ULONG * pLockMode)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
my_retrieve_vol_type(PVCB Vcb,PWCHAR fn)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
my_open(PVCB Vcb,PWCHAR fn)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
udf_lseek64(HANDLE fd,uint64 offset,int whence)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
udf_get_sizes(IN PDEVICE_OBJECT DeviceObject,IN ULONG * blocks)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
UDFGetDevType(PDEVICE_OBJECT DeviceObject)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
UDFGetDevType(PDEVICE_OBJECT DeviceObject)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
PrintDbgConsole(PCHAR DebugMessage,...)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
PrintDbgConsole(PCHAR DebugMessage,...)866 PrintDbgConsole(
867 PCHAR DebugMessage,
868 ...
869 )
870 {
871 } // end ClassDebugPrint()
872 #endif //PRINT_DBG_CONSOLE
873
874 BOOLEAN
RtlTimeFieldsToTime(IN PTIME_FIELDS TimeFields,IN PLARGE_INTEGER Time)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
RtlTimeToTimeFields(IN PLARGE_INTEGER Time,IN PTIME_FIELDS TimeFields)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
ExInitThreadPools()924 ExInitThreadPools()
925 {
926 MemLock = CreateMutex(NULL, 0, NULL);
927 }
928
929 VOID
ExDeInitThreadPools()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
_ExAllocatePool_(ULONG MemoryType,ULONG Size)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
_ExFreePool_(PVOID Addr)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
ExFreeThreadPool()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
ExAllocatePool(ULONG MemoryType,ULONG Size)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
ExFreePool(PVOID uAddr)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
ProbeMemory(PVOID MemPtr,ULONG Length,BOOLEAN ForWrite)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