Reactos
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