add_subdirectory(mup)
add_subdirectory(npfs)
add_subdirectory(ntfs)
+if(MSVC)
+ # FIXME: Make sure this compiles with the *nix builder before enabling it
+ add_subdirectory(udfs)
+endif()
--- /dev/null
+
+include_directories(include)
+
+set_cpp(WITH_RUNTIME)
+
+list(APPEND SOURCE
+ udf_info/alloc.cpp
+ udf_info/dirtree.cpp
+ udf_info/extent.cpp
+ udf_info/mount.cpp
+ udf_info/phys_eject.cpp
+ udf_info/physical.cpp
+ udf_info/remap.cpp
+ udf_info/udf_info.cpp
+ cleanup.cpp
+ close.cpp
+ create.cpp
+ devcntrl.cpp
+ dircntrl.cpp
+ env_spec.cpp
+ fastio.cpp
+ fileinfo.cpp
+ filter.cpp
+ flush.cpp
+ fscntrl.cpp
+ lockctrl.cpp
+ mem.cpp
+ misc.cpp
+ namesup.cpp
+ pnp.cpp
+ read.cpp
+ secursup.cpp
+ shutdown.cpp
+ sys_spec.cpp
+ udf_dbg.cpp
+ udfinit.cpp
+ unload.cpp
+ verfysup.cpp
+ volinfo.cpp
+ wcache.cpp
+ write.cpp)
+
+add_library(udfs SHARED ${SOURCE} udffs.rc)
+if(MSVC)
+ # FIXME: Make sure we marked all what needs to be marked with stdcall before removing this.
+ add_target_compile_flags(udfs "/Gz")
+else()
+ # FIXME: Tons of warnings.
+ replace_compile_flags("-Werror" " ")
+ add_target_compile_flags(udfs "-fpermissive")
+endif()
+set_module_type(udfs kernelmodedriver)
+target_link_libraries(udfs ${PSEH_LIB})
+add_importlibs(udfs ntoskrnl hal)
+add_cd_file(TARGET udfs DESTINATION reactos/system32/drivers NO_CAB FOR all)
--- /dev/null
+
+#ifdef CROSSNT_DECL
+#undef CROSSNT_DECL
+#undef CROSSNT_DECL_EX
+#endif //CROSSNT_DECL
+
+/***************************/
+#ifdef CROSSNT_DECL_API
+
+#define CROSSNT_DECL(type, dspec, name, args, callargs) \
+typedef type (dspec *ptr##name) args; \
+extern "C" ptr##name CrNt##name; \
+type dspec CrNt##name##_impl args;
+
+#define CROSSNT_DECL_EX(mod, type, dspec, name, args, callargs) \
+typedef type (dspec *ptr##name) args; \
+extern "C" ptr##name CrNt##name; \
+type dspec CrNt##name##_impl args;
+
+#endif //CROSSNT_DECL_API
+
+/***************************/
+#ifdef CROSSNT_DECL_STUB
+
+#define CROSSNT_DECL(type, dspec, name, args, callargs) \
+extern "C" ptr##name CrNt##name = NULL; \
+
+#define CROSSNT_DECL_EX(mod, type, dspec, name, args, callargs) \
+extern "C" ptr##name CrNt##name = NULL; \
+
+#endif //CROSSNT_DECL_STUB
+
+/***************************/
+#ifdef CROSSNT_INIT_STUB
+
+#define CROSSNT_DECL(type, dspec, name, args, callargs) \
+ KdPrint(("Init " #name " cur %x\n", CrNt##name)); \
+ if(!CrNt##name) { \
+ CrNt##name = (ptr##name)CrNtGetProcAddress(g_hNtosKrnl, #name); \
+ KdPrint((" GetProcAddr(NTOSKRNL.EXE," #name ") = %x\n", CrNt##name)); \
+ if(!CrNt##name) { \
+ CrNt##name = CrNt##name##_impl; \
+ } \
+ KdPrint((" final %\n", CrNt##name)); \
+ }
+
+#define CROSSNT_DECL_EX(mod, type, dspec, name, args, callargs) \
+ KdPrint(("Init " mod "," #name " cur %x\n", CrNt##name)); \
+ if(!CrNt##name) { \
+ CrNt##name = (ptr##name)CrNtGetProcAddress(CrNtGetModuleBase(mod), #name); \
+ KdPrint((" GetProcAddr(" mod "," #name ") = %x\n", CrNt##name)); \
+ if(!CrNt##name) { \
+ CrNt##name = CrNt##name##_impl; \
+ } \
+ KdPrint((" final %x\n", CrNt##name)); \
+ }
+
+#endif //CROSSNT_INIT_STUB
--- /dev/null
+
+CROSSNT_DECL(
+HANDLE,__stdcall,
+PsGetCurrentProcessId,(),())
+
+CROSSNT_DECL(
+HANDLE,__stdcall,
+PsGetCurrentThreadId,(),())
+
+CROSSNT_DECL(
+BOOLEAN,
+__fastcall,
+KeTestSpinLock,(
+ IN PKSPIN_LOCK SpinLock
+ ),
+ (
+ SpinLock
+ ))
+
+CROSSNT_DECL(
+LONG,
+__fastcall,
+InterlockedIncrement,(
+ IN OUT PLONG Addend
+ ),
+ (
+ IN OUT PLONG Addend
+ ))
+
+CROSSNT_DECL(
+LONG,
+__fastcall,
+InterlockedDecrement,(
+ IN OUT PLONG Addend
+ ),
+ (
+ IN OUT PLONG Addend
+ ))
+
+CROSSNT_DECL(
+LONG,
+__fastcall,
+InterlockedExchangeAdd,(
+ IN OUT PLONG Addend,
+ IN LONG Increment
+ ),
+ (
+ IN OUT PLONG Addend,
+ IN LONG Increment
+ ))
+
+CROSSNT_DECL(
+PVOID,
+__fastcall,
+InterlockedCompareExchange,(
+ IN OUT PVOID *Destination,
+ IN PVOID ExChange,
+ IN PVOID Comperand
+ ),
+ (
+ IN OUT PVOID *Destination,
+ IN PVOID ExChange,
+ IN PVOID Comperand
+ ))
+
+CROSSNT_DECL_EX("HAL.DLL",
+KIRQL,__stdcall,
+KeRaiseIrqlToDpcLevel,(),())
+
+CROSSNT_DECL_EX("HAL.DLL",
+KIRQL,__stdcall,
+KeRaiseIrqlToSynchLevel,(),())
+
+CROSSNT_DECL_EX("NDIS.SYS",
+VOID,
+__stdcall,
+NdisInitializeReadWriteLock,(
+ IN PNDIS_RW_LOCK Lock
+ ),
+ (
+ Lock
+ ))
+
+CROSSNT_DECL_EX("NDIS.SYS",
+VOID,
+__stdcall,
+NdisAcquireReadWriteLock,(
+ IN PNDIS_RW_LOCK Lock,
+ IN BOOLEAN fWrite,
+ IN PLOCK_STATE LockState
+ ),
+ (
+ Lock,
+ fWrite,
+ LockState
+ ))
+
+CROSSNT_DECL_EX("NDIS.SYS",
+VOID,
+__stdcall,
+NdisReleaseReadWriteLock,(
+ IN PNDIS_RW_LOCK Lock,
+ IN PLOCK_STATE LockState
+ ),
+ (
+ Lock,
+ LockState
+ ))
+
--- /dev/null
+#ifndef __CROSS_VERSION_LIB_NT__H__
+#define __CROSS_VERSION_LIB_NT__H__
+
+extern "C" {
+
+#pragma pack(push, 8)
+
+#if !defined(NT_INCLUDED)
+#include <ntddk.h> // various NT definitions
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include "ntddk_ex.h"
+
+#include "rwlock.h"
+
+#ifdef CROSS_NT_INTERNAL
+#include "ilock.h"
+#endif //CROSS_NT_INTERNAL
+
+#include "misc.h"
+#include "tools.h"
+
+#pragma pack(pop)
+
+extern "C"
+NTSTATUS
+CrNtInit(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ );
+
+extern "C"
+ULONG
+CrNtGetCPUGen();
+
+extern "C"
+PVOID
+CrNtGetModuleBase(
+ IN PCHAR pModuleName
+ );
+
+extern "C"
+PVOID
+CrNtFindModuleBaseByPtr(
+ IN PVOID ptrInSection,
+ IN PCHAR ptrExportedName
+ );
+
+extern "C"
+PVOID
+CrNtGetProcAddress(
+ PVOID ModuleBase,
+ PCHAR pFunctionName
+ );
+
+typedef BOOLEAN (__stdcall *ptrCrNtPsGetVersion)(
+ PULONG MajorVersion OPTIONAL,
+ PULONG MinorVersion OPTIONAL,
+ PULONG BuildNumber OPTIONAL,
+ PUNICODE_STRING CSDVersion OPTIONAL
+ );
+
+extern "C"
+ptrCrNtPsGetVersion CrNtPsGetVersion;
+
+typedef NTSTATUS (__stdcall *ptrCrNtNtQuerySystemInformation)(
+ IN SYSTEM_INFORMATION_CLASS SystemInfoClass,
+ OUT PVOID SystemInfoBuffer,
+ IN ULONG SystemInfoBufferSize,
+ OUT PULONG BytesReturned OPTIONAL
+ );
+
+extern "C"
+ptrCrNtNtQuerySystemInformation CrNtNtQuerySystemInformation;
+
+extern "C"
+PVOID
+CrNtSkipImportStub(
+ PVOID p
+ );
+
+extern "C" {
+
+extern ULONG MajorVersion;
+extern ULONG MinorVersion;
+extern ULONG BuildNumber;
+extern ULONG SPVersion;
+
+extern HANDLE g_hNtosKrnl;
+extern HANDLE g_hHal;
+
+extern PCHAR g_KeNumberProcessors;
+
+};
+
+#define WinVer_Is351 (MajorVersion==0x03)
+#define WinVer_IsNT (MajorVersion==0x04)
+#define WinVer_Is2k (MajorVersion==0x05 && MinorVersion==0x00)
+#define WinVer_IsXP (MajorVersion==0x05 && MinorVersion==0x01)
+#define WinVer_IsXPp (MajorVersion==0x05 && MinorVersion>=0x01)
+#define WinVer_IsdNET (MajorVersion==0x05 && MinorVersion==0x02)
+#define WinVer_IsdNETp ((MajorVersion==0x05 && MinorVersion>=0x02) || (MajorVersion>0x05))
+#define WinVer_IsVista (MajorVersion==0x06 && MinorVersion==0x00)
+
+#define WinVer_Id() ((MajorVersion << 8) | MinorVersion)
+
+#define WinVer_351 (0x0351)
+#define WinVer_NT (0x0400)
+#define WinVer_ROS (0x0401)
+#define WinVer_2k (0x0500)
+#define WinVer_XP (0x0501)
+#define WinVer_dNET (0x0502)
+#define WinVer_Vista (0x0600)
+
+#ifdef _DEBUG
+
+// NT3.51 doesn't export strlen() and strcmp()
+// The same time, Release build doesn't depend no these functions since they are inlined
+
+size_t __cdecl CrNtstrlen (
+ const char * str
+ );
+
+int __cdecl CrNtstrcmp (
+ const char * src,
+ const char * dst
+ );
+
+#define strlen CrNtstrlen
+#define strcmp CrNtstrcmp
+
+#endif //_DEBUG
+
+#define CROSSNT_DECL_API
+
+#include "CrNtDecl.h"
+#include "CrNtStubs.h"
+
+#undef CROSSNT_DECL_API
+
+}; // end extern "C"
+
+#endif //__CROSS_VERSION_LIB_NT__H__
\ No newline at end of file
--- /dev/null
+#ifndef __CROSS_NT_INTERLOCKED__H__
+#define __CROSS_NT_INTERLOCKED__H__
+
+LONG
+__fastcall
+CrNtInterlockedIncrement_impl_i386_MP(
+ IN OUT PLONG Addend
+ );
+
+LONG
+__fastcall
+CrNtInterlockedIncrement_impl_i386_UP(
+ IN OUT PLONG Addend
+ );
+
+/********************************************************/
+
+LONG
+__fastcall
+CrNtInterlockedDecrement_impl_i386_MP(
+ IN OUT PLONG Addend
+ );
+
+LONG
+__fastcall
+CrNtInterlockedDecrement_impl_i386_UP(
+ IN OUT PLONG Addend
+ );
+
+/********************************************************/
+
+LONG
+__fastcall
+CrNtInterlockedExchangeAdd_impl_i386_MP(
+ IN OUT PLONG Addend,
+ IN LONG Increment
+ );
+
+LONG
+__fastcall
+CrNtInterlockedExchangeAdd_impl_i386_UP(
+ IN OUT PLONG Addend,
+ IN LONG Increment
+ );
+
+/********************************************************/
+
+PVOID
+__fastcall
+CrNtInterlockedCompareExchange_impl_i386_MP(
+ IN OUT PVOID *Destination,
+ IN PVOID ExChange,
+ IN PVOID Comperand
+ );
+
+PVOID
+__fastcall
+CrNtInterlockedCompareExchange_impl_i386_UP(
+ IN OUT PVOID *Destination,
+ IN PVOID ExChange,
+ IN PVOID Comperand
+ );
+
+#endif __CROSS_NT_INTERLOCKED__H__
--- /dev/null
+#ifndef __CROSSNT_MISC__H__
+#define __CROSSNT_MISC__H__
+
+#ifdef _X86_
+
+typedef void
+(__fastcall *ptrMOV_DD_SWP)(
+ void* a, // ECX
+ void* b // EDX
+ );
+extern "C" ptrMOV_DD_SWP _MOV_DD_SWP;
+
+extern "C"
+void
+__fastcall
+_MOV_DD_SWP_i486(
+ void* a, // ECX
+ void* b // EDX
+ );
+
+extern "C"
+void
+__fastcall
+_MOV_DD_SWP_i386(
+ void* a, // ECX
+ void* b // EDX
+ );
+#define MOV_DD_SWP(a,b) _MOV_DD_SWP(&(a),&(b))
+
+/********************/
+
+extern "C"
+void
+__fastcall
+_MOV_DW_SWP(
+ void* a, // ECX
+ void* b // EDX
+ );
+
+#define MOV_DW_SWP(a,b) _MOV_DW_SWP(&(a),&(b))
+
+/********************/
+
+typedef void
+(__fastcall *ptrREVERSE_DD)(
+ void* a // ECX
+ );
+extern "C" ptrREVERSE_DD _REVERSE_DD;
+
+void
+__fastcall
+_REVERSE_DD_i486(
+ void* a // ECX
+ );
+
+void
+__fastcall
+_REVERSE_DD_i386(
+ void* a // ECX
+ );
+#define REVERSE_DD(a) _REVERSE_DD(&(a))
+
+/********************/
+
+extern "C"
+void
+__fastcall
+_REVERSE_DW(
+ void* a // ECX
+ );
+
+#define REVERSE_DW(a) _REVERSE_DW(&(a))
+
+/********************/
+
+extern "C"
+void
+__fastcall
+_MOV_DW2DD_SWP(
+ void* a, // ECX
+ void* b // EDX
+ );
+
+#define MOV_DW2DD_SWP(a,b) _MOV_DW2DD_SWP(&(a),&(b))
+
+/********************/
+
+extern "C"
+void
+__fastcall
+_MOV_SWP_DW2DD(
+ void* a, // ECX
+ void* b // EDX
+ );
+
+#define MOV_SWP_DW2DD(a,b) _MOV_SWP_DW2DD(&(a),&(b))
+
+/********************/
+
+extern "C"
+void
+__fastcall
+_MOV_MSF(
+ void* a, // ECX
+ void* b // EDX
+ );
+#define MOV_MSF(a,b) _MOV_MSF(&(a),&(b))
+
+/********************/
+
+typedef void
+(__fastcall *ptrMOV_MSF_SWP)(
+ void* a, // ECX
+ void* b // EDX
+ );
+extern "C" ptrMOV_MSF_SWP _MOV_MSF_SWP;
+
+extern "C"
+void
+__fastcall
+_MOV_MSF_SWP_i486(
+ void* a, // ECX
+ void* b // EDX
+ );
+
+extern "C"
+void
+__fastcall
+_MOV_MSF_SWP_i386(
+ void* a, // ECX
+ void* b // EDX
+ );
+#define MOV_MSF_SWP(a,b) _MOV_MSF_SWP(&(a),&(b))
+
+/********************/
+
+extern "C"
+void
+__fastcall
+_XCHG_DD(
+ void* a, // ECX
+ void* b // EDX
+ );
+#define XCHG_DD(a,b) _XCHG_DD(&(a),&(b))
+
+#endif //_X86_
+
+#endif // __CROSSNT_MISC__H__
--- /dev/null
+#ifndef __CROSS_NT_RWLOCK__H__
+#define __CROSS_NT_RWLOCK__H__
+
+#ifndef MAXIMUM_PROCESSORS
+#define MAXIMUM_PROCESSORS 32
+#endif
+
+typedef union _NDIS_RW_LOCK_REFCOUNT {
+ unsigned int RefCount;
+ UCHAR cacheLine[16]; // One refCount per cache line
+} NDIS_RW_LOCK_REFCOUNT;
+
+typedef struct _NDIS_RW_LOCK {
+ union {
+ struct {
+ KSPIN_LOCK SpinLock;
+ PVOID Context;
+ };
+ UCHAR Reserved[16];
+ };
+
+ NDIS_RW_LOCK_REFCOUNT RefCount[MAXIMUM_PROCESSORS];
+} NDIS_RW_LOCK, *PNDIS_RW_LOCK;
+
+typedef struct _LOCK_STATE {
+ USHORT LockState;
+ KIRQL OldIrql;
+} LOCK_STATE, *PLOCK_STATE;
+
+#define RWLOCK_STATE_FREE 0
+#define RWLOCK_STATE_READ_ACQUIRED 1
+#define RWLOCK_STATE_WRITE_ACQUIRED 2
+#define RWLOCK_STATE_RECURSIVE 3
+#define RWLOCK_STATE_RELEASED 0xffff
+
+#define RWLOCK_FOR_WRITE TRUE
+#define RWLOCK_FOR_READ FALSE
+
+#endif /* __CROSS_NT_RWLOCK__H__ */
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+/*************************************************************************
+*
+* File: Sys_Spec.cpp
+*
+* Module: UDF File System Driver
+* (both User and Kernel mode execution)
+*
+* Description:
+* Contains system-secific code
+*
+*************************************************************************/
+
+
+/*
+ This routine converts UDF timestamp to NT time
+ */
+LONGLONG
+UDFTimeToNT(
+ IN PUDF_TIME_STAMP UdfTime
+ )
+{
+ LONGLONG NtTime;
+ TIME_FIELDS TimeFields;
+
+ TimeFields.Milliseconds = (USHORT)(UdfTime->centiseconds * 10 + UdfTime->hundredsOfMicroseconds / 100);
+ TimeFields.Second = (USHORT)(UdfTime->second);
+ TimeFields.Minute = (USHORT)(UdfTime->minute);
+ TimeFields.Hour = (USHORT)(UdfTime->hour);
+ TimeFields.Day = (USHORT)(UdfTime->day);
+ TimeFields.Month = (USHORT)(UdfTime->month);
+ TimeFields.Year = (USHORT)((UdfTime->year < 1601) ? 1601 : UdfTime->year);
+
+ if (!RtlTimeFieldsToTime(&TimeFields, (PLARGE_INTEGER)&NtTime)) {
+ NtTime = 0;
+ } else {
+ ExLocalTimeToSystemTime( (PLARGE_INTEGER)&NtTime, (PLARGE_INTEGER)&NtTime );
+ }
+
+ return NtTime;
+} // end UDFTimeToNT()
+
+
+/*
+ This routine converts NT time to UDF timestamp
+ */
+VOID
+UDFTimeToUDF(
+ IN LONGLONG NtTime,
+ OUT PUDF_TIME_STAMP UdfTime
+ )
+{
+ if(!NtTime) return;
+ LONGLONG LocalTime;
+
+ TIME_FIELDS TimeFields;
+
+ ExSystemTimeToLocalTime( (PLARGE_INTEGER)&NtTime, (PLARGE_INTEGER)&LocalTime );
+ RtlTimeToTimeFields( (PLARGE_INTEGER)&LocalTime, &TimeFields );
+
+ LocalTime /= 10; // microseconds
+ UdfTime->microseconds = (UCHAR)(NtTime % 100);
+ LocalTime /= 100; // hundreds of microseconds
+ UdfTime->hundredsOfMicroseconds = (UCHAR)(NtTime % 100);
+ LocalTime /= 100; // centiseconds
+ UdfTime->centiseconds = (UCHAR)(TimeFields.Milliseconds / 10);
+ UdfTime->second = (UCHAR)(TimeFields.Second);
+ UdfTime->minute = (UCHAR)(TimeFields.Minute);
+ UdfTime->hour = (UCHAR)(TimeFields.Hour);
+ UdfTime->day = (UCHAR)(TimeFields.Day);
+ UdfTime->month = (UCHAR)(TimeFields.Month);
+ UdfTime->year = (USHORT)(TimeFields.Year);
+ UdfTime->typeAndTimezone = (TIMESTAMP_TYPE_LOCAL << 14);
+} // end UDFTimeToUDF()
+
+/*
+ */
+ULONG
+UDFAttributesToNT(
+ IN PDIR_INDEX_ITEM FileDirNdx,
+ IN tag* FileEntry
+ )
+{
+ ASSERT(FileDirNdx);
+ if( (FileDirNdx->FI_Flags & UDF_FI_FLAG_SYS_ATTR) &&
+ !(FileDirNdx->FI_Flags & UDF_FI_FLAG_LINKED))
+ return FileDirNdx->SysAttr;
+
+ ULONG NTAttr = 0;
+ ULONG attr = 0; //permissions
+ USHORT Flags = 0;
+ USHORT Type = 0;
+ UCHAR FCharact = 0;
+
+ if(!FileEntry) {
+ if(!FileDirNdx->FileInfo)
+ return 0;
+ ValidateFileInfo(FileDirNdx->FileInfo);
+ FileEntry = FileDirNdx->FileInfo->Dloc->FileEntry;
+ }
+ if(FileEntry->tagIdent == TID_FILE_ENTRY) {
+ attr = ((PFILE_ENTRY)FileEntry)->permissions;
+ Flags = ((PFILE_ENTRY)FileEntry)->icbTag.flags;
+ Type = ((PFILE_ENTRY)FileEntry)->icbTag.fileType;
+ if(((PFILE_ENTRY)FileEntry)->fileLinkCount > 1)
+ FileDirNdx->FI_Flags |= UDF_FI_FLAG_LINKED;
+ } else {
+ attr = ((PEXTENDED_FILE_ENTRY)FileEntry)->permissions;
+ Flags = ((PEXTENDED_FILE_ENTRY)FileEntry)->icbTag.flags;
+ Type = ((PEXTENDED_FILE_ENTRY)FileEntry)->icbTag.fileType;
+ if(((PEXTENDED_FILE_ENTRY)FileEntry)->fileLinkCount > 1)
+ FileDirNdx->FI_Flags |= UDF_FI_FLAG_LINKED;
+ }
+ FCharact = FileDirNdx->FileCharacteristics;
+
+ if(Flags & ICB_FLAG_SYSTEM) NTAttr |= FILE_ATTRIBUTE_SYSTEM;
+ if(Flags & ICB_FLAG_ARCHIVE) NTAttr |= FILE_ATTRIBUTE_ARCHIVE;
+ if((Type == UDF_FILE_TYPE_DIRECTORY) ||
+ (Type == UDF_FILE_TYPE_STREAMDIR) ||
+ (FCharact & FILE_DIRECTORY)) {
+ NTAttr |= FILE_ATTRIBUTE_DIRECTORY;
+#ifdef UDF_DBG
+ } else {
+ //NTAttr |= FILE_ATTRIBUTE_NORMAL;
+#endif
+ }
+ if(FCharact & FILE_HIDDEN) NTAttr |= FILE_ATTRIBUTE_HIDDEN;
+ if( !(attr & PERM_O_WRITE) &&
+ !(attr & PERM_G_WRITE) &&
+ !(attr & PERM_U_WRITE) &&
+ !(attr & PERM_O_DELETE) &&
+ !(attr & PERM_G_DELETE) &&
+ !(attr & PERM_U_DELETE) ) {
+ NTAttr |= FILE_ATTRIBUTE_READONLY;
+ }
+ FileDirNdx->SysAttr = NTAttr;
+ return NTAttr;
+} // end UDFAttributesToNT()
+
+/*
+ */
+VOID
+UDFAttributesToUDF(
+ IN PDIR_INDEX_ITEM FileDirNdx,
+ IN tag* FileEntry,
+ IN ULONG NTAttr
+ )
+{
+ PULONG attr; //permissions
+ PUSHORT Flags;
+ PUCHAR Type;
+ PUCHAR FCharact;
+
+ NTAttr &= UDF_VALID_FILE_ATTRIBUTES;
+
+ if(!FileEntry) {
+ ASSERT(FileDirNdx);
+ if(!FileDirNdx->FileInfo)
+ return;
+ ValidateFileInfo(FileDirNdx->FileInfo);
+ FileEntry = FileDirNdx->FileInfo->Dloc->FileEntry;
+ FileDirNdx->FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
+ }
+ if(FileEntry->tagIdent == TID_FILE_ENTRY) {
+ attr = &((PFILE_ENTRY)FileEntry)->permissions;
+ Flags = &((PFILE_ENTRY)FileEntry)->icbTag.flags;
+ Type = &((PFILE_ENTRY)FileEntry)->icbTag.fileType;
+ } else {
+ attr = &((PEXTENDED_FILE_ENTRY)FileEntry)->permissions;
+ Flags = &((PEXTENDED_FILE_ENTRY)FileEntry)->icbTag.flags;
+ Type = &((PEXTENDED_FILE_ENTRY)FileEntry)->icbTag.fileType;
+ }
+ FCharact = &(FileDirNdx->FileCharacteristics);
+
+ if((*FCharact & FILE_DIRECTORY) ||
+ (*Type == UDF_FILE_TYPE_STREAMDIR) ||
+ (*Type == UDF_FILE_TYPE_DIRECTORY)) {
+ *FCharact |= FILE_DIRECTORY;
+ if(*Type != UDF_FILE_TYPE_STREAMDIR)
+ *Type = UDF_FILE_TYPE_DIRECTORY;
+ *attr |= (PERM_O_EXEC | PERM_G_EXEC | PERM_U_EXEC);
+ NTAttr |= FILE_ATTRIBUTE_DIRECTORY;
+ NTAttr &= ~FILE_ATTRIBUTE_NORMAL;
+ } else {
+ *FCharact &= ~FILE_DIRECTORY;
+ *Type = UDF_FILE_TYPE_REGULAR;
+ *attr &= ~(PERM_O_EXEC | PERM_G_EXEC | PERM_U_EXEC);
+ }
+
+ if(NTAttr & FILE_ATTRIBUTE_SYSTEM) {
+ *Flags |= ICB_FLAG_SYSTEM;
+ } else {
+ *Flags &= ~ICB_FLAG_SYSTEM;
+ }
+ if(NTAttr & FILE_ATTRIBUTE_ARCHIVE) {
+ *Flags |= ICB_FLAG_ARCHIVE;
+ } else {
+ *Flags &= ~ICB_FLAG_ARCHIVE;
+ }
+ if(NTAttr & FILE_ATTRIBUTE_HIDDEN) {
+ *FCharact |= FILE_HIDDEN;
+ } else {
+ *FCharact &= ~FILE_HIDDEN;
+ }
+ *attr |= (PERM_O_READ | PERM_G_READ | PERM_U_READ);
+ if(!(NTAttr & FILE_ATTRIBUTE_READONLY)) {
+ *attr |= (PERM_O_WRITE | PERM_G_WRITE | PERM_U_WRITE |
+ PERM_O_DELETE | PERM_G_DELETE | PERM_U_DELETE |
+ PERM_O_CHATTR | PERM_G_CHATTR | PERM_U_CHATTR);
+ } else {
+ *attr &= ~(PERM_O_WRITE | PERM_G_WRITE | PERM_U_WRITE |
+ PERM_O_DELETE | PERM_G_DELETE | PERM_U_DELETE |
+ PERM_O_CHATTR | PERM_G_CHATTR | PERM_U_CHATTR);
+ }
+ FileDirNdx->SysAttr = NTAttr;
+ if(FileDirNdx->FileInfo)
+ FileDirNdx->FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
+ FileDirNdx->FI_Flags |= UDF_FI_FLAG_FI_MODIFIED;
+ return;
+} // end UDFAttributesToUDF()
+
+#ifndef _CONSOLE
+/*
+ This routine fills PFILE_BOTH_DIR_INFORMATION structure (NT)
+ */
+NTSTATUS
+UDFFileDirInfoToNT(
+ IN PVCB Vcb,
+ IN PDIR_INDEX_ITEM FileDirNdx,
+ OUT PFILE_BOTH_DIR_INFORMATION NTFileInfo
+ )
+{
+ PFILE_ENTRY FileEntry;
+ UNICODE_STRING UdfName;
+ UNICODE_STRING DosName;
+ PEXTENDED_FILE_ENTRY ExFileEntry;
+ USHORT Ident;
+ BOOLEAN ReadSizes;
+ NTSTATUS status;
+ PtrUDFNTRequiredFCB NtReqFcb;
+
+ KdPrint(("@=%#x, FileDirNdx %x\n", &Vcb, FileDirNdx));
+
+ ASSERT((ULONG)NTFileInfo > 0x1000);
+ RtlZeroMemory(NTFileInfo, sizeof(FILE_BOTH_DIR_INFORMATION));
+
+ DosName.Buffer = (PWCHAR)&(NTFileInfo->ShortName);
+ DosName.MaximumLength = sizeof(NTFileInfo->ShortName); // 12*sizeof(WCHAR)
+
+ _SEH2_TRY {
+ KdPrint((" DirInfoToNT: %*.*S\n", FileDirNdx->FName.Length/sizeof(WCHAR), FileDirNdx->FName.Length/sizeof(WCHAR), FileDirNdx->FName));
+ } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+ KdPrint((" DirInfoToNT: exception when printing file name\n"));
+ } _SEH2_END;
+
+ if(FileDirNdx->FileInfo) {
+ KdPrint((" FileInfo\n"));
+ // validate FileInfo
+ ValidateFileInfo(FileDirNdx->FileInfo);
+ if(UDFGetFileLinkCount(FileDirNdx->FileInfo) > 1)
+ FileDirNdx->FI_Flags |= UDF_FI_FLAG_LINKED;
+ FileEntry = (PFILE_ENTRY)(FileDirNdx->FileInfo->Dloc->FileEntry);
+ // read required sizes from Fcb (if any) if file is not linked
+ // otherwise we should read them from FileEntry
+ if(FileDirNdx->FileInfo->Fcb) {
+ KdPrint((" Fcb\n"));
+ NtReqFcb = FileDirNdx->FileInfo->Fcb->NTRequiredFCB;
+ NTFileInfo->CreationTime.QuadPart = NtReqFcb->CreationTime.QuadPart;
+ NTFileInfo->LastWriteTime.QuadPart = NtReqFcb->LastWriteTime.QuadPart;
+ NTFileInfo->LastAccessTime.QuadPart = NtReqFcb->LastAccessTime.QuadPart;
+ NTFileInfo->ChangeTime.QuadPart = NtReqFcb->ChangeTime.QuadPart;
+// NTFileInfo->AllocationSize.QuadPart = NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart;
+ NTFileInfo->AllocationSize.QuadPart = FileDirNdx->AllocationSize;
+/* FileDirNdx->FileSize =
+ NTFileInfo->EndOfFile.QuadPart = NtReqFcb->CommonFCBHeader.FileSize.QuadPart;*/
+ NTFileInfo->EndOfFile.QuadPart = FileDirNdx->FileSize;
+ if(FileDirNdx->FI_Flags & UDF_FI_FLAG_SYS_ATTR) {
+ KdPrint((" SYS_ATTR\n"));
+ NTFileInfo->FileAttributes = FileDirNdx->SysAttr;
+ goto get_name_only;
+ }
+ FileDirNdx->CreationTime = NTFileInfo->CreationTime.QuadPart;
+ FileDirNdx->LastWriteTime = NTFileInfo->LastWriteTime.QuadPart;
+ FileDirNdx->LastAccessTime = NTFileInfo->LastAccessTime.QuadPart;
+ FileDirNdx->ChangeTime = NTFileInfo->ChangeTime.QuadPart;
+ goto get_attr_only;
+ }
+ ASSERT(FileEntry);
+ } else if(!(FileDirNdx->FI_Flags & UDF_FI_FLAG_SYS_ATTR) ||
+ (FileDirNdx->FI_Flags & UDF_FI_FLAG_LINKED)) {
+ LONG_AD feloc;
+
+ KdPrint((" !SYS_ATTR\n"));
+ FileEntry = (PFILE_ENTRY)MyAllocatePool__(NonPagedPool, Vcb->LBlockSize);
+ if(!FileEntry) return STATUS_INSUFFICIENT_RESOURCES;
+
+ feloc.extLength = Vcb->LBlockSize;
+ feloc.extLocation = FileDirNdx->FileEntryLoc;
+
+ if(!NT_SUCCESS(status = UDFReadFileEntry(Vcb, &feloc, FileEntry, &Ident))) {
+ KdPrint((" !UDFReadFileEntry\n"));
+ MyFreePool__(FileEntry);
+ FileEntry = NULL;
+ goto get_name_only;
+ }
+ ReadSizes = TRUE;
+ } else {
+ KdPrint((" FileDirNdx\n"));
+ NTFileInfo->CreationTime.QuadPart = FileDirNdx->CreationTime;
+ NTFileInfo->LastWriteTime.QuadPart = FileDirNdx->LastWriteTime;
+ NTFileInfo->LastAccessTime.QuadPart = FileDirNdx->LastAccessTime;
+ NTFileInfo->ChangeTime.QuadPart = FileDirNdx->ChangeTime;
+ NTFileInfo->FileAttributes = FileDirNdx->SysAttr;
+ NTFileInfo->AllocationSize.QuadPart = FileDirNdx->AllocationSize;
+ NTFileInfo->EndOfFile.QuadPart = FileDirNdx->FileSize;
+ NTFileInfo->EaSize = 0;
+ FileEntry = NULL;
+ goto get_name_only;
+ }
+
+ if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK)
+ goto get_name_only;
+
+ KdPrint((" direct\n"));
+ if(FileEntry->descTag.tagIdent == TID_FILE_ENTRY) {
+ KdPrint((" TID_FILE_ENTRY\n"));
+ if(ReadSizes) {
+ KdPrint((" ReadSizes\n"));
+ // Times
+ FileDirNdx->CreationTime = NTFileInfo->CreationTime.QuadPart =
+ FileDirNdx->LastWriteTime = NTFileInfo->LastWriteTime.QuadPart = UDFTimeToNT(&(FileEntry->modificationTime));
+ FileDirNdx->LastAccessTime = NTFileInfo->LastAccessTime.QuadPart = UDFTimeToNT(&(FileEntry->accessTime));
+ FileDirNdx->ChangeTime = NTFileInfo->ChangeTime.QuadPart = UDFTimeToNT(&(FileEntry->attrTime));
+ // FileSize
+ FileDirNdx->FileSize =
+ NTFileInfo->EndOfFile.QuadPart =
+ FileEntry->informationLength;
+ KdPrint((" informationLength=%I64x, lengthAllocDescs=%I64x\n",
+ FileEntry->informationLength,
+ FileEntry->lengthAllocDescs
+ ));
+ // AllocSize
+ FileDirNdx->AllocationSize =
+ NTFileInfo->AllocationSize.QuadPart =
+ (FileEntry->informationLength + Vcb->LBlockSize - 1) & ~((LONGLONG)(Vcb->LBlockSize) - 1);
+ }
+// NTFileInfo->EaSize = 0;//FileEntry->lengthExtendedAttr;
+ } else if(FileEntry->descTag.tagIdent == TID_EXTENDED_FILE_ENTRY) {
+ ExFileEntry = (PEXTENDED_FILE_ENTRY)FileEntry;
+ KdPrint((" PEXTENDED_FILE_ENTRY\n"));
+ if(ReadSizes) {
+ KdPrint((" ReadSizes\n"));
+ // Times
+ FileDirNdx->CreationTime = NTFileInfo->CreationTime.QuadPart = UDFTimeToNT(&(ExFileEntry->createTime));
+ FileDirNdx->LastWriteTime = NTFileInfo->LastWriteTime.QuadPart = UDFTimeToNT(&(ExFileEntry->modificationTime));
+ FileDirNdx->LastAccessTime = NTFileInfo->LastAccessTime.QuadPart = UDFTimeToNT(&(ExFileEntry->accessTime));
+ FileDirNdx->ChangeTime = NTFileInfo->ChangeTime.QuadPart = UDFTimeToNT(&(ExFileEntry->attrTime));
+ // FileSize
+ FileDirNdx->FileSize =
+ NTFileInfo->EndOfFile.QuadPart =
+ ExFileEntry->informationLength;
+ KdPrint((" informationLength=%I64x, lengthAllocDescs=%I64x\n",
+ FileEntry->informationLength,
+ FileEntry->lengthAllocDescs
+ ));
+ // AllocSize
+ FileDirNdx->AllocationSize =
+ NTFileInfo->AllocationSize.QuadPart =
+ (ExFileEntry->informationLength + Vcb->LBlockSize - 1) & ~((LONGLONG)(Vcb->LBlockSize) - 1);
+ }
+// NTFileInfo->EaSize = 0;//ExFileEntry->lengthExtendedAttr;
+ } else {
+ KdPrint((" ???\n"));
+ goto get_name_only;
+ }
+
+get_attr_only:
+
+ KdPrint((" get_attr"));
+ // do some substitutions
+ if(!FileDirNdx->CreationTime) {
+ FileDirNdx->CreationTime = NTFileInfo->CreationTime.QuadPart = Vcb->VolCreationTime;
+ }
+ if(!FileDirNdx->LastAccessTime) {
+ FileDirNdx->LastAccessTime = NTFileInfo->LastAccessTime.QuadPart = FileDirNdx->CreationTime;
+ }
+ if(!FileDirNdx->LastWriteTime) {
+ FileDirNdx->LastWriteTime = NTFileInfo->LastWriteTime.QuadPart = FileDirNdx->CreationTime;
+ }
+ if(!FileDirNdx->ChangeTime) {
+ FileDirNdx->ChangeTime = NTFileInfo->ChangeTime.QuadPart = FileDirNdx->CreationTime;
+ }
+
+ FileDirNdx->SysAttr =
+ NTFileInfo->FileAttributes = UDFAttributesToNT(FileDirNdx, (tag*)FileEntry);
+ FileDirNdx->FI_Flags |= UDF_FI_FLAG_SYS_ATTR;
+
+get_name_only:
+ // get filename in standard Unicode format
+ UdfName = FileDirNdx->FName;
+ NTFileInfo->FileNameLength = UdfName.Length;
+ RtlCopyMemory((PCHAR)&(NTFileInfo->FileName), (PCHAR)(UdfName.Buffer), UdfName.MaximumLength);
+ if(!(FileDirNdx->FI_Flags & UDF_FI_FLAG_DOS)) {
+ KdPrint((" !UDF_FI_FLAG_DOS"));
+ UDFDOSName(Vcb, &DosName, &UdfName,
+ (FileDirNdx->FI_Flags & UDF_FI_FLAG_KEEP_NAME) ? TRUE : FALSE);
+ NTFileInfo->ShortNameLength = (UCHAR)DosName.Length;
+ }
+ // report zero EOF & AllocSize for Dirs
+ if(FileDirNdx->FileCharacteristics & FILE_DIRECTORY) {
+ KdPrint((" FILE_DIRECTORY"));
+ NTFileInfo->AllocationSize.QuadPart =
+ NTFileInfo->EndOfFile.QuadPart = 0;
+ }
+ KdPrint((" AllocationSize=%I64x, NTFileInfo->EndOfFile=%I64x", NTFileInfo->AllocationSize.QuadPart, NTFileInfo->EndOfFile.QuadPart));
+ // free tmp buffer (if any)
+ KdPrint(("\n"));
+ if(FileEntry && !FileDirNdx->FileInfo)
+ MyFreePool__(FileEntry);
+ return STATUS_SUCCESS;
+} // end UDFFileDirInfoToNT()
+
+#endif //_CONSOLE
+
+#ifndef UDF_READ_ONLY_BUILD
+/*
+ This routine changes xxxTime field(s) in (Ext)FileEntry
+ */
+VOID
+UDFSetFileXTime(
+ IN PUDF_FILE_INFO FileInfo,
+ IN LONGLONG* CrtTime,
+ IN LONGLONG* AccTime,
+ IN LONGLONG* AttrTime,
+ IN LONGLONG* ChgTime
+ )
+{
+ USHORT Ident;
+ PDIR_INDEX_ITEM DirNdx;
+
+ ValidateFileInfo(FileInfo);
+
+ FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
+ DirNdx = UDFDirIndex(UDFGetDirIndexByFileInfo(FileInfo), FileInfo->Index);
+ Ident = FileInfo->Dloc->FileEntry->tagIdent;
+
+ if(Ident == TID_FILE_ENTRY) {
+ PFILE_ENTRY fe = (PFILE_ENTRY)(FileInfo->Dloc->FileEntry);
+
+ if(AccTime) {
+ if(DirNdx && *AccTime) DirNdx->LastAccessTime = *AccTime;
+ UDFTimeToUDF(*AccTime, &(fe->accessTime));
+ }
+ if(AttrTime) {
+ if(DirNdx && *AttrTime) DirNdx->ChangeTime = *AttrTime;
+ UDFTimeToUDF(*AttrTime, &(fe->attrTime));
+ }
+ if(ChgTime) {
+ if(DirNdx && *ChgTime) DirNdx->CreationTime =
+ DirNdx->LastWriteTime = *ChgTime;
+ UDFTimeToUDF(*ChgTime, &(fe->modificationTime));
+ } else
+ if(CrtTime) {
+ if(DirNdx && *CrtTime) DirNdx->CreationTime =
+ DirNdx->LastWriteTime = *CrtTime;
+ UDFTimeToUDF(*CrtTime, &(fe->modificationTime));
+ }
+
+ } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
+ PEXTENDED_FILE_ENTRY fe = (PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry);
+
+ if(AccTime) {
+ if(DirNdx && *AccTime) DirNdx->LastAccessTime = *AccTime;
+ UDFTimeToUDF(*AccTime, &(fe->accessTime));
+ }
+ if(AttrTime) {
+ if(DirNdx && *AttrTime) DirNdx->ChangeTime = *AttrTime;
+ UDFTimeToUDF(*AttrTime, &(fe->attrTime));
+ }
+ if(ChgTime) {
+ if(DirNdx && *ChgTime) DirNdx->LastWriteTime = *ChgTime;
+ UDFTimeToUDF(*ChgTime, &(fe->modificationTime));
+ }
+ if(CrtTime) {
+ if(DirNdx && *CrtTime) DirNdx->CreationTime = *CrtTime;
+ UDFTimeToUDF(*CrtTime, &(fe->createTime));
+ }
+
+ }
+} // end UDFSetFileXTime()
+#endif //UDF_READ_ONLY_BUILD
+
+/*
+ This routine gets xxxTime field(s) in (Ext)FileEntry
+ */
+VOID
+UDFGetFileXTime(
+ IN PUDF_FILE_INFO FileInfo,
+ OUT LONGLONG* CrtTime,
+ OUT LONGLONG* AccTime,
+ OUT LONGLONG* AttrTime,
+ OUT LONGLONG* ChgTime
+ )
+{
+ USHORT Ident;
+
+ ValidateFileInfo(FileInfo);
+
+ Ident = FileInfo->Dloc->FileEntry->tagIdent;
+
+ if(Ident == TID_FILE_ENTRY) {
+ PFILE_ENTRY fe = (PFILE_ENTRY)(FileInfo->Dloc->FileEntry);
+
+ if(AccTime) *AccTime = UDFTimeToNT(&(fe->accessTime));
+ if(AttrTime) *AttrTime = UDFTimeToNT(&(fe->attrTime));
+ if(ChgTime) *ChgTime = UDFTimeToNT(&(fe->modificationTime));
+ if(CrtTime) {
+ (*CrtTime) = *ChgTime;
+ }
+
+ } else if(Ident == TID_EXTENDED_FILE_ENTRY) {
+ PEXTENDED_FILE_ENTRY fe = (PEXTENDED_FILE_ENTRY)(FileInfo->Dloc->FileEntry);
+
+ if(AccTime) *AccTime = UDFTimeToNT(&(fe->accessTime));
+ if(AttrTime) *AttrTime = UDFTimeToNT(&(fe->attrTime));
+ if(ChgTime) *ChgTime = UDFTimeToNT(&(fe->modificationTime));
+ if(CrtTime) *CrtTime = UDFTimeToNT(&(fe->createTime));
+
+ }
+ if(CrtTime) {
+ if(!(*CrtTime))
+ KeQuerySystemTime((PLARGE_INTEGER)CrtTime);
+ if(AccTime && !(*AccTime)) (*AccTime) = *CrtTime;
+ if(AttrTime && !(*AttrTime)) (*AttrTime) = *CrtTime;
+ if(AccTime && !(*AccTime)) (*AccTime) = *CrtTime;
+ }
+} // end UDFGetFileXTime()
+
+VOID
+UDFNormalizeFileName(
+ IN PUNICODE_STRING FName,
+ IN USHORT valueCRC
+ )
+{
+ PWCHAR buffer;
+ USHORT len;
+
+ len = FName->Length/sizeof(WCHAR);
+ buffer = FName->Buffer;
+
+ // check for '', '.' & '..'
+ if(!len) return;
+ if(!buffer[len-1]) {
+ FName->Length-=sizeof(WCHAR);
+ len--;
+ }
+ if(!len) return;
+ if(buffer[0] == UNICODE_PERIOD) {
+ if(len == 1) return;
+ if((buffer[1] == UNICODE_PERIOD) && (len == 2)) return;
+ }
+
+ // check for trailing '.'
+ for(len--;len;len--) {
+ if( ((buffer[len] == UNICODE_PERIOD) || (buffer[len] == UNICODE_SPACE)) ) {
+ FName->Length-=sizeof(WCHAR);
+ buffer[len] = 0;
+ } else
+ break;
+ }
+} // end UDFNormalizeFileName()
+
+#ifndef _CONSOLE
+
+void
+__fastcall
+UDFDOSNameOsNative(
+ IN OUT PUNICODE_STRING DosName,
+ IN PUNICODE_STRING UdfName,
+ IN BOOLEAN KeepIntact
+ )
+{
+ PWCHAR dosName = DosName->Buffer;
+ PWCHAR udfName = UdfName->Buffer;
+ uint32 udfLen = UdfName->Length / sizeof(WCHAR);
+ GENERATE_NAME_CONTEXT Ctx;
+
+ if(KeepIntact &&
+ (udfLen <= 2) && (udfName[0] == UNICODE_PERIOD)) {
+ if((udfLen != 2) || (udfName[1] == UNICODE_PERIOD)) {
+ RtlCopyMemory(dosName, udfName, UdfName->Length);
+ DosName->Length = UdfName->Length;
+ return;
+ }
+ }
+ RtlZeroMemory(&Ctx, sizeof(GENERATE_NAME_CONTEXT));
+ RtlGenerate8dot3Name(UdfName, FALSE, &Ctx, DosName);
+
+} // UDFDOSNameOsNative()
+
+#endif //_CONSOLE
+
+/*VOID
+UDFNormalizeFileName(
+ IN PUNICODE_STRING FName,
+ IN USHORT valueCRC
+ )
+{
+ WCHAR _newName[UDF_NAME_LEN+5];
+ PWCHAR newName = (PWCHAR)(&_newName);
+ PWCHAR udfName = FName->Buffer;
+ LONG udfLen = FName->Length >> 1;
+
+ LONG index, newIndex = 0, extIndex = 0, newExtIndex = 0, trailIndex = 0;
+ BOOLEAN needsCRC = FALSE, hasExt = FALSE;
+ WCHAR ext[UDF_EXT_SIZE], current;
+
+ // handle CurrentDir ('.') and ParentDir ('..') cases
+ if((udfLen <= 2) && (udfName[0] == UNICODE_PERIOD)) {
+ if((udfLen != 2) || (udfName[1] == UNICODE_PERIOD))
+ return;
+ }
+
+ for (index = 0 ; index < udfLen ; index++) {
+ current = udfName[index];
+
+ // Look for illegal or unprintable characters.
+ if (UDFIsIllegalChar(current) || !UnicodeIsPrint(current)) {
+ needsCRC = TRUE;
+ current = ILLEGAL_CHAR_MARK;
+ // Skip Illegal characters(even spaces),
+ // but not periods.
+ while(index+1 < udfLen &&
+ (UDFIsIllegalChar(udfName[index+1]) ||
+ !UnicodeIsPrint(udfName[index+1])) &&
+ udfName[index+1] != UNICODE_PERIOD)
+ index++;
+ }
+
+ // Record position of extension, if one is found.
+ if ((current == UNICODE_PERIOD) && ((udfLen - index -1) <= UDF_EXT_SIZE)) {
+ if (udfLen == index + 1) {
+ // A trailing period is NOT an extension.
+ hasExt = FALSE;
+ } else {
+ hasExt = TRUE;
+ extIndex = index;
+ newExtIndex = newIndex;
+ }
+ } else if((current != UNICODE_PERIOD) && (current != UNICODE_SPACE)) {
+ trailIndex = index;
+ }
+
+// if (newIndex < MAXLEN) // tshi is always TRUE for WINNT
+ newName[newIndex] = current;
+ newIndex++;
+
+ // For OS2, 95 & NT, truncate any trailing periods and\or spaces.
+ if (trailIndex != (newIndex - 1)) {
+ newIndex = trailIndex + 1;
+ needsCRC = TRUE;
+ hasExt = FALSE; //* Trailing period does not make an extension.
+ }
+ }
+
+ if (needsCRC) {
+ int localExtIndex = 0;
+ if (hasExt) {
+ int maxFilenameLen;
+ //* Translate extension, and store it in ext.
+ for(index = 0; index<UDF_EXT_SIZE && extIndex + index +1 < udfLen; index++ ) {
+ current = udfName[extIndex + index + 1];
+ if (UDFIsIllegalChar(current) /*|| !UnicodeIsPrint(current)) {
+ needsCRC = TRUE;
+ // Replace Illegal and non-displayable chars
+ // with underscore.
+ current = ILLEGAL_CHAR_MARK;
+ // Skip any other illegal or non-displayable
+ // characters.
+ while(index + 1 < UDF_EXT_SIZE &&
+ (UDFIsIllegalChar(udfName[extIndex + index + 2]) ||
+ !UnicodeIsPrint(udfName[extIndex + index + 2])) )
+ index++;
+ }
+ ext[localExtIndex++] = current;
+ }
+ // Truncate filename to leave room for extension and CRC.
+ maxFilenameLen = ((UDF_NAME_LEN - 4) - localExtIndex - 1);
+ if (newIndex > maxFilenameLen) {
+ newIndex = maxFilenameLen;
+ } else {
+ newIndex = newExtIndex;
+ }
+ } else if (newIndex > UDF_NAME_LEN - 5) {
+ //If no extension, make sure to leave room for CRC.
+ newIndex = UDF_NAME_LEN - 5;
+ }
+ newName[newIndex++] = UNICODE_CRC_MARK; // Add mark for CRC.
+ //Calculate CRC from original filename from FileIdentifier.
+// valueCRC = UDFUnicodeCksum(fidName, fidNameLen);
+// / Convert 16-bits of CRC to hex characters.
+ newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12];
+ newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8];
+ newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4];
+ newName[newIndex++] = hexChar[(valueCRC & 0x000f)];
+ // Place a translated extension at end, if found.
+ if (hasExt) {
+ newName[newIndex++] = UNICODE_PERIOD;
+ for (index = 0;index < localExtIndex ;index++ ) {
+ newName[newIndex++] = ext[index];
+ }
+ }
+ }
+
+ if(FName->Length == (USHORT)newIndex*sizeof(WCHAR)) {
+ RtlCopyMemory(FName->Buffer, newName, newIndex*sizeof(WCHAR));
+ return;
+ }
+ MyFreePool__(FName->Buffer);
+ FName->Buffer = (PWCHAR)MyAllocatePool__(UDF_FILENAME_MT, (newIndex+1)*sizeof(WCHAR));
+ if(FName->Buffer) {
+ FName->Buffer[newIndex] = 0;
+ RtlCopyMemory(FName->Buffer, newName, newIndex*sizeof(WCHAR));
+ }
+ FName->Length = (USHORT)newIndex*sizeof(WCHAR);
+ FName->MaximumLength = (USHORT)(newIndex+1)*sizeof(WCHAR);
+}*/
+
+/*PUDF_FILE_INFO
+UDFAllocFileInfo(
+ return ExAllocateFromZone(&(UDFGlobalData.FileInfoZoneHeader));
+)*/
+
+#define STRING_BUFFER_ALIGNMENT (32)
+#define STRING_BUFFER_ALIGN(sz) (((sz)+STRING_BUFFER_ALIGNMENT)&(~((ULONG)(STRING_BUFFER_ALIGNMENT-1))))
+
+NTSTATUS
+MyAppendUnicodeStringToString_(
+ IN PUNICODE_STRING Str1,
+ IN PUNICODE_STRING Str2
+#ifdef UDF_TRACK_UNICODE_STR
+ ,IN PCHAR Tag
+#endif
+ )
+{
+ PWCHAR tmp;
+ USHORT i;
+
+#ifdef UDF_TRACK_UNICODE_STR
+ #define UDF_UNC_STR_TAG Tag
+#else
+ #define UDF_UNC_STR_TAG "AppUStr"
+#endif
+
+ tmp = Str1->Buffer;
+ i = Str1->Length + Str2->Length + sizeof(WCHAR);
+ ASSERT(Str1->MaximumLength);
+ if(i > Str1->MaximumLength) {
+ if(!MyReallocPool__((PCHAR)tmp, Str1->MaximumLength,
+ (PCHAR*)&tmp, STRING_BUFFER_ALIGN(i)*2) ) {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ Str1->MaximumLength = i*2;
+ Str1->Buffer = tmp;
+ }
+ RtlCopyMemory(((PCHAR)tmp)+Str1->Length, Str2->Buffer, Str2->Length);
+
+/* tmp = (PWCHAR)MyAllocatePoolTag__(NonPagedPool, i = Str1->Length + Str2->Length + sizeof(WCHAR), UDF_UNC_STR_TAG);
+ if(!tmp)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ RtlCopyMemory(tmp, Str1->Buffer, Str1->Length);
+ RtlCopyMemory(((PCHAR)tmp)+Str1->Length, Str2->Buffer, Str2->Length);*/
+ tmp[(i / sizeof(WCHAR)) - 1] = 0;
+ Str1->Length = i - sizeof(WCHAR);
+ //MyFreePool__(Str1->Buffer);
+#ifdef UDF_DBG
+ if(Str1->Buffer && (Str1->Length >= 2*sizeof(WCHAR))) {
+ ASSERT((Str1->Buffer[0] != L'\\') || (Str1->Buffer[1] != L'\\'));
+ }
+#endif // UDF_DBG
+ return STATUS_SUCCESS;
+
+#undef UDF_UNC_STR_TAG
+
+} // end MyAppendUnicodeStringToString()
+
+NTSTATUS
+MyAppendUnicodeToString_(
+ IN PUNICODE_STRING Str1,
+ IN PWSTR Str2
+#ifdef UDF_TRACK_UNICODE_STR
+ ,IN PCHAR Tag
+#endif
+ )
+{
+ PWCHAR tmp;
+ USHORT i;
+
+#ifdef UDF_TRACK_UNICODE_STR
+ #define UDF_UNC_STR_TAG Tag
+#else
+ #define UDF_UNC_STR_TAG "AppStr"
+#endif
+
+//#ifdef _X86_
+#ifdef _MSC_VER
+
+ __asm push ebx
+ __asm push esi
+
+ __asm xor ebx,ebx
+ __asm mov esi,Str2
+Scan_1:
+ __asm cmp [word ptr esi+ebx],0
+ __asm je EO_Scan
+ __asm add ebx,2
+ __asm jmp Scan_1
+EO_Scan:
+ __asm mov i,bx
+
+ __asm pop esi
+ __asm pop ebx
+
+#else // NO X86 optimization, use generic C/C++
+
+ i=0;
+ while(Str2[i]) {
+ i++;
+ }
+ i *= sizeof(WCHAR);
+
+#endif // _X86_
+
+ tmp = Str1->Buffer;
+ ASSERT(Str1->MaximumLength);
+ if((Str1->Length+i+sizeof(WCHAR)) > Str1->MaximumLength) {
+ if(!MyReallocPool__((PCHAR)tmp, Str1->MaximumLength,
+ (PCHAR*)&tmp, STRING_BUFFER_ALIGN(i + Str1->Length + sizeof(WCHAR))*2 ) ) {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ Str1->MaximumLength = STRING_BUFFER_ALIGN(i + sizeof(WCHAR))*2;
+ Str1->Buffer = tmp;
+ }
+ RtlCopyMemory(((PCHAR)tmp)+Str1->Length, Str2, i);
+ i+=Str1->Length;
+ tmp[(i / sizeof(WCHAR))] = 0;
+ Str1->Length = i;
+#ifdef UDF_DBG
+/* if(Str1->Buffer && (Str1->Length >= 2*sizeof(WCHAR))) {
+ ASSERT((Str1->Buffer[0] != L'\\') || (Str1->Buffer[1] != L'\\'));
+ }*/
+#endif // UDF_DBG
+ return STATUS_SUCCESS;
+
+#undef UDF_UNC_STR_TAG
+
+} // end MyAppendUnicodeToString_()
+
+NTSTATUS
+MyInitUnicodeString(
+ IN PUNICODE_STRING Str1,
+ IN PCWSTR Str2
+ )
+{
+
+ USHORT i;
+
+//#ifdef _X86_
+#ifdef _MSC_VER
+
+ __asm push ebx
+ __asm push esi
+
+ __asm xor ebx,ebx
+ __asm mov esi,Str2
+Scan_1:
+ __asm cmp [word ptr esi+ebx],0
+ __asm je EO_Scan
+ __asm add ebx,2
+ __asm jmp Scan_1
+EO_Scan:
+ __asm mov i,bx
+
+ __asm pop esi
+ __asm pop ebx
+
+#else // NO X86 optimization, use generic C/C++
+
+ i=0;
+ while(Str2[i]) {
+ i++;
+ }
+ i *= sizeof(WCHAR);
+
+#endif // _X86_
+
+ Str1->MaximumLength = STRING_BUFFER_ALIGN((Str1->Length = i) + sizeof(WCHAR));
+ Str1->Buffer = (PWCHAR)MyAllocatePool__(NonPagedPool, Str1->MaximumLength);
+ if(!Str1->Buffer)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ RtlCopyMemory(Str1->Buffer, Str2, i);
+ Str1->Buffer[i/sizeof(WCHAR)] = 0;
+ return STATUS_SUCCESS;
+
+} // end MyInitUnicodeString()
+
+NTSTATUS
+MyCloneUnicodeString(
+ IN PUNICODE_STRING Str1,
+ IN PUNICODE_STRING Str2
+ )
+{
+ Str1->MaximumLength = STRING_BUFFER_ALIGN((Str1->Length = Str2->Length) + sizeof(WCHAR));
+ Str1->Buffer = (PWCHAR)MyAllocatePool__(NonPagedPool, Str1->MaximumLength);
+ if(!Str1->Buffer)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ ASSERT(Str2->Buffer);
+ RtlCopyMemory(Str1->Buffer, Str2->Buffer, Str2->Length);
+ Str1->Buffer[Str1->Length/sizeof(WCHAR)] = 0;
+ return STATUS_SUCCESS;
+
+} // end MyCloneUnicodeString()
+
+/*
+ This routine checks do we needn't read something from disk to
+ obtain Attributes & so on
+ */
+BOOLEAN
+UDFIsDirInfoCached(
+ IN PVCB Vcb,
+ IN PUDF_FILE_INFO DirInfo
+ )
+{
+ PDIR_INDEX_HDR hDirNdx = DirInfo->Dloc->DirIndex;
+ PDIR_INDEX_ITEM DirNdx;
+ for(uint_di i=2; DirNdx = UDFDirIndex(hDirNdx,i); i++) {
+ if(!(DirNdx->FI_Flags & UDF_FI_FLAG_SYS_ATTR) ||
+ (DirNdx->FI_Flags & UDF_FI_FLAG_LINKED)) return FALSE;
+ }
+ return TRUE;
+} // end UDFIsDirInfoCached()
+
+#ifndef UDF_READ_ONLY_BUILD
+NTSTATUS
+UDFDoesOSAllowFileToBeTargetForRename__(
+ IN PUDF_FILE_INFO FileInfo
+ )
+{
+#ifndef _CONSOLE
+ NTSTATUS RC;
+#endif //_CONSOLE
+
+ if(UDFIsADirectory(FileInfo))
+ return STATUS_ACCESS_DENIED;
+ if(!FileInfo->ParentFile)
+ return STATUS_ACCESS_DENIED;
+
+ if(UDFAttributesToNT(UDFDirIndex(UDFGetDirIndexByFileInfo(FileInfo),FileInfo->Index),
+ FileInfo->Dloc->FileEntry) & FILE_ATTRIBUTE_READONLY)
+ return STATUS_ACCESS_DENIED;
+
+ if(!FileInfo->Fcb)
+ return STATUS_SUCCESS;
+#ifndef _CONSOLE
+ RC = UDFCheckAccessRights(NULL, NULL, FileInfo->Fcb, NULL, DELETE, 0);
+ if(!NT_SUCCESS(RC))
+ return RC;
+#endif //_CONSOLE
+ if(!FileInfo->Fcb)
+ return STATUS_SUCCESS;
+// RC = UDFMarkStreamsForDeletion(FileInfo->Fcb->Vcb, FileInfo->Fcb, TRUE); // Delete
+/* RC = UDFSetDispositionInformation(FileInfo->Fcb, NULL,
+ FileInfo->Fcb->Vcb, NULL, TRUE);
+ if(NT_SUCCESS(RC)) {
+ FileInfo->Fcb->FCBFlags |= UDF_FCB_DELETED;
+ if(UDFGetFileLinkCount(FileInfo) <= 1) {
+ FileInfo->Fcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_DELETED;
+ }
+ }
+ return RC;*/
+ return STATUS_ACCESS_DENIED;
+
+} // end UDFDoesOSAllowFileToBeTargetForRename__()
+
+NTSTATUS
+UDFDoesOSAllowFileToBeUnlinked__(
+ IN PUDF_FILE_INFO FileInfo
+ )
+{
+ PDIR_INDEX_HDR hCurDirNdx;
+ PDIR_INDEX_ITEM CurDirNdx;
+ uint_di i;
+// IO_STATUS_BLOCK IoStatus;
+
+ ASSERT(FileInfo->Dloc);
+
+ if(!FileInfo->ParentFile)
+ return STATUS_CANNOT_DELETE;
+ if(FileInfo->Dloc->SDirInfo)
+ return STATUS_CANNOT_DELETE;
+ if(!UDFIsADirectory(FileInfo))
+ return STATUS_SUCCESS;
+
+// UDFFlushAFile(FileInfo->Fcb, NULL, &IoStatus, 0);
+ hCurDirNdx = FileInfo->Dloc->DirIndex;
+ // check if we can delete all files
+ for(i=2; CurDirNdx = UDFDirIndex(hCurDirNdx,i); i++) {
+ // try to open Stream
+ if(CurDirNdx->FileInfo)
+ return STATUS_CANNOT_DELETE;
+ }
+// return UDFCheckAccessRights(NULL, NULL, FileInfo->Fcb, NULL, DELETE, 0);
+ return STATUS_SUCCESS;
+} // end UDFDoesOSAllowFileToBeUnlinked__()
+
+NTSTATUS
+UDFDoesOSAllowFilePretendDeleted__(
+ IN PUDF_FILE_INFO FileInfo
+ )
+{
+ PDIR_INDEX_HDR hDirNdx = UDFGetDirIndexByFileInfo(FileInfo);
+ if(!hDirNdx) return STATUS_CANNOT_DELETE;
+ PDIR_INDEX_ITEM DirNdx = UDFDirIndex(hDirNdx, FileInfo->Index);
+ if(!DirNdx) return STATUS_CANNOT_DELETE;
+ // we can't hide file that is not marked as deleted
+ if(!(DirNdx->FileCharacteristics & FILE_DELETED)) {
+ BrutePoint();
+
+#ifndef _CONSOLE
+ if(!(FileInfo->Fcb->FCBFlags & (UDF_FCB_DELETE_ON_CLOSE |
+ UDF_FCB_DELETED) ))
+#endif //_CONSOLE
+
+ return STATUS_CANNOT_DELETE;
+ }
+ return STATUS_SUCCESS;
+}
+#endif //UDF_READ_ONLY_BUILD
+
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+/*************************************************************************
+*
+* File: sys_spec_lib.h
+*
+* Module: UDF File System Driver (Kernel mode execution only)
+*
+* Description:
+* The main include file for the UDF file system driver.
+*
+* Author: Alter
+*
+*************************************************************************/
+
+#ifndef _UDF_SYS_SPEC_LIB__H_
+#define _UDF_SYS_SPEC_LIB__H_
+
+typedef struct _UDF_PH_CALL_CONTEXT {
+ KEVENT event;
+ IO_STATUS_BLOCK IosbToUse;
+} UDF_PH_CALL_CONTEXT, *PUDF_PH_CALL_CONTEXT;
+
+#ifdef _BROWSE_UDF_
+
+// convert UDF timestamp to NT time
+LONGLONG UDFTimeToNT(IN PUDF_TIME_STAMP UdfTime);
+// translate UDF file attributes to NT ones
+ULONG UDFAttributesToNT(IN PDIR_INDEX_ITEM FileDirNdx,
+ IN tag* FileEntry);
+// translate NT file attributes to UDF ones
+VOID UDFAttributesToUDF(IN PDIR_INDEX_ITEM FileDirNdx,
+ IN tag* FileEntry,
+ IN ULONG NTAttr);
+// translate all file information to NT
+NTSTATUS UDFFileDirInfoToNT(IN PVCB Vcb,
+ IN PDIR_INDEX_ITEM FileDirNdx,
+ OUT PFILE_BOTH_DIR_INFORMATION NTFileInfo);
+// convert NT time to UDF timestamp
+VOID UDFTimeToUDF(IN LONGLONG NtTime,
+ OUT PUDF_TIME_STAMP UdfTime);
+// change xxxTime field(s) in (Ext)FileEntry
+VOID UDFSetFileXTime(IN PUDF_FILE_INFO FileInfo,
+ IN LONGLONG* CrtTime,
+ IN LONGLONG* AccTime,
+ IN LONGLONG* AttrTime,
+ IN LONGLONG* ChgTime);
+// get xxxTime field(s) in (Ext)FileEntry
+VOID UDFGetFileXTime(IN PUDF_FILE_INFO FileInfo,
+ OUT LONGLONG* CrtTime,
+ OUT LONGLONG* AccTime,
+ OUT LONGLONG* AttrTime,
+ OUT LONGLONG* ChgTime);
+//
+#define UDFUpdateAccessTime(Vcb, FileInfo) \
+if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_ACCESS_TIME) { \
+ LONGLONG NtTime; \
+ KeQuerySystemTime((PLARGE_INTEGER)&NtTime); \
+ UDFSetFileXTime(FileInfo, NULL, &NtTime, NULL, NULL); \
+}
+//
+#define UDFUpdateModifyTime(Vcb, FileInfo) \
+if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_MODIFY_TIME) { \
+ LONGLONG NtTime; \
+ ULONG Attr; \
+ PDIR_INDEX_ITEM DirNdx; \
+ KeQuerySystemTime((PLARGE_INTEGER)&NtTime); \
+ UDFSetFileXTime(FileInfo, NULL, &NtTime, NULL, &NtTime); \
+ DirNdx = UDFDirIndex(UDFGetDirIndexByFileInfo(FileInfo), (FileInfo)->Index); \
+ Attr = UDFAttributesToNT(DirNdx, (FileInfo)->Dloc->FileEntry); \
+ if(!(Attr & FILE_ATTRIBUTE_ARCHIVE)) \
+ UDFAttributesToUDF(DirNdx, (FileInfo)->Dloc->FileEntry, Attr); \
+}
+//
+#define UDFUpdateAttrTime(Vcb, FileInfo) \
+if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_ATTR_TIME) { \
+ LONGLONG NtTime; \
+ KeQuerySystemTime((PLARGE_INTEGER)&NtTime); \
+ UDFSetFileXTime(FileInfo, NULL, &NtTime, &NtTime, NULL); \
+}
+//
+#define UDFUpdateCreateTime(Vcb, FileInfo) \
+{ \
+ LONGLONG NtTime; \
+ KeQuerySystemTime((PLARGE_INTEGER)&NtTime); \
+ UDFSetFileXTime(FileInfo, &NtTime, &NtTime, &NtTime, &NtTime); \
+}
+
+void
+__fastcall
+UDFDOSNameOsNative(
+ IN OUT PUNICODE_STRING DosName,
+ IN PUNICODE_STRING UdfName,
+ IN BOOLEAN KeepIntact
+ );
+
+VOID UDFNormalizeFileName(IN PUNICODE_STRING FName,
+ IN USHORT valueCRC);
+
+NTSTATUS MyAppendUnicodeStringToString_(IN PUNICODE_STRING Str1,
+ IN PUNICODE_STRING Str2
+#ifdef UDF_TRACK_UNICODE_STR
+ ,IN PCHAR Tag
+#endif
+ );
+
+NTSTATUS MyAppendUnicodeToString_(IN PUNICODE_STRING Str1,
+ IN PWSTR Str2
+#ifdef UDF_TRACK_UNICODE_STR
+ ,IN PCHAR Tag
+#endif
+ );
+
+#ifdef UDF_TRACK_UNICODE_STR
+ #define MyAppendUnicodeStringToString(s1,s2) MyAppendUnicodeStringToString_(s1,s2,"AppUStr")
+ #define MyAppendUnicodeStringToStringTag(s1,s2,tag) MyAppendUnicodeStringToString_(s1,s2,tag)
+ #define MyAppendUnicodeToString(s1,s2) MyAppendUnicodeToString_(s1,s2,"AppStr")
+ #define MyAppendUnicodeToStringTag(s1,s2,tag) MyAppendUnicodeToString_(s1,s2,tag)
+#else
+ #define MyAppendUnicodeStringToString(s1,s2) MyAppendUnicodeStringToString_(s1,s2)
+ #define MyAppendUnicodeStringToStringTag(s1,s2,tag) MyAppendUnicodeStringToString_(s1,s2)
+ #define MyAppendUnicodeToString(s1,s2) MyAppendUnicodeToString_(s1,s2)
+ #define MyAppendUnicodeToStringTag(s1,s2,tag) MyAppendUnicodeToString_(s1,s2)
+#endif
+
+NTSTATUS MyInitUnicodeString(IN PUNICODE_STRING Str1,
+ IN PCWSTR Str2);
+
+NTSTATUS MyCloneUnicodeString(IN PUNICODE_STRING Str1,
+ IN PUNICODE_STRING Str2);
+
+/*ULONG MyCompareUnicodeString(PUNICODE_STRING s1,
+ PUNICODE_STRING s2,
+ BOOLEAN UpCase);*/
+
+/*
+#define UDFAllocFileInfo() \
+ ExAllocateFromZone(&(UDFGlobalData.FileInfoZoneHeader))
+*/
+
+#define UDFIsDataCached(Vcb,Lba,BCount) \
+ ( WCacheIsInitialized__(&((Vcb)->FastCache)) && \
+ (KeGetCurrentIrql() < DISPATCH_LEVEL) && \
+ WCacheIsCached__(&((Vcb)->FastCache),Lba, BCount) )
+
+BOOLEAN UDFIsDirInfoCached(IN PVCB Vcb,
+ IN PUDF_FILE_INFO DirInfo);
+
+#define UDFGetNTFileId(Vcb, fi, fn) (((fi)->Dloc->FELoc.Mapping[0].extLocation - UDFPartStart(Vcb, -2)) + \
+ ((ULONG)(UDFUnicodeCksum((fn)->Buffer, (fn)->Length/sizeof(WCHAR))) << 16) + \
+ ((LONGLONG)Vcb<<32) )
+
+#define UnicodeIsPrint(a) RtlIsValidOemCharacter(&(a))
+
+#define UDFSysGetAllocSize(Vcb, Size) ((Size + Vcb->LBlockSize - 1) & ~((LONGLONG)(Vcb->LBlockSize - 1)))
+
+NTSTATUS UDFDoesOSAllowFileToBeTargetForRename__(IN PUDF_FILE_INFO FileInfo);
+#define UDFDoesOSAllowFileToBeTargetForHLink__ UDFDoesOSAllowFileToBeTargetForRename__
+NTSTATUS UDFDoesOSAllowFileToBeUnlinked__(IN PUDF_FILE_INFO FileInfo);
+#define UDFDoesOSAllowFileToBeMoved__ UDFDoesOSAllowFileToBeUnlinked__
+NTSTATUS UDFDoesOSAllowFilePretendDeleted__(IN PUDF_FILE_INFO FileInfo);
+BOOLEAN UDFRemoveOSReferences__(IN PUDF_FILE_INFO FileInfo);
+
+#define UDFIsFSDevObj(DeviceObject) \
+ (DeviceObject->DeviceExtension && \
+ ( (((PVCB)(DeviceObject->DeviceExtension))->NodeIdentifier.NodeType == \
+ UDF_NODE_TYPE_UDFFS_DEVOBJ) || \
+ (((PVCB)(DeviceObject->DeviceExtension))->NodeIdentifier.NodeType == \
+ UDF_NODE_TYPE_UDFFS_DRVOBJ) \
+ ) \
+ )
+/*
+extern ULONG MajorVersion;
+extern ULONG MinorVersion;
+extern ULONG BuildNumber;
+
+#define WinVer_Is351 (MajorVersion==0x03 && MinorVersion==51)
+#define WinVer_IsNT (MajorVersion==0x04)
+#define WinVer_Is2k (MajorVersion==0x05 && MinorVersion==0x00)
+#define WinVer_IsXP (MajorVersion==0x05 && MinorVersion==0x01)
+#define WinVer_IsdNET (MajorVersion==0x05 && MinorVersion==0x02)
+*/
+#endif //_BROWSE_UDF_
+
+#endif // _UDF_SYS_SPEC_LIB__H_
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifndef __CHECK_EXECUTION_ENVIRONMENT__H__
+#define __CHECK_EXECUTION_ENVIRONMENT__H__
+
+/*
+// check mode
+#ifdef NT_KERNEL_MODE
+ #ifdef NT_NATIVE_MODE
+ #error Error cannot combine Kernel and Natime
+ #endif //
+#endif //NT_KERNEL_MODE
+#ifdef NT_KERNEL_MODE
+ #if defined(NT_NATIVE_MODE) || defined(WIN_32_MODE)
+ #error !!!! Execution mode definition conflict !!!!
+ #endif //
+#endif //NT_KERNEL_MODE
+#ifdef NT_NATIVE_MODE
+ #if defined(WIN_32_MODE)
+ #error !!!! Execution mode definition conflict !!!!
+ #endif //
+#endif //NT_NATIVE_MODE
+
+// include appropriate header(s)
+#ifdef NT_KERNEL_MODE
+
+ #ifdef NT_DEV_DRV_ENV
+ #include <ntddk.h>
+ #endif //NT_DEV_DRV_ENV
+
+ #ifdef NT_FS_DRV_ENV
+ #include <ntifs.h>
+ #endif //NT_DEV_DRV_ENV
+ #include "Include/ntddk_ex.h"
+
+ #ifdef WIN_32_ENV
+ #error Error: Win32 environment is not supported in Kernel Mode
+ #endif //WIN_32_ENV
+
+#endif //NT_KERNEL_MODE
+
+#ifdef NT_NATIVE_MODE
+
+ #include "Include/nt_native.h"
+ #ifdef NT_DEV_DRV_ENV
+ #include "LibCdrw/env_spec_cdrw_w32.h"
+ #endif //NT_DEV_DRV_ENV
+
+ #ifdef NT_FS_DRV_ENV
+ #error Error: FS Driver environment is not supported in Native Mode
+ #endif //NT_DEV_DRV_ENV
+
+ #ifdef WIN_32_ENV
+ #endif //WIN_32_ENV
+
+#endif //NT_NATIVE_MODE
+
+#ifdef WIN_32_MODE
+
+ #include "windows.h"
+ #ifdef NT_DEV_DRV_ENV
+ #include "LibCdrw/env_spec_cdrw_w32.h"
+ #endif //NT_DEV_DRV_ENV
+
+ #ifdef NT_FS_DRV_ENV
+ #error Error: FS Driver environment is not supported in Win32 Mode
+ #endif //NT_DEV_DRV_ENV
+
+ #ifdef WIN_32_ENV
+ #endif //WIN_32_ENV
+
+#endif //WIN_32_MODE
+*/
+
+
+#ifdef NT_INCLUDED
+#define NT_KERNEL_MODE
+#endif //NT_INCLUDED
+
+#ifdef NT_NATIVE_MODE
+//#define USER_MODE
+#endif //NT_NATIVE_MODE
+
+// default to Win32 environment
+#if (!defined(NT_KERNEL_MODE) && !defined(NT_NATIVE_MODE)) || defined(WIN_32_MODE)
+//#warning !!!! Execution mode defaulted to WIN_32 !!!!
+//#define USER_MODE
+#define WIN_32_MODE
+#endif
+
+// check mode
+#ifdef NT_KERNEL_MODE
+ #if defined(NT_NATIVE_MODE) || defined(WIN_32_MODE)
+ #error !!!! Execution mode definition conflict !!!!
+ #endif //
+#endif //NT_KERNEL_MODE
+#ifdef NT_NATIVE_MODE
+ #if defined(WIN_32_MODE)
+ #error !!!! Execution mode definition conflict !!!!
+ #endif //
+#endif //NT_NATIVE_MODE
+
+
+#endif //__CHECK_EXECUTION_ENVIRONMENT__H__
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+//+-------------------------------------------------------------------------
+//
+// File: common.rc
+//
+//--------------------------------------------------------------------------
+
+#include "version.h"
+
+#undef VER_COMPANYNAME_STR
+#define VER_COMPANYNAME_STR VER_STR_VENDOR_NAME
+#define VER_FILEDESCRIPTION_STR_HDR ""
+#define VER_LEGALCOPYRIGHT_YEARS "1999-2008"
+#define VER_LEGALCOPYRIGHT_STR "Copyright \251 " VER_STR_VENDOR_NAME " " VER_LEGALCOPYRIGHT_YEARS
+#undef VER_PRODUCTNAME_STR
+#define VER_PRODUCTNAME_STR VER_STR_PRODUCT_NAME
+#undef VER_LEGALTRADEMARKS_STR
+
+#define VER_LANGNEUTRAL
+
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+//+-------------------------------------------------------------------------
+//
+// File: common.rc
+//
+//--------------------------------------------------------------------------
+
+#include "version.h"
+
+#undef VER_COMPANYNAME_STR
+#define VER_COMPANYNAME_STR VER_STR_VENDOR_NAME
+#define VER_FILEDESCRIPTION_STR_HDR ""
+#define VER_LEGALCOPYRIGHT_YEARS "1999-2008"
+#define VER_LEGALCOPYRIGHT_STR "Copyright \251 " VER_STR_VENDOR_NAME " " VER_LEGALCOPYRIGHT_YEARS
+#undef VER_PRODUCTNAME_STR
+#define VER_PRODUCTNAME_STR VER_STR_PRODUCT_NAME
+#undef VER_LEGALTRADEMARKS_STR
+
+#define VER_LANGNEUTRAL
+
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifdef NT_NATIVE_MODE
+
+#include "regtools.h"
+#include <stdarg.h>
+
+/*typedef BOOLEAN (*PPsGetVersion) (
+ PULONG MajorVersion OPTIONAL,
+ PULONG MinorVersion OPTIONAL,
+ PULONG BuildNumber OPTIONAL,
+ PUNICODE_STRING CSDVersion OPTIONAL
+ );
+
+//PPsGetVersion _PsGetVersion = PsGetVersion;
+
+/*NTSTATUS
+KernelGetProcAddress(
+ PWCHAR DllName,
+ PUCHAR ProcName,
+ PVOID* ProcAddr
+ )
+{
+ NTSTATUS RC;
+ HANDLE h;
+ UNICODE_STRING uname;
+ ANSI_STRING aname;
+
+ RtlInitUnicodeString(&uname, DllName);
+ *ProcAddr = NULL;
+
+ // RC = LdrGetDllHandle(NULL, NULL, &uname, &h);
+ if(!NT_SUCCESS(RC))
+ return RC;
+
+ RtlInitAnsiString(&aname, ProcName);
+
+// RC = LdrGetProcedureAddress(h, &aname, 0, ProcAddr);
+ return RC;
+} */
+
+
+BOOLEAN
+GetOsVersion(
+ PULONG MajorVersion OPTIONAL,
+ PULONG MinorVersion OPTIONAL,
+ PULONG BuildNumber OPTIONAL,
+ PUNICODE_STRING CSDVersion OPTIONAL
+ )
+{
+ WCHAR Str[32];
+ ULONG mn=0, mj=0, bld=0;
+
+// if(_PsGetVersion)
+// return _PsGetVersion(MajorVersion, MinorVersion, BuildNumber, CSDVersion);
+
+ RtlZeroMemory(Str, sizeof(Str));
+ if(RegTGetStringValue(NULL, L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
+ L"CurrentVersion",
+ &Str[0], sizeof(Str)-sizeof(WCHAR))) {
+ ULONG i=0;
+ WCHAR a;
+ while(a = Str[i]) {
+ if(a == '.')
+ break;
+ if(a < '0' || a > '9')
+ break;
+ mj = mj*16 + (a-'0');
+ i++;
+ }
+ i++;
+ while(a = Str[i]) {
+ if(a == '.')
+ break;
+ if(a < '0' || a > '9')
+ break;
+ mn = mn*16 + (a-'0');
+ i++;
+ }
+ }
+
+ if(RegTGetStringValue(NULL, L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
+ L"CurrentBuildNumber",
+ &Str[0], sizeof(Str)-sizeof(WCHAR))) {
+ ULONG i=0;
+ WCHAR a;
+ while(a = Str[i]) {
+ if(a < '0' || a > '9')
+ break;
+ bld = bld*10 + (a-'0');
+ i++;
+ }
+ }
+ if(MajorVersion)
+ *MajorVersion = mj;
+ if(MinorVersion)
+ *MinorVersion = mn;
+ if(BuildNumber)
+ *BuildNumber = bld;
+ return TRUE;
+}
+
+BOOLEAN
+MyDeviceIoControl(
+ HANDLE h,
+ DWORD dwIoControlCode,
+ PVOID lpInBuffer,
+ DWORD nInBufferSize,
+ PVOID lpOutBuffer,
+ DWORD nOutBufferSize,
+ DWORD* lpBytesReturned,
+ PVOID lpOverlapped
+ )
+{
+
+ NTSTATUS RC;
+ BOOLEAN DevIoCtl = TRUE;
+ IO_STATUS_BLOCK Iosb;
+
+ if ( dwIoControlCode >> 16 == FILE_DEVICE_FILE_SYSTEM ) {
+ DevIoCtl = FALSE;
+ } else {
+ DevIoCtl = TRUE;
+ }
+
+ if ( DevIoCtl ) {
+ RC = NtDeviceIoControlFile(
+ h,
+ NULL,
+ NULL, // APC routine
+ NULL, // APC Context
+ &Iosb,
+ dwIoControlCode, // IoControlCode
+ lpInBuffer, // Buffer for data to the FS
+ nInBufferSize,
+ lpOutBuffer, // OutputBuffer for data from the FS
+ nOutBufferSize // OutputBuffer Length
+ );
+ } else {
+ RC = NtFsControlFile(
+ h,
+ NULL,
+ NULL, // APC routine
+ NULL, // APC Context
+ &Iosb,
+ dwIoControlCode, // IoControlCode
+ lpInBuffer, // Buffer for data to the FS
+ nInBufferSize,
+ lpOutBuffer, // OutputBuffer for data from the FS
+ nOutBufferSize // OutputBuffer Length
+ );
+ }
+
+ if ( RC == STATUS_PENDING) {
+ // Operation must complete before return & Iosb destroyed
+ RC = NtWaitForSingleObject( h, FALSE, NULL );
+ if ( NT_SUCCESS(RC)) {
+ RC = Iosb.Status;
+ }
+ }
+
+ if ( NT_SUCCESS(RC) ) {
+ *lpBytesReturned = Iosb.Information;
+ return TRUE;
+ } else {
+ // handle warning value STATUS_BUFFER_OVERFLOW somewhat correctly
+ if ( !NT_ERROR(RC) ) {
+ *lpBytesReturned = Iosb.Information;
+ }
+ return FALSE;
+ }
+}
+
+VOID
+Sleep(
+ ULONG t
+ )
+{
+ LARGE_INTEGER delay = {0,0};
+ delay.QuadPart = -10I64*1000*t;
+ NtDelayExecution(FALSE, &delay);
+}
+
+HANDLE hGlobalHeap = NULL;
+
+extern "C"
+PVOID
+MyGlobalAlloc(
+ ULONG Size
+ )
+{
+ if(!hGlobalHeap) {
+ // Initialize some heap
+ hGlobalHeap = RtlCreateHeap( HEAP_GROWABLE, // Flags
+ NULL, // HeapBase
+ 0, // ReserveSize
+ 0, // CommitSize
+ NULL, // Lock
+ NULL ); // Parameters
+ if(!hGlobalHeap || hGlobalHeap == (HANDLE)(-1)) {
+ hGlobalHeap = NULL;
+ return NULL;
+ }
+ }
+ return RtlAllocateHeap( hGlobalHeap, 0, Size );
+}
+
+extern "C"
+VOID
+MyGlobalFree(
+ PVOID Addr
+ )
+{
+ if(!hGlobalHeap) {
+// BrutePoint();
+ return;
+ }
+ RtlFreeHeap( hGlobalHeap, 0, Addr );
+ return;
+}
+
+CHAR dbg_print_tmp_buff[2048];
+WCHAR dbg_stringBuffer[2048];
+
+BOOLEAN was_enter = TRUE;
+
+extern "C"
+VOID
+PrintNtConsole(
+ PCHAR DebugMessage,
+ ...
+ )
+{
+ int len;
+ UNICODE_STRING msgBuff;
+ va_list ap;
+ va_start(ap, DebugMessage);
+
+ if(was_enter) {
+ strcpy(&dbg_print_tmp_buff[0], NT_DBG_PREFIX);
+ len = _vsnprintf(&dbg_print_tmp_buff[sizeof(NT_DBG_PREFIX)-1], 2047-sizeof(NT_DBG_PREFIX), DebugMessage, ap);
+ } else {
+ len = _vsnprintf(&dbg_print_tmp_buff[0], 2047, DebugMessage, ap);
+ }
+ dbg_print_tmp_buff[2047] = 0;
+ if(len > 0 &&
+ (dbg_print_tmp_buff[len-1] == '\n' ||
+ dbg_print_tmp_buff[len-1] == '\r') ) {
+ was_enter = TRUE;
+ } else {
+ was_enter = FALSE;
+ }
+
+ len = swprintf( dbg_stringBuffer, L"%S", dbg_print_tmp_buff );
+ msgBuff.Buffer = dbg_stringBuffer;
+ msgBuff.Length = len * sizeof(WCHAR);
+ msgBuff.MaximumLength = msgBuff.Length + sizeof(WCHAR);
+ NtDisplayString( &msgBuff );
+
+ va_end(ap);
+
+} // end PrintNtConsole()
+
+extern "C"
+NTSTATUS
+EnvFileOpenW(
+ PWCHAR Name,
+ HANDLE* ph
+ )
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatus;
+ NTSTATUS Status;
+ UNICODE_STRING fName;
+
+ RtlInitUnicodeString(&fName, Name);
+
+ InitializeObjectAttributes(&ObjectAttributes, &fName, OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+ Status = NtCreateFile(ph,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatus,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_OPEN,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED /*| FILE_WRITE_THROUGH*/,
+ NULL,
+ 0);
+
+ return Status;
+} // end EnvFileOpenW()
+
+extern "C"
+NTSTATUS
+EnvFileOpenA(
+ PCHAR Name,
+ HANDLE* ph
+ )
+{
+ ULONG len;
+ PWCHAR NameW;
+ NTSTATUS Status;
+
+ len = strlen(Name);
+
+ NameW = (PWCHAR)MyAllocatePool__(NonPagedPool, (len+1)*sizeof(WCHAR));
+ if(!NameW)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ swprintf(NameW, L"%S", Name);
+
+ Status = EnvFileOpenW(NameW, ph);
+
+ MyFreePool__(NameW);
+
+ return Status;
+} // end EnvFileOpenA()
+
+extern "C"
+NTSTATUS
+EnvFileClose(
+ HANDLE hFile
+ )
+{
+ return NtClose(hFile);
+} // end EnvFileClose()
+
+extern "C"
+NTSTATUS
+EnvFileGetSizeByHandle(
+ HANDLE hFile,
+ PLONGLONG lpFileSize
+ )
+{
+ NTSTATUS Status;
+ IO_STATUS_BLOCK IoStatusBlock;
+ FILE_STANDARD_INFORMATION StandardInfo;
+
+ Status = NtQueryInformationFile(
+ hFile,
+ &IoStatusBlock,
+ &StandardInfo,
+ sizeof(StandardInfo),
+ FileStandardInformation
+ );
+ if (NT_SUCCESS(Status)) {
+ *lpFileSize = StandardInfo.EndOfFile.QuadPart;
+ }
+ return Status;
+} // end EnvFileGetSizeByHandle()
+
+extern "C"
+NTSTATUS
+EnvFileGetSizeA(
+ PCHAR Name,
+ PLONGLONG lpFileSize
+ )
+{
+ NTSTATUS Status;
+ HANDLE hFile;
+
+ (*lpFileSize) = -1I64;
+
+ Status = EnvFileOpenA(Name, &hFile);
+
+ if(!NT_SUCCESS(Status))
+ return Status;
+
+ Status = EnvFileGetSizeByHandle(hFile, lpFileSize);
+
+ NtClose(hFile);
+
+ return Status;
+} // end EnvFileGetSizeA()
+
+extern "C"
+NTSTATUS
+EnvFileGetSizeW(
+ PWCHAR Name,
+ PLONGLONG lpFileSize
+ )
+{
+ NTSTATUS Status;
+ HANDLE hFile;
+
+ (*lpFileSize) = -1I64;
+
+ Status = EnvFileOpenW(Name, &hFile);
+
+ if(!NT_SUCCESS(Status))
+ return Status;
+
+ Status = EnvFileGetSizeByHandle(hFile, lpFileSize);
+
+ NtClose(hFile);
+
+ return Status;
+} // end EnvFileGetSizeW()
+
+extern "C"
+BOOLEAN
+EnvFileExistsA(PCHAR Name) {
+ LONGLONG Size;
+ EnvFileGetSizeA(Name, &Size);
+ return Size != -1;
+}
+
+extern "C"
+BOOLEAN
+EnvFileExistsW(PWCHAR Name) {
+ LONGLONG Size;
+ EnvFileGetSizeW(Name, &Size);
+ return Size != -1;
+}
+
+extern "C"
+NTSTATUS
+EnvFileWrite(
+ HANDLE h,
+ PVOID ioBuffer,
+ ULONG Length,
+ PULONG bytesWritten
+ )
+{
+ IO_STATUS_BLOCK IoStatus;
+ NTSTATUS Status;
+
+ Status = NtWriteFile(
+ h,
+ NULL, // Event
+ NULL, // ApcRoutine
+ NULL, // ApcContext
+ &IoStatus,
+ ioBuffer,
+ Length,
+ NULL, // ByteOffset
+ NULL // Key
+ );
+ (*bytesWritten) = IoStatus.Information;
+
+ return Status;
+} // end EnvFileWrite()
+
+extern "C"
+NTSTATUS
+EnvFileRead(
+ HANDLE h,
+ PVOID ioBuffer,
+ ULONG Length,
+ PULONG bytesRead
+ )
+{
+ IO_STATUS_BLOCK IoStatus;
+ NTSTATUS Status;
+
+ Status = NtReadFile(
+ h,
+ NULL, // Event
+ NULL, // ApcRoutine
+ NULL, // ApcContext
+ &IoStatus,
+ ioBuffer,
+ Length,
+ NULL, // ByteOffset
+ NULL // Key
+ );
+ (*bytesRead) = IoStatus.Information;
+
+ return Status;
+} // end EnvFileRead()
+
+extern "C"
+NTSTATUS
+EnvFileSetPointer(
+ HANDLE hFile,
+ LONGLONG lDistanceToMove,
+ LONGLONG* lResultPointer,
+ DWORD dwMoveMethod
+ )
+{
+ NTSTATUS Status;
+ IO_STATUS_BLOCK IoStatus;
+ FILE_POSITION_INFORMATION CurrentPosition;
+ FILE_STANDARD_INFORMATION FileInfo;
+
+ switch (dwMoveMethod) {
+ case ENV_FILE_BEGIN :
+ CurrentPosition.CurrentByteOffset.QuadPart = lDistanceToMove;
+ break;
+
+ case ENV_FILE_CURRENT :
+
+ // Get the current position of the file pointer
+ Status = NtQueryInformationFile(
+ hFile,
+ &IoStatus,
+ &CurrentPosition,
+ sizeof(CurrentPosition),
+ FilePositionInformation
+ );
+ if(!NT_SUCCESS(Status)) {
+ return Status;
+ }
+ CurrentPosition.CurrentByteOffset.QuadPart += lDistanceToMove;
+ break;
+
+ case ENV_FILE_END :
+ Status = NtQueryInformationFile(
+ hFile,
+ &IoStatus,
+ &FileInfo,
+ sizeof(FileInfo),
+ FileStandardInformation
+ );
+ if (!NT_SUCCESS(Status)) {
+ return Status;
+ }
+ CurrentPosition.CurrentByteOffset.QuadPart =
+ FileInfo.EndOfFile.QuadPart + lDistanceToMove;
+ break;
+
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if ( CurrentPosition.CurrentByteOffset.QuadPart < 0 ) {
+ return Status;
+ }
+
+ Status = NtSetInformationFile(
+ hFile,
+ &IoStatus,
+ &CurrentPosition,
+ sizeof(CurrentPosition),
+ FilePositionInformation
+ );
+
+ if(!NT_SUCCESS(Status)) {
+ return Status;
+ }
+ if(lResultPointer) {
+ *lResultPointer = CurrentPosition.CurrentByteOffset.QuadPart;
+ }
+ return STATUS_SUCCESS;
+} // end EnvFileSetPointer()
+
+NTSTATUS EnvFileDeleteW(PWCHAR Name) {
+
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatus;
+ NTSTATUS Status;
+ UNICODE_STRING fName;
+ HANDLE Handle;
+ FILE_DISPOSITION_INFORMATION Disposition;
+
+ RtlInitUnicodeString(&fName, Name);
+
+ InitializeObjectAttributes(&ObjectAttributes, &fName, OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+ Status = NtOpenFile(
+ &Handle,
+ (ACCESS_MASK)DELETE,
+ &ObjectAttributes,
+ &IoStatus,
+ FILE_SHARE_DELETE |
+ FILE_SHARE_READ |
+ FILE_SHARE_WRITE,
+ FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT
+ );
+
+
+ if ( !NT_SUCCESS(Status) ) {
+ return Status;
+ }
+
+ Disposition.DeleteFile = TRUE;
+
+ Status = NtSetInformationFile(
+ Handle,
+ &IoStatus,
+ &Disposition,
+ sizeof(Disposition),
+ FileDispositionInformation
+ );
+
+ NtClose(Handle);
+
+ return Status;
+}
+#endif //NT_NATIVE_MODE
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifndef __ENV_SPEC_NT_NATIVE__H__
+#define __ENV_SPEC_NT_NATIVE__H__
+
+#ifdef NT_NATIVE_MODE
+
+#include "zw_2_nt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif //__cplusplus
+
+#ifndef MAX_PATH
+#define MAX_PATH 260
+#endif //MAX_PATH
+
+BOOLEAN
+GetOsVersion(
+ PULONG MajorVersion OPTIONAL,
+ PULONG MinorVersion OPTIONAL,
+ PULONG BuildNumber OPTIONAL,
+ PUNICODE_STRING CSDVersion OPTIONAL
+ );
+
+#define PsGetVersion(a,b,c,d) GetOsVersion(a,b,c,d)
+
+#define InterlockedIncrement(addr) \
+ ((*addr)++)
+#define InterlockedDecrement(addr) \
+ ((*addr)--)
+int
+__inline
+InterlockedExchangeAdd(PLONG addr, LONG i) {
+ LONG Old = (*addr);
+ (*addr) += i;
+ return Old;
+}
+
+#define DeviceIoControl(h, ctlc, ib, is, ob, os, r, ov) MyDeviceIoControl(h, ctlc, ib, is, ob, os, r, ov)
+
+BOOLEAN
+MyDeviceIoControl(
+ HANDLE hDevice,
+ DWORD dwIoControlCode,
+ PVOID lpInBuffer,
+ DWORD nInBufferSize,
+ PVOID lpOutBuffer,
+ DWORD nOutBufferSize,
+ DWORD* lpBytesReturned,
+ PVOID lpOverlapped
+ );
+
+#define OemToCharW(ansi_s, uni_s) (swprintf(uni_s, L"%S", ansi_s))
+#define MultiByteToWideChar(cp, f, ansi_s, a_sz, uni_s, u_sz) (swprintf(uni_s, L"%S", ansi_s))
+
+VOID
+Sleep(
+ ULONG t
+ );
+
+#define GlobalAlloc(foo, size) MyGlobalAlloc( size );
+#define GlobalFree(ptr) MyGlobalFree( ptr );
+
+extern "C"
+PVOID MyGlobalAlloc(ULONG Size);
+
+extern "C"
+VOID MyGlobalFree(PVOID Addr);
+
+#define ExitProcess(Status) NtTerminateProcess( NtCurrentProcess(), Status );
+
+extern "C"
+VOID
+PrintNtConsole(
+ PCHAR DebugMessage,
+ ...
+ );
+
+extern "C"
+NTSTATUS
+EnvFileOpenW(
+ PWCHAR Name,
+ HANDLE* ph
+ );
+
+extern "C"
+NTSTATUS
+EnvFileOpenA(
+ PCHAR Name,
+ HANDLE* ph
+ );
+
+extern "C"
+NTSTATUS
+EnvFileClose(
+ HANDLE hFile
+ );
+
+extern "C"
+NTSTATUS
+EnvFileGetSizeByHandle(
+ HANDLE hFile,
+ PLONGLONG lpFileSize
+ );
+
+extern "C"
+NTSTATUS
+EnvFileGetSizeA(
+ PCHAR Name,
+ PLONGLONG lpFileSize
+ );
+
+extern "C"
+NTSTATUS
+EnvFileGetSizeW(
+ PWCHAR Name,
+ PLONGLONG lpFileSize
+ );
+
+extern "C"
+BOOLEAN
+EnvFileExistsA(PCHAR Name);
+
+extern "C"
+BOOLEAN
+EnvFileExistsW(PWCHAR Name);
+
+extern "C"
+NTSTATUS
+EnvFileWrite(
+ HANDLE h,
+ PVOID ioBuffer,
+ ULONG Length,
+ PULONG bytesWritten
+ );
+
+extern "C"
+NTSTATUS
+EnvFileRead(
+ HANDLE h,
+ PVOID ioBuffer,
+ ULONG Length,
+ PULONG bytesRead
+ );
+
+#define ENV_FILE_CURRENT 1
+#define ENV_FILE_END 2
+#define ENV_FILE_BEGIN 3
+
+extern "C"
+NTSTATUS
+EnvFileSetPointer(
+ HANDLE hFile,
+ LONGLONG lDistanceToMove,
+ LONGLONG* lResultPointer,
+ DWORD dwMoveMethod
+ );
+
+extern "C"
+NTSTATUS
+EnvFileDeleteW(
+ PWCHAR fName
+ );
+
+#define PrintDbgConsole PrintNtConsole
+
+#ifdef __cplusplus
+};
+#endif //__cplusplus
+
+#endif //NT_NATIVE_MODE
+
+#endif //__ENV_SPEC_NT_NATIVE__H__
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifndef UDF_FORMAT_MEDIA
+ULONG LockMode = 0;
+BOOLEAN opt_invalidate_volume = FALSE;
+#endif //UDF_FORMAT_MEDIA
+
+#ifndef CDRW_W32
+#ifndef UDF_FORMAT_MEDIA
+BOOLEAN open_as_device = FALSE;
+#endif //UDF_FORMAT_MEDIA
+#ifdef USE_SKIN_MODEL
+
+PSKIN_API SkinAPI = NULL;
+
+PSKIN_API
+SkinLoad(
+ PWCHAR path,
+ HINSTANCE hInstance, // handle to current instance
+ HINSTANCE hPrevInstance, // handle to previous instance
+ int nCmdShow // show state
+ )
+{
+ HMODULE hm;
+ PSKIN_API Skin;
+ PSKIN_API (__stdcall *SkinInit) (VOID);
+
+ hm = LoadLibraryW(path);
+ if(!hm)
+ return NULL;
+ SkinInit = (PSKIN_API(__stdcall *)(void))GetProcAddress(hm, "SkinInit");
+ if(!SkinInit)
+ return NULL;
+ Skin = SkinInit();
+ if(!Skin)
+ return NULL;
+ Skin->Init(hInstance, hPrevInstance, nCmdShow);
+ return Skin;
+}
+
+
+#endif //USE_SKIN_MODEL
+
+#ifdef _BROWSE_UDF_
+#ifndef LIBUDF
+
+extern PVCB Vcb;
+
+#endif // LIBUDF
+#endif //_BROWSE_UDF_
+
+#ifdef LIBUDF
+#define _lphUdf ((PUDF_VOL_HANDLE_I)(DeviceObject->lpContext))
+#endif //LIBUDF
+#ifdef LIBUDFFMT
+#define _lphUdf (DeviceObject->cbio)
+#endif //LIBUDFFMT
+
+#ifndef CDRW_W32
+
+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
+ )
+{
+ ULONG real_read;
+#if !defined(LIBUDF) && !defined(LIBUDFFMT)
+ ULONG ret;
+
+ ULONG RC = DeviceIoControl(DeviceObject->h,IoControlCode,
+ InputBuffer,InputBufferLength,
+ OutputBuffer,OutputBufferLength,
+ &real_read,NULL);
+
+ if (!RC) {
+ ret = GetLastError();
+ }
+ return RC ? 1 : -1;
+
+#else // LIBUDF
+
+ ULONG RC = _lphUdf->lpIOCtlFunc(_lphUdf->lpParameter,IoControlCode,
+ InputBuffer,InputBufferLength,
+ OutputBuffer,OutputBufferLength,
+ &real_read);
+
+ return RC;
+
+#endif // LIBUDF
+
+} // end UDFPhSendIOCTL()
+
+
+NTSTATUS
+UDFPhReadSynchronous(
+ PDEVICE_OBJECT DeviceObject, // the physical device object
+ PVOID Buffer,
+ ULONG Length,
+ LONGLONG Offset,
+ PULONG ReadBytes,
+ ULONG Flags
+ )
+{
+
+#if !defined(LIBUDF) && !defined(LIBUDFFMT)
+
+ NTSTATUS RC;
+// KdPrint(("UDFPhRead: Length: %x Lba: %lx\n",Length>>0xb,Offset>>0xb));
+ LONG HiOffs = (ULONG)(Offset >> 32);
+
+ RC = SetFilePointer(DeviceObject->h,(ULONG)Offset,&HiOffs,FILE_BEGIN);
+ if(RC == INVALID_SET_FILE_POINTER) {
+ if(GetLastError() != NO_ERROR) {
+ KdPrint(("UDFPhReadSynchronous: error %x\n", GetLastError()));
+ return STATUS_END_OF_FILE;
+ }
+ }
+ RC = ReadFile(DeviceObject->h,Buffer,Length,ReadBytes,NULL);
+ if(NT_SUCCESS(RC) &&
+ (!(*ReadBytes))) {
+ RC = GetLastError();
+ return STATUS_END_OF_FILE;
+ }
+ return STATUS_SUCCESS;
+
+#else // LIBUDF
+
+ return _lphUdf->lpReadFunc(_lphUdf->lpParameter,
+ Buffer,
+ Length,
+ Offset,
+ ReadBytes);
+
+#endif //defined LIBUDF || defined LIBUDFFMT
+
+} // end UDFPhReadSynchronous()
+
+
+NTSTATUS
+UDFPhWriteSynchronous(
+ PDEVICE_OBJECT DeviceObject, // the physical device object
+ PVOID Buffer,
+ ULONG Length,
+ LONGLONG Offset,
+ PULONG WrittenBytes,
+ ULONG Flags
+ )
+{
+#if !defined(LIBUDF) && !defined(LIBUDFFMT)
+
+ NTSTATUS RC = STATUS_SUCCESS;
+ LONG HiOffs = (ULONG)(Offset >> 32);
+ PVOID Buffer2 = NULL;
+ PVOID Buffer3 = NULL;
+
+ RC = SetFilePointer(DeviceObject->h,(ULONG)Offset,&HiOffs,FILE_BEGIN);
+ if(RC == INVALID_SET_FILE_POINTER) {
+ if(GetLastError() != NO_ERROR) {
+ KdPrint(("UDFPhWriteSynchronous: error %x\n", GetLastError()));
+ return STATUS_END_OF_FILE;
+ }
+ }
+
+ Buffer2 = ExAllocatePool(NonPagedPool, Length+0x10000);
+ Buffer3 = (PVOID)( ((ULONG)Buffer2 + 0xffff) & ~0xffff);
+ RtlCopyMemory(Buffer3, Buffer, Length);
+
+ RC = WriteFile(DeviceObject->h,Buffer3,Length,WrittenBytes,NULL);
+ if(!RC ||
+ !(*WrittenBytes)) {
+ RC = GetLastError();
+ KdPrint(("UDFPhWriteSynchronous: EOF, error %x\n", RC));
+ RC = STATUS_END_OF_FILE;
+ } else {
+ RC = STATUS_SUCCESS;
+ }
+
+ if(Buffer2) ExFreePool(Buffer2);
+
+ return RC;
+
+#else // LIBUDF
+
+ return _lphUdf->lpWriteFunc(_lphUdf->lpParameter,
+ Buffer,
+ Length,
+ Offset,
+ WrittenBytes);
+
+#endif // LIBUDF
+
+} // end UDFPhWriteSynchronous()
+
+#if 0
+NTSTATUS
+UDFPhWriteVerifySynchronous(
+ PDEVICE_OBJECT DeviceObject, // the physical device object
+ PVOID Buffer,
+ ULONG Length,
+ LONGLONG Offset,
+ PULONG WrittenBytes,
+ ULONG Flags
+ )
+{
+ NTSTATUS RC;
+ PUCHAR v_buff = NULL;
+ ULONG ReadBytes;
+
+ RC = UDFPhWriteSynchronous(DeviceObject, Buffer, Length, Offset, WrittenBytes, 0);
+ if(!Verify)
+ return RC;
+ v_buff = (PUCHAR)DbgAllocatePool(NonPagedPool, Length);
+ if(!v_buff)
+ return RC;
+
+ RC = UDFPhSendIOCTL( IOCTL_CDRW_SYNC_CACHE, DeviceObject,
+ NULL,0, NULL,0, FALSE, NULL);
+
+ RC = UDFPhReadSynchronous(DeviceObject, v_buff, Length, Offset, &ReadBytes, 0);
+ if(!NT_SUCCESS(RC)) {
+ BrutePoint();
+ DbgFreePool(v_buff);
+ return RC;
+ }
+ if(RtlCompareMemory(v_buff, Buffer, ReadBytes) == Length) {
+ DbgFreePool(v_buff);
+ return RC;
+ }
+ BrutePoint();
+ DbgFreePool(v_buff);
+ return STATUS_LOST_WRITEBEHIND_DATA;
+} // end UDFPhWriteVerifySynchronous()
+#endif
+
+VOID
+set_image_size(
+ HANDLE h,
+// ULONG LBA)
+ int64 len)
+{
+ LONG offh = (ULONG)(len >> 32);
+ //( (LONGLONG)LBA >> (32-Vcb->BlockSizeBits) );
+
+ SetFilePointer((HANDLE)h, (ULONG)(len /*(LBA << Vcb->BlockSizeBits)*/ ), &offh, FILE_BEGIN);
+ SetEndOfFile(h);
+ offh = 0;
+ SetFilePointer((HANDLE)h, 0, &offh, FILE_BEGIN);
+} // end set_image_size()
+
+int64
+get_file_size(
+ HANDLE h
+ )
+{
+ LONG hsz = 0;
+ LONG lsz;
+
+ lsz = SetFilePointer(h, 0, &hsz, FILE_END);
+ return (((int64)hsz) << 32) | lsz;
+} // end get_file_size()
+
+int64
+set_file_pointer(
+ HANDLE h,
+ int64 sz
+ )
+{
+ ULONG hsz = (ULONG)(sz >> 32);
+ ULONG lsz = (ULONG)sz;
+
+ lsz = SetFilePointer(h, lsz, (PLONG)&hsz, FILE_BEGIN);
+ return (((int64)hsz) << 32) | lsz;
+} // end set_file_pointer()
+
+#endif //CDRW_W32
+
+#ifndef LIBUDF
+
+#ifndef UDF_FORMAT_MEDIA
+
+ULONG
+write(
+ PVCB Vcb,
+ HANDLE h,
+ PCHAR buff,
+ ULONG len)
+{
+ ULONG written;
+ LONG offh = 0;
+ ULONG offl = SetFilePointer((HANDLE)h, 0, &offh, FILE_CURRENT);
+// ULONG Lba = (ULONG)((((LONGLONG)offh << 32) + offl) >> Vcb->BlockSizeBits);
+
+ UDFWriteData(Vcb, FALSE, (((LONGLONG)offh)<<32)+offl, len, FALSE, buff, &written);
+
+ SetFilePointer((HANDLE)h, offl, &offh, FILE_BEGIN);
+ offh = 0;
+ SetFilePointer((HANDLE)h, written, &offh, FILE_CURRENT);
+
+ return written;
+} // end write()
+#endif //UDF_FORMAT_MEDIA
+
+#endif // LIBUDF
+
+#endif //CDRW_W32
+
+#ifdef NT_NATIVE_MODE
+
+BOOL
+Privilege(
+ LPTSTR pszPrivilege,
+ BOOL bEnable
+ )
+{
+#ifndef NT_NATIVE_MODE
+ HANDLE hToken;
+ TOKEN_PRIVILEGES tp;
+
+ // obtain the token, first check the thread and then the process
+ if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, TRUE, &hToken)) {
+ if (GetLastError() == ERROR_NO_TOKEN) {
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
+ return FALSE;
+ }
+ } else {
+ return FALSE;
+ }
+ }
+
+ // get the luid for the privilege
+ if (!LookupPrivilegeValue(NULL, pszPrivilege, &tp.Privileges[0].Luid)) {
+ CloseHandle(hToken);
+ return FALSE;
+ }
+
+ tp.PrivilegeCount = 1;
+
+ if (bEnable)
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ else
+ tp.Privileges[0].Attributes = 0;
+
+ // enable or disable the privilege
+ if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0)) {
+ CloseHandle(hToken);
+ return FALSE;
+ }
+
+ if (!CloseHandle(hToken))
+ return FALSE;
+
+#endif //NT_NATIVE_MODE
+
+ return TRUE;
+
+} // end Privilege()
+#endif //NT_NATIVE_MODE
+
+#ifndef LIBUDF
+
+extern "C"
+ULONG
+MyLockVolume(
+ HANDLE h,
+ ULONG* pLockMode // OUT
+ )
+{
+ ULONG RC;
+ ULONG returned;
+
+ (*pLockMode) = -1;
+#ifndef CDRW_W32
+ RC = DeviceIoControl(h,IOCTL_UDF_LOCK_VOLUME_BY_PID,NULL,0,NULL,0,&returned,NULL);
+ if(RC) {
+ (*pLockMode) = IOCTL_UDF_LOCK_VOLUME_BY_PID;
+ return STATUS_SUCCESS;
+ }
+#endif //CDRW_W32
+
+ RC = DeviceIoControl(h,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&returned,NULL);
+ if(RC) {
+ (*pLockMode) = FSCTL_LOCK_VOLUME;
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+} // MyLockVolume()
+
+extern "C"
+ULONG
+MyUnlockVolume(
+ HANDLE h,
+ ULONG* pLockMode // IN
+ )
+{
+ ULONG returned;
+
+#ifndef CDRW_W32
+ if((*pLockMode) == IOCTL_UDF_LOCK_VOLUME_BY_PID) {
+ return DeviceIoControl(h,IOCTL_UDF_UNLOCK_VOLUME_BY_PID,NULL,0,NULL,0,&returned,NULL);
+ }
+#endif //CDRW_W32
+
+ return DeviceIoControl(h,FSCTL_UNLOCK_VOLUME,NULL,0,NULL,0,&returned,NULL);
+
+} // MyUnlockVolume()
+
+void
+my_retrieve_vol_type(
+#ifndef CDRW_W32
+ PVCB Vcb,
+#endif
+ PWCHAR fn
+ )
+{
+#ifndef CDRW_W32
+ if(wcslen(fn) == 2 && fn[1] == ':') {
+ ULONG DevType = GetDriveTypeW(fn);
+ KdPrint((" DevType %x\n", DevType));
+ switch(DevType) {
+ case DRIVE_CDROM:
+ Vcb->PhDeviceType = FILE_DEVICE_CD_ROM;
+ break;
+ default:
+ Vcb->PhDeviceType = FILE_DEVICE_DISK;
+ break;
+ }
+ }
+ if(wcslen(fn) == 2 && fn[1] == ';') {
+ UserPrint(("Warrning: File name is similar to drive letter.\n"
+ " Don't you type semicolon ';' instead of colon ':' ?\n"));
+ }
+#endif //CDRW_W32
+} // end my_retrieve_vol_type()
+
+
+#ifdef NT_NATIVE_MODE
+#define GetLastError() ((ULONG)(-1))
+#endif //NT_NATIVE_MODE
+
+#define MAX_INVALIDATE_VOLUME_RETRY 8
+
+extern "C"
+HANDLE
+my_open(
+#ifndef CDRW_W32
+ PVCB Vcb,
+#endif
+ PWCHAR fn
+ )
+{
+ HANDLE h/*, h2*/;
+ WCHAR deviceNameBuffer[0x200];
+ WCHAR FSNameBuffer[0x200];
+// CCHAR RealDeviceName[0x200];
+// WCHAR DeviceName[MAX_PATH+1];
+ ULONG RC;
+ ULONG retry;
+ ULONG i;
+ BOOLEAN CantLock = FALSE;
+ PULONG pLockMode;
+#ifdef NT_NATIVE_MODE
+ IO_STATUS_BLOCK ioStatus;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING uniFilename;
+#endif //NT_NATIVE_MODE
+ ULONG returned;
+
+#ifndef CDRW_W32
+#ifdef UDF_FORMAT_MEDIA
+ PUDFFmtState fms = Vcb->fms;
+ fms->
+#endif
+ open_as_device = TRUE;
+#endif //CDRW_W32
+
+ pLockMode = &
+#ifdef UDF_FORMAT_MEDIA
+ fms->
+#endif
+ LockMode;
+
+ // make several retries to workaround smart applications,
+ // those attempts to work with volume immediately after arrival
+ retry = 1 +
+#ifdef UDF_FORMAT_MEDIA
+ fms->
+#endif
+ opt_invalidate_volume ? 0 : MAX_INVALIDATE_VOLUME_RETRY;
+
+#ifndef NT_NATIVE_MODE
+ swprintf(deviceNameBuffer, L"%ws\\", fn);
+ KdPrint(("my_open: %S\n", fn));
+ i = sizeof(FSNameBuffer)/sizeof(FSNameBuffer[0]);
+ if(GetVolumeInformationW(deviceNameBuffer, NULL, 0,
+ &returned, &returned, &returned, FSNameBuffer, i)) {
+ KdPrint(("my_open: FS: %S\n", FSNameBuffer));
+ if(!wcscmp(FSNameBuffer, L"Unknown")) {
+ retry++;
+ }
+ } else {
+ KdPrint(("my_open: FS: ???\n"));
+ }
+ KdPrint(("my_open: retry %d times\n", retry));
+
+#endif //NT_NATIVE_MODE
+
+ do {
+ // open as device
+#ifndef NT_NATIVE_MODE
+ swprintf(deviceNameBuffer, L"\\\\.\\%ws", fn);
+ if(wcslen(fn) == 2 && fn[1] == ';') {
+ UserPrint(("Warrning: File name is similar to drive letter.\n"
+ " Don't you type semicolon ';' instead of colon ':' ?\n"));
+ }
+ h = (HANDLE)(-1);
+ for(i=0; i<4; i++) {
+ if(h == ((HANDLE)-1)) {
+ h = CreateFileW(deviceNameBuffer, GENERIC_READ | GENERIC_WRITE,
+ ((i & 1) ? 0 : FILE_SHARE_READ) | ((i & 2) ? 0 : FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
+ if(h != ((HANDLE)-1)) {
+ KdPrint((" opened i=%x\n", i));
+ }
+ }
+ }
+#else //NT_NATIVE_MODE
+ uniFilename.Length = swprintf(deviceNameBuffer, L"\\??\\%ws", fn);
+ uniFilename.Buffer = deviceNameBuffer;
+ uniFilename.Length *= sizeof(WCHAR);
+ uniFilename.MaximumLength = uniFilename.Length + sizeof(WCHAR);
+
+ h = (HANDLE)(-1);
+ for(i=0; i<4; i++) {
+ InitializeObjectAttributes(&ObjectAttributes, &uniFilename, OBJ_CASE_INSENSITIVE, NULL, NULL);
+ if(h == ((HANDLE)-1)) {
+ RC = NtCreateFile(&h,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE | FILE_READ_ATTRIBUTES,
+ &ObjectAttributes,
+ &ioStatus,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ ((i & 1) ? 0 : FILE_SHARE_READ) | ((i & 2) ? 0 : FILE_SHARE_WRITE),
+ FILE_OPEN,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED | FILE_WRITE_THROUGH | FILE_NO_INTERMEDIATE_BUFFERING,
+ NULL,
+ 0);
+ if(!NT_SUCCESS(RC)) {
+ KdPrint((" opened i2=%x\n", i));
+ h = ((HANDLE)-1);
+ }
+ }
+ }
+#endif //NT_NATIVE_MODE
+ if(h != ((HANDLE)-1)) {
+#ifndef CDRW_W32
+#ifdef UDF_FORMAT_MEDIA
+ if(fms->opt_flush || fms->opt_probe) {
+ return h;
+ }
+#endif //UDF_FORMAT_MEDIA
+ my_retrieve_vol_type(Vcb, fn);
+#else
+ my_retrieve_vol_type(fn);
+#endif //CDRW_W32
+ if(!NT_SUCCESS(MyLockVolume(h,pLockMode))) {
+#ifndef CDRW_W32
+ if(retry < MAX_INVALIDATE_VOLUME_RETRY) {
+ retry++;
+ if(!Privilege(SE_TCB_NAME, TRUE)) {
+ KdPrint(("SE_TCB privilege not held\n"));
+ } else
+ if(DeviceIoControl(h,FSCTL_INVALIDATE_VOLUMES,&h,sizeof(h),NULL,0,&returned,NULL) ) {
+ KdPrint((" FSCTL_INVALIDATE_VOLUMES ok, status %x\n", GetLastError()));
+ CloseHandle(h);
+ continue;
+ } else {
+//#ifndef CDRW_W32
+ KdPrint((" FSCTL_INVALIDATE_VOLUMES failed, error %x\n", GetLastError()));
+ RC = GetLastError();
+ if(DeviceIoControl(h,IOCTL_UDF_INVALIDATE_VOLUMES,&h,sizeof(h),NULL,0,&returned,NULL) ) {
+ KdPrint((" IOCTL_UDF_INVALIDATE_VOLUMES ok, status %x\n", GetLastError()));
+ CloseHandle(h);
+ continue;
+ }
+ KdPrint((" IOCTL_UDF_INVALIDATE_VOLUMES, error %x\n", GetLastError()));
+//#endif //CDRW_W32
+ }
+ UserPrint(("can't lock volume, retry\n"));
+ CloseHandle(h);
+ continue;
+ }
+#endif //CDRW_W32
+ UserPrint(("can't lock volume\n"));
+#ifndef NT_NATIVE_MODE
+ // In native mode the volume can be not mounted yet !!!
+ CantLock = TRUE;
+ CloseHandle(h);
+ h = NULL;
+ goto try_as_file;
+#endif //NT_NATIVE_MODE
+ }
+//#ifndef CDRW_W32
+ if(!DeviceIoControl(h,FSCTL_ALLOW_EXTENDED_DASD_IO,NULL,0,NULL,0,&returned,NULL)) {
+ KdPrint(("Warning: can't allow extended DASD i/o\n"));
+ }
+//#endif //CDRW_W32
+
+ KdPrint((" opened, h=%x\n", h));
+ return h;
+ }
+ RC = GetLastError();
+
+#ifndef NT_NATIVE_MODE
+ h = CreateFileW(deviceNameBuffer, GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+#else //NT_NATIVE_MODE
+ RC = NtCreateFile(&h,
+ GENERIC_READ | SYNCHRONIZE | FILE_READ_ATTRIBUTES,
+ &ObjectAttributes,
+ &ioStatus,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ,
+ FILE_OPEN,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED | FILE_WRITE_THROUGH,
+ NULL,
+ 0);
+ if(!NT_SUCCESS(RC)) {
+ h = ((HANDLE)-1);
+ }
+#endif //NT_NATIVE_MODE
+ if(h != ((HANDLE)-1)) {
+
+ KdPrint((" opened R/O, h=%x\n", h));
+#ifndef CDRW_W32
+ my_retrieve_vol_type(Vcb, fn);
+#else
+ my_retrieve_vol_type(fn);
+#endif
+
+ UserPrint(("read-only open\n"));
+ if(!NT_SUCCESS(MyLockVolume(h,pLockMode))) {
+#ifndef CDRW_W32
+ if(retry < MAX_INVALIDATE_VOLUME_RETRY) {
+ retry++;
+ if(!Privilege(SE_TCB_NAME, TRUE)) {
+ KdPrint(("SE_TCB privilege not held\n"));
+ } else
+ if(DeviceIoControl(h,FSCTL_INVALIDATE_VOLUMES,&h,sizeof(h),NULL,0,&returned,NULL) ) {
+ CloseHandle(h);
+ continue;
+ }
+ UserPrint(("can't lock read-only volumem retry"));
+ CloseHandle(h);
+ continue;
+ }
+#endif //CDRW_W32
+ UserPrint(("can't lock read-only volume"));
+#ifndef NT_NATIVE_MODE
+ CantLock = TRUE;
+ CloseHandle(h);
+ h = NULL;
+ goto try_as_file;
+#endif //NT_NATIVE_MODE
+ }
+// write_cdfs = TRUE;
+// DeviceIoControl(h,FSCTL_DISMOUNT_VOLUME,NULL,0,NULL,0,&returned,NULL);
+ return h;
+ }
+#ifndef NT_NATIVE_MODE
+try_as_file:
+#endif //NT_NATIVE_MODE
+
+#ifndef CDRW_W32
+#ifdef UDF_FORMAT_MEDIA
+ fms->
+#endif
+ open_as_device = FALSE;
+ // open as plain file
+ Vcb->PhDeviceType = FILE_DEVICE_DISK;
+#endif //CDRW_W32
+
+ UserPrint(("try image file\n"));
+#ifndef NT_NATIVE_MODE
+ h = CreateFileW(fn, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+#else //NT_NATIVE_MODE
+ RC = NtCreateFile(&h,
+ GENERIC_READ | SYNCHRONIZE,
+ &ObjectAttributes,
+ &ioStatus,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ,
+ FILE_OPEN,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED | FILE_WRITE_THROUGH,
+ NULL,
+ 0);
+ if(!NT_SUCCESS(RC)) {
+ h = ((HANDLE)-1);
+ }
+#endif //NT_NATIVE_MODE
+ if(h == ((HANDLE)-1)) {
+
+ RC = GetLastError();
+ if(CantLock) {
+#ifndef CDRW_W32
+ my_exit(
+#ifdef UDF_FORMAT_MEDIA
+ fms,
+#endif
+ MKUDF_CANT_LOCK_VOL);
+#else
+ return NULL;
+#endif //CDRW_W32
+ }
+#ifndef CDRW_W32
+ UserPrint(("error opening device or image file"));
+ my_exit(
+#ifdef UDF_FORMAT_MEDIA
+ fms,
+#endif
+ MKUDF_CANT_OPEN_FILE);
+#else
+ return NULL;
+#endif //CDRW_W32
+ }
+ KdPrint((" opened as file, h=%x\n", h));
+ break;
+
+ } while(TRUE);
+ return h;
+} // end my_open()
+
+#endif //LIBUDF
+
+#ifndef CDRW_W32
+
+uint64
+udf_lseek64(
+ HANDLE fd,
+ uint64 offset,
+ int whence)
+{
+ LONG offh = (ULONG)(offset>>32);
+ LONG offl;
+ offl = SetFilePointer(fd, (ULONG)offset, &offh, whence);
+ if(offl == -1 && offh == -1) {
+ return -1;
+ }
+ return (((uint64)offh) << 32) | (uint64)offl;
+} // end udf_lseek64()
+
+#ifdef LIBUDFFMT
+BOOLEAN
+udf_get_sizes(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG* blocks
+ )
+{
+ ULONG bs;
+ int64 sz;
+ ULONG RC;
+
+ RC = _lphUdf->lpGetSizeFunc(_lphUdf->lpParameter, &sz, &bs);
+
+ (*blocks) = (ULONG)(sz/bs);
+
+ return(OS_SUCCESS(RC));
+}
+#endif //LIBUDFFMT
+
+#include "string_lib.cpp"
+
+#ifdef _BROWSE_UDF_
+#ifndef LIBUDF
+
+ULONG
+UDFGetDevType(
+ PDEVICE_OBJECT DeviceObject
+ )
+{
+ if(DeviceObject && DeviceObject == Vcb->TargetDeviceObject) {
+ return Vcb->PhDeviceType;
+ }
+ return FILE_DEVICE_DISK;
+} // end UDFGetDevType()
+
+#else // LIBUDF
+
+ULONG
+UDFGetDevType(
+ PDEVICE_OBJECT DeviceObject
+ )
+{
+#define lphUdf ((PUDF_VOL_HANDLE_I)(DeviceObject->lpContext))
+ return lphUdf->bHddDevice ? FILE_DEVICE_DISK : FILE_DEVICE_CD_ROM;
+#undef lphUdf
+} // end UDFGetDevType()
+
+#endif // LIBUDF
+
+#endif //_BROWSE_UDF_
+
+#endif //CDRW_W32
+
+#ifndef NT_NATIVE_MODE
+
+#ifdef PRINT_DBG_CONSOLE
+CHAR dbg_print_tmp_buff[2048];
+
+BOOLEAN was_enter = TRUE;
+
+extern "C"
+VOID
+PrintDbgConsole(
+ PCHAR DebugMessage,
+ ...
+ )
+{
+ int len;
+ va_list ap;
+ va_start(ap, DebugMessage);
+
+ if(was_enter) {
+ strcpy(&dbg_print_tmp_buff[0], JS_DBG_PREFIX);
+ len = _vsnprintf(&dbg_print_tmp_buff[sizeof(JS_DBG_PREFIX)-1], 2047-sizeof(JS_DBG_PREFIX), DebugMessage, ap);
+ } else {
+ len = _vsnprintf(&dbg_print_tmp_buff[0], 2047, DebugMessage, ap);
+ }
+ dbg_print_tmp_buff[2047] = 0;
+ if(len > 0 &&
+ (dbg_print_tmp_buff[len-1] == '\n' ||
+ dbg_print_tmp_buff[len-1] == '\r') ) {
+ was_enter = TRUE;
+ } else {
+ was_enter = FALSE;
+ }
+
+ OutputDebugString(&dbg_print_tmp_buff[0]);
+
+ va_end(ap);
+
+} // end PrintDbgConsole()
+#else // PRINT_DBG_CONSOLE
+VOID
+PrintDbgConsole(
+ PCHAR DebugMessage,
+ ...
+ )
+{
+} // end ClassDebugPrint()
+#endif //PRINT_DBG_CONSOLE
+
+BOOLEAN
+RtlTimeFieldsToTime(
+ IN PTIME_FIELDS TimeFields,
+ IN PLARGE_INTEGER Time
+ )
+{
+ SYSTEMTIME st;
+
+ st.wYear = TimeFields->Year;
+ st.wMonth = TimeFields->Month;
+ st.wDayOfWeek = 0;
+ st.wDay = TimeFields->Day;
+ st.wHour = TimeFields->Hour;
+ st.wMinute = TimeFields->Minute;
+ st.wSecond = TimeFields->Second;
+ st.wMilliseconds = TimeFields->Milliseconds;
+
+ return SystemTimeToFileTime(&st, (PFILETIME)Time);
+} // end RtlTimeFieldsToTime()
+
+BOOLEAN
+RtlTimeToTimeFields(
+ IN PLARGE_INTEGER Time,
+ IN PTIME_FIELDS TimeFields
+ )
+{
+ SYSTEMTIME st;
+ BOOLEAN retval;
+
+ retval = FileTimeToSystemTime((PFILETIME)Time, &st);
+
+ TimeFields->Year = st.wYear;
+ TimeFields->Month = st.wMonth;
+ TimeFields->Weekday = st.wDayOfWeek;
+ TimeFields->Day = st.wDay;
+ TimeFields->Hour = st.wHour;
+ TimeFields->Minute = st.wMinute;
+ TimeFields->Second = st.wSecond;
+ TimeFields->Milliseconds = st.wMilliseconds;
+
+ return retval;
+} // end ()
+
+#endif //NT_NATIVE_MODE
+
+#ifdef USE_THREAD_HEAPS
+
+HANDLE MemLock = NULL;
+
+VOID
+ExInitThreadPools()
+{
+ MemLock = CreateMutex(NULL, 0, NULL);
+}
+
+VOID
+ExDeInitThreadPools()
+{
+ if(MemLock)
+ CloseHandle(MemLock);
+}
+
+#define MAX_THREADS_WITH_OWN_POOL 128
+
+typedef struct _THREAD_POOL_LIST_ITEM {
+ HANDLE HeapHandle;
+ ULONG ThreadId;
+} THREAD_POOL_LIST_ITEM, *PTHREAD_POOL_LIST_ITEM;
+
+ULONG LastThreadPool = -1;
+THREAD_POOL_LIST_ITEM ThreadPoolList[MAX_THREADS_WITH_OWN_POOL];
+
+extern "C"
+PVOID
+#ifdef KERNEL_MODE_MM_BEHAVIOR
+_ExAllocatePool_(
+#else
+ExAllocatePool(
+#endif
+ ULONG MemoryType,
+ ULONG Size
+ )
+{
+ ULONG i;
+ ULONG ThreadId = GetCurrentThreadId();
+ BOOLEAN found = FALSE;
+
+ WaitForSingleObject(MemLock,-1);
+
+ for(i=0; i<(LastThreadPool+1); i++) {
+ if(ThreadPoolList[i].ThreadId == ThreadId) {
+ found = TRUE;
+ break;
+ }
+ }
+ if(found) {
+ ReleaseMutex(MemLock);
+ return HeapAlloc(ThreadPoolList[i].HeapHandle, HEAP_NO_SERIALIZE, Size);
+ }
+ for(i=0; i<(LastThreadPool+1); i++) {
+ if(ThreadPoolList[i].ThreadId == -1) {
+ break;
+ }
+ }
+ if(i>=MAX_THREADS_WITH_OWN_POOL) {
+ ReleaseMutex(MemLock);
+ return NULL;
+ }
+ ThreadPoolList[i].ThreadId = ThreadId;
+ ThreadPoolList[i].HeapHandle = HeapCreate(HEAP_NO_SERIALIZE, 128*PAGE_SIZE, 0);
+ if(!ThreadPoolList[i].HeapHandle) {
+ ThreadPoolList[i].ThreadId = -1;
+ ReleaseMutex(MemLock);
+ return NULL;
+ }
+
+ if(i+1 > LastThreadPool+1)
+ LastThreadPool = i;
+
+ ReleaseMutex(MemLock);
+
+ return HeapAlloc(ThreadPoolList[i].HeapHandle, HEAP_NO_SERIALIZE, Size);
+
+} // end ExAllocatePool()
+
+extern "C"
+VOID
+#ifdef KERNEL_MODE_MM_BEHAVIOR
+_ExFreePool_(
+#else
+ExFreePool(
+#endif
+ PVOID Addr
+ )
+{
+ ULONG ThreadId = GetCurrentThreadId();
+ ULONG i;
+
+ WaitForSingleObject(MemLock,-1);
+ for(i=0; i<(LastThreadPool+1); i++) {
+ if(ThreadPoolList[i].ThreadId == ThreadId) {
+ break;
+ }
+ }
+ if(i+1 > LastThreadPool+1) {
+ // Not found
+ BrutePoint();
+ //__asm int 3;
+ return;
+ }
+ HeapFree(ThreadPoolList[i].HeapHandle, HEAP_NO_SERIALIZE, Addr);
+
+ ReleaseMutex(MemLock);
+
+} // end ExFreePool()
+
+extern "C"
+VOID
+ExFreeThreadPool()
+{
+ ULONG ThreadId = GetCurrentThreadId();
+ ULONG i;
+
+ WaitForSingleObject(MemLock,-1);
+ for(i=0; i<(LastThreadPool+1); i++) {
+ if(ThreadPoolList[i].ThreadId == ThreadId) {
+ break;
+ }
+ }
+ if(i+1 > LastThreadPool+1) {
+ // Not found
+ BrutePoint();
+ //__asm int 3;
+ return;
+ }
+ HeapDestroy(ThreadPoolList[i].HeapHandle);
+ ThreadPoolList[i].HeapHandle = INVALID_HANDLE_VALUE;
+ ThreadPoolList[i].ThreadId = -1;
+
+ ReleaseMutex(MemLock);
+}
+
+#endif //USE_THREAD_HEAPS
+
+#if defined(KERNEL_MODE_MM_BEHAVIOR)
+extern "C"
+PVOID
+ExAllocatePool(
+ ULONG MemoryType,
+ ULONG Size
+ )
+{
+ PVOID Addr;
+ PVOID uAddr;
+ if(Size < PAGE_SIZE) {
+#ifdef USE_THREAD_HEAPS
+ Addr = _ExAllocatePool_(MemoryType, Size+8);
+#else
+ Addr = GlobalAlloc(GMEM_DISCARDABLE, Size+8);
+#endif
+ if(!Addr)
+ return NULL;
+ uAddr = ((PCHAR)Addr)+8;
+ } else {
+#ifdef USE_THREAD_HEAPS
+ Addr = _ExAllocatePool_(MemoryType, Size+PAGE_SIZE*2);
+#else
+ Addr = GlobalAlloc(GMEM_DISCARDABLE, Size+PAGE_SIZE*2);
+#endif
+ if(!Addr)
+ return NULL;
+ uAddr = (PVOID)(((ULONG)(((PCHAR)Addr)+PAGE_SIZE)) & ~(PAGE_SIZE-1));
+ }
+ *(((PULONG)uAddr)-2) = (ULONG)Addr;
+ *(((PULONG)uAddr)-1) = 0xFEDCBA98;
+ return uAddr;
+} // end ExAllocatePool()
+
+extern "C"
+VOID
+ExFreePool(
+ PVOID uAddr
+ )
+{
+ PVOID Addr;
+
+ if(*(((PULONG)uAddr)-1) == 0xFEDCBA98) {
+ Addr = (PVOID)(*(((PULONG)uAddr)-2));
+#ifdef USE_THREAD_HEAPS
+ _ExFreePool_(Addr);
+#else
+ GlobalFree(Addr);
+#endif
+ return;
+ }
+ BrutePoint();
+} // end ExFreePool()
+#endif //defined(KERNEL_MODE_MM_BEHAVIOR) || defined(NT_NATIVE_MODE)
+
+#ifdef _lphUdf
+#undef _lphUdf
+#endif //_lphUdf
+
+extern "C"
+BOOLEAN
+ProbeMemory(
+ PVOID MemPtr,
+ ULONG Length,
+ BOOLEAN ForWrite
+ )
+{
+ ULONG i;
+ UCHAR a;
+ if(!MemPtr && !Length)
+ return TRUE;
+ if(!MemPtr || !Length)
+ return FALSE;
+ _SEH2_TRY {
+ a = ((PCHAR)MemPtr)[Length-1];
+ if(ForWrite) {
+ ((PCHAR)MemPtr)[Length-1] = a;
+ }
+ for(i=0; i<Length; i+=PAGE_SIZE) {
+ a = ((PCHAR)MemPtr)[i];
+ if(ForWrite) {
+ ((PCHAR)MemPtr)[i] = a;
+ }
+ }
+ } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+ return FALSE;
+ } _SEH2_END;
+ return TRUE;
+} // end ProbeMemory()
+
+#ifdef NT_NATIVE_MODE
+#include "env_spec_nt.cpp"
+#endif //NT_NATIVE_MODE
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+/*************************************************************************
+*
+* File: env_spec_w32.h
+*
+* Module: User-mode applications (User mode execution only)
+*
+* Description:
+*
+*
+* Author: Alter
+*
+*************************************************************************/
+
+#ifndef __ENV_SPEC_W32__H_
+#define __ENV_SPEC_W32__H_
+
+#ifdef NT_NATIVE_MODE
+//#include "ntddk.h" // include this for its native functions and defn's
+#include "nt_native.h"
+#else //NT_NATIVE_MODE
+#include <windows.h>
+#endif //NT_NATIVE_MODE
+#include "platform.h"
+//#ifndef WITHOUT_FORMATTER
+#include "udferr_usr.h"
+//#endif WITHOUT_FORMATTER
+
+#ifndef NT_NATIVE_MODE
+#ifdef ASSERT
+ #undef ASSERT
+ #define ASSERT(a) if(!(a)) {__asm int 3;}
+#endif
+#endif //NT_NATIVE_MODE
+
+#ifndef MAXIMUM_FILENAME_LENGTH
+#define MAXIMUM_FILENAME_LENGTH MAX_PATH
+#endif //MAXIMUM_FILENAME_LENGTH
+
+#ifndef PAGE_SHIFT
+#define PAGE_SHIFT 12
+#endif //PAGE_SHIFT
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE (ULONG)0x1000
+#endif //PAGE_SIZE
+
+#ifndef PHYSICAL_ADDRESS
+#define PHYSICAL_ADDRESS LARGE_INTEGER
+#endif //PHYSICAL_ADDRESS
+
+#define OS_SUCCESS(a) NT_SUCCESS(a)
+#define OSSTATUS NTSTATUS
+
+#if defined UDF_DBG || defined DEBUG
+#define DBG
+#ifndef CDRW_W32
+#define UDF_DBG
+#endif //CDRW_W32
+#endif
+
+#define ERESEOURCE ULONG
+#define PERESEOURCE PULONG
+
+#define KEVENT ULONG
+#define PKEVENT PULONG
+
+typedef ULONG KSPIN_LOCK; // winnt ntndis
+typedef KSPIN_LOCK *PKSPIN_LOCK;
+
+#ifndef NT_NATIVE_MODE
+// Status ot
+#define NTSTATUS LONG
+
+#define NT_SUCCESS(x) ( (NTSTATUS)(x)>=0 )
+
+#define PsGetCurrentThread() GetCurrentThreadId()
+
+#define PsGetVersion(a,b,c,d) { \
+ OSVERSIONINFO OsVer; \
+ OsVer.dwOSVersionInfoSize = sizeof(OsVer); \
+ GetVersionEx(&OsVer); \
+ if(a) (*(a)) = OsVer.dwMajorVersion; \
+ if(b) (*(b)) = OsVer.dwMinorVersion; \
+ if(c) (*(c)) = OsVer.dwBuildNumber; \
+ if(d) (d)->Buffer = L""; \
+ if(d) (d)->Length = 0; \
+ if(d) (d)->MaximumLength = 0; \
+}
+
+extern "C"
+VOID
+PrintDbgConsole(
+ PCHAR DebugMessage,
+ ...
+ );
+
+#else //NT_NATIVE_MODE
+#define HINSTANCE HANDLE
+#endif //NT_NATIVE_MODE
+
+typedef
+int (*PSKIN_INIT) (
+ HINSTANCE hInstance, // handle to current instance
+ HINSTANCE hPrevInstance, // handle to previous instance
+ int nCmdShow // show state
+ );
+
+typedef
+int (*PSKIN_PRINTF) (
+ const char* Message,
+ ...
+ );
+
+typedef
+PWCHAR (__stdcall *PSKIN_GETCMDLINE) (
+ VOID
+ );
+
+typedef
+ULONG (__stdcall *PSKIN_MSG) (
+ ULONG MsgId,
+ ULONG MsgSubId,
+ PVOID DataIn,
+ ULONG DataInLen,
+ PVOID DataOut,
+ ULONG DataInOut
+ );
+
+typedef struct _SKIN_API {
+ PSKIN_INIT Init;
+ PSKIN_PRINTF Printf;
+ PSKIN_GETCMDLINE GetCommandLine;
+ PSKIN_MSG Msg;
+} SKIN_API, *PSKIN_API;
+
+#ifdef USE_SKIN_MODEL
+
+extern "C" PSKIN_API SkinAPI;
+extern PSKIN_API SkinLoad(
+ PWCHAR path,
+ HINSTANCE hInstance, // handle to current instance
+ HINSTANCE hPrevInstance, // handle to previous instance
+ int nCmdShow // show state
+ );
+
+#define SkinPrintf SkinAPI->Printf
+#define SkinGetCmdLine SkinAPI->GetCommandLine
+#define SkinNotify(op, state, ctx, sz) SkinAPI->Msg(op, state, ctx, sz, NULL, 0)
+#define SkinAsk(op, state, ctx, def) SkinAPI->Msg(op, state, ctx, sizeof(ctx), NULL, 0)
+
+#else
+
+#define SkinLoad(path) {;}
+
+#if defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+ #define SkinPrintf(x) {;}
+/*VOID
+inline
+SkinPrintf(
+ PCHAR Message,
+ ...
+ )
+{
+ //do nothing
+ return;
+}*/
+#else // defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+ #define SkinPrintf printf
+#endif
+
+#define SkinGetCmdLine GetCommandLineW
+#define SkinNotify(op, state, ctx) {;}
+#define SkinAsk(op, state, ctx, def) (def)
+
+#endif // defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+
+#if defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+
+ #if defined(PRINT_TO_DBG_LOG) || defined(PRINT_ALWAYS)
+ #define UserPrint(x) PrintDbgConsole x
+ #else
+ #define UserPrint(x) {;}
+ #endif // PRINT_TO_DBG_LOG
+
+#else // defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+
+ #if defined(PRINT_TO_DBG_LOG) || defined(PRINT_ALWAYS)
+
+ #define UserPrint(x) \
+ { \
+ SkinPrintf x ; \
+ PrintDbgConsole x ; \
+ }
+
+ #else // PRINT_TO_DBG_LOG
+
+ #define UserPrint(x) \
+ { \
+ SkinPrintf x ; \
+ }
+
+ #endif // PRINT_TO_DBG_LOG
+
+#endif // defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+
+#if defined(DBG) || defined(PRINT_ALWAYS)
+
+ #define DbgPrint SkinPrintf
+
+ #ifdef KdPrint
+ #undef KdPrint
+ #endif
+
+ #if defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+ #ifdef PRINT_TO_DBG_LOG
+ #define KdPrint(x) PrintDbgConsole x;
+ #else
+ #define KdPrint(x) {;}
+ #endif
+ #else
+
+ #if defined(PRINT_TO_DBG_LOG) || defined(PRINT_ALWAYS)
+ #define KdPrint(x) \
+ { \
+ SkinPrintf x ; \
+ PrintDbgConsole x ; \
+ }
+ #else
+ #define KdPrint(x) \
+ { \
+ SkinPrintf x ; \
+ }
+ #endif
+ #endif
+
+ #ifdef USE_MM_PRINT
+ #define MmPrint(_x_) DbgPrint _x_
+ #else
+ #define MmPrint(_x_) {NOTHING;}
+ #endif //USE_MM_PRINT
+
+ #ifdef USE_TIME_PRINT
+ extern ULONG UdfTimeStamp;
+ #define TmPrint(_x_) {UdfTimeStamp++;KdPrint(("TM:%d: ",UdfTimeStamp));KdPrint(_x_);}
+ #else
+ #define TmPrint KdPrint
+ #endif //USE_MM_PRINT
+
+ #ifdef USE_PERF_PRINT
+ #define PerfPrint(_x_) DbgPrint _x_
+ #else
+ #define PerfPrint(_x_) {NOTHING;}
+ #endif //USE_MM_PRINT
+
+#if defined(CDRW_W32) || defined(LIBUDFFMT) || defined(LIBUDF)
+ #ifdef USE_AD_PRINT
+ #undef USE_AD_PRINT
+ #endif
+ #ifdef USE_TH_PRINT
+ #undef USE_TH_PRINT
+ #endif
+#endif
+
+ #ifdef USE_AD_PRINT
+ #define AdPrint(_x_) {DbgPrint("Thrd:%x:",PsGetCurrentThread());DbgPrint _x_;}
+ #else
+ #define AdPrint(_x_) {NOTHING;}
+ #endif
+
+ #ifdef USE_TH_PRINT
+ #define ThPrint(_x_) {DbgPrint("Thrd:%x:",PsGetCurrentThread());DbgPrint _x_;}
+ #else
+ #define ThPrint(_x_) {NOTHING;}
+ #endif
+
+ #ifdef USE_DUMP_EXT
+ #define ExtPrint(_x_) DbgPrint _x_
+ #else
+ #define ExtPrint(_x_) {NOTHING;}
+ #endif //USE_MM_PRINT
+
+#else
+ #define KdPrint(x) {NOTHING;}
+ #define MmPrint(_x_) {NOTHING;}
+ #define TmPrint(_x_) {NOTHING;}
+ #define PerfPrint(_x_) {NOTHING;}
+ #define AdPrint(_x_) {NOTHING;}
+ #define ThPrint(_x_) {NOTHING;}
+ #define ExtPrint(_x_) {NOTHING;}
+#endif
+
+#define DbgTouch(a)
+
+#ifndef NT_NATIVE_MODE
+#include "assert.h"
+
+#define ASSERT(_x_) assert(_x_)
+#define UDFTouch(a)
+
+#endif //NT_NATIVE_MODE
+
+#define NonPagedPool 0
+#define PagedPool 1
+//#define NonPagedPoolMustSucceed 2
+#define NonPagedPoolCacheAligned 4
+
+#define KdDump(a,b) \
+if((a)!=NULL) { \
+ ULONG i; \
+ for(i=0; i<(b); i++) { \
+ ULONG c; \
+ c = (ULONG)(*(((PUCHAR)(a))+i)); \
+ KdPrint(("%2.2x ",c)); \
+ if ((i & 0x0f) == 0x0f) KdPrint(("\n")); \
+ } \
+ KdPrint(("\n")); \
+}
+
+//mem ot
+//#define ExAllocatePool(hernya,size) MyAllocatePool(size)
+//#define ExFreePool(size) MyFreePool((PCHAR)(size))
+//#define SystemAllocatePool(hernya,size) GlobalAlloc(GMEM_DISCARDABLE, size);
+//#define SystemFreePool(addr) GlobalFree((PVOID)(addr))
+#define DbgMoveMemory RtlMoveMemory
+#define DbgCompareMemory RtlCompareMemory
+#define DbgCopyMemory RtlCopyMemory
+#define DbgAllocatePool ExAllocatePool
+#define DbgAllocatePoolWithTag(a,b,c) ExAllocatePool(a,b)
+#define DbgFreePool ExFreePool
+
+#ifdef NT_NATIVE_MODE
+/*
+#define GlobalAlloc(foo, size) MyGlobalAlloc( size );
+#define GlobalFree(ptr) MyGlobalFree( ptr );
+
+extern "C"
+PVOID MyGlobalAlloc(ULONG Size);
+
+extern "C"
+VOID MyGlobalFree(PVOID Addr);
+*/
+#endif
+
+#if !defined(KERNEL_MODE_MM_BEHAVIOR) && !defined(USE_THREAD_HEAPS)
+#define ExAllocatePoolWithTag(hernya,size,tag) GlobalAlloc(GMEM_DISCARDABLE, (size))
+#define ExAllocatePool(hernya,size) GlobalAlloc(GMEM_DISCARDABLE, (size))
+#define ExFreePool(addr) GlobalFree((PVOID)(addr))
+#endif
+
+#if defined(KERNEL_MODE_MM_BEHAVIOR) || defined(USE_THREAD_HEAPS)
+#define ExAllocatePoolWithTag(MemoryType,size,tag) ExAllocatePool((MemoryType), (size))
+
+extern "C"
+PVOID ExAllocatePool(ULONG MemoryType, ULONG Size);
+
+extern "C"
+VOID ExFreePool(PVOID Addr);
+#endif //KERNEL_MODE_MM_BEHAVIOR || USE_THREAD_HEAPS
+
+#ifndef NT_NATIVE_MODE
+
+//string ot
+typedef struct _UNICODE_STRING {
+ USHORT Length;
+ USHORT MaximumLength;
+ PWSTR Buffer;
+} UNICODE_STRING;
+typedef UNICODE_STRING *PUNICODE_STRING;
+
+typedef struct _ANSI_STRING {
+ USHORT Length;
+ USHORT MaximumLength;
+ PSTR Buffer;
+} ANSI_STRING;
+typedef ANSI_STRING *PANSI_STRING;
+
+#endif //NT_NATIVE_MODE
+
+#define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG)(OFFSET) - (ULONG)(BASE)))
+
+// Device object ot
+
+#ifndef DO_UNLOAD_PENDING
+// Define Device Object (DO) flags
+//
+
+#define DO_UNLOAD_PENDING 0x00000001
+#define DO_VERIFY_VOLUME 0x00000002
+#define DO_BUFFERED_IO 0x00000004
+#define DO_EXCLUSIVE 0x00000008
+#define DO_DIRECT_IO 0x00000010
+#define DO_MAP_IO_BUFFER 0x00000020
+#define DO_DEVICE_HAS_NAME 0x00000040
+#define DO_DEVICE_INITIALIZING 0x00000080
+#define DO_SYSTEM_BOOT_PARTITION 0x00000100
+#define DO_LONG_TERM_REQUESTS 0x00000200
+#define DO_NEVER_LAST_DEVICE 0x00000400
+#define DO_SHUTDOWN_REGISTERED 0x00000800
+
+#endif //DO_UNLOAD_PENDING
+
+#ifdef NT_NATIVE_MODE
+#define _DEVICE_OBJECT _MY_DEVICE_OBJECT
+#define DEVICE_OBJECT MY_DEVICE_OBJECT
+#define PDEVICE_OBJECT PMY_DEVICE_OBJECT
+#endif //NT_NATIVE_MODE
+
+typedef struct _DEVICE_OBJECT {
+
+#ifndef LIBUDF
+
+ HANDLE h;
+ PVOID DeviceExtension;
+ ULONG Flags;
+ ULONG AlignmentRequirement;
+ UCHAR StackSize;
+
+#endif // LIBUDF
+
+
+#ifdef LIBUDFFMT
+
+ struct _UDF_FMT_PARAMETERS* cbio;
+ PVOID lpContext;
+
+#else
+#ifdef LIBUDF
+ PVOID lpContext;
+#endif // LIBUDF
+#endif // LIBUDFFMT
+
+} DEVICE_OBJECT, *PDEVICE_OBJECT;
+
+#ifndef CDRW_W32
+/*
+typedef ULONG DEVICE_OBJECT;
+typedef ULONG PDEVICE_OBJECT;
+*/
+#define INVALID_PACKET 0x01
+
+typedef struct _PACKET {
+ // Node Identifier
+// UDFIdentifier NodeIdentifier;
+ // Pointer to the buffer (in non-paged pool)
+ PCHAR buffer;
+ // Offset, from which this data was read
+ LARGE_INTEGER offset;
+ // Flags
+ UCHAR flags;
+} PACKET, *PPACKET;
+
+#define UDFInitPacket(x) STATUS_SUCCESS
+#endif //CDRW_W32
+
+#define try_return(S) { S; goto try_exit; }
+#define NOTHING
+
+#define FlagOn(x,f) ((x) & (f))
+
+#define RtlCompareMemory(s1,s2,l) MyRtlCompareMemory(s1,s2,l)
+// Structure ot
+extern "C"
+ULONG
+MyRtlCompareMemory(
+ PVOID s1,
+ PVOID s2,
+ ULONG len
+ );
+//#define RtlCompareMemory(d1,d2,l) (ULONG)(memcmp (d1,d2,l))
+
+#define KeSetEvent(pEvt, foo, foo2) {NOTHING;}
+#define KeInitializeEvent(pEvt, foo, foo2) {NOTHING;}
+#define KeWaitForSingleObject(pEvt, foo, a, b, c) {NOTHING;}
+#define DbgWaitForSingleObject(o, to) KeWaitForSingleObject(o, Executive, KernelMode, FALSE, to);
+//#define DbgWaitForSingleObject KeWaitForSingleObject
+#ifdef NT_NATIVE_MODE
+#define KeDelayExecutionThread(mode, foo, t) { NtDelayExecution(false, t); }
+#else //NT_NATIVE_MODE
+#define KeDelayExecutionThread(mode, foo, t) { Sleep( abs((LONG)(((t)->QuadPart)/10000)) ); }
+#endif //NT_NATIVE_MODE
+
+/*#define RtlCompareUnicodeString(s1,s2,cs) \
+ (((s1)->Length == (s2)->Length) && \
+ (RtlCompareMemory(s1,s2,(s1)->Length)))
+*/
+#ifndef CDRW_W32
+#ifdef _X86_
+
+// This is an illegal use of INT3
+#define UDFBreakPoint() __asm int 3
+#else // _X86_
+
+#define UDFBreakPoint() DbgBreakPoint()
+#endif // _X86_
+
+#ifdef BRUTE
+#define BrutePoint() UDFBreakPoint()
+#else
+#define BrutePoint() {}
+#endif // BRUTE
+
+#ifdef VALIDATE_STRUCTURES
+#define ValidateFileInfo(fi) \
+{ /* validate FileInfo */ \
+ if((fi)->IntegrityTag) { \
+ KdPrint(("UDF: ERROR! Using deallocated structure !!!\n"));\
+ /*BrutePoint();*/ \
+ } \
+}
+#else
+#define ValidateFileInfo(fi) {}
+#endif
+
+#else //CDRW_W32
+
+#ifdef BRUTE
+#ifdef _X86_
+
+// This is an illegal use of INT3
+#define BrutePoint() __asm int 3
+#else // _X86_
+
+#define BrutePoint() DbgBreakPoint()
+#endif // _X86_
+#else
+#define BrutePoint() {}
+#endif // BRUTE
+
+#endif //CDRW_W32
+
+#ifndef NT_NATIVE_MODE
+
+extern "C"
+ULONG
+RtlCompareUnicodeString(
+ PUNICODE_STRING s1,
+ PUNICODE_STRING s2,
+ BOOLEAN UpCase);
+
+extern "C"
+NTSTATUS
+RtlUpcaseUnicodeString(
+ PUNICODE_STRING dst,
+ PUNICODE_STRING src,
+ BOOLEAN Alloc
+ );
+
+extern "C"
+NTSTATUS
+RtlAppendUnicodeToString(
+ IN PUNICODE_STRING Str1,
+ IN PWSTR Str2
+ );
+
+#endif //NT_NATIVE_MODE
+
+extern "C"
+NTSTATUS
+MyInitUnicodeString(
+ IN PUNICODE_STRING Str1,
+ IN PCWSTR Str2
+ );
+
+#ifndef NT_NATIVE_MODE
+#define KeQuerySystemTime(t) GetSystemTimeAsFileTime((LPFILETIME)(t));
+
+typedef struct _FILE_BOTH_DIR_INFORMATION {
+ ULONG NextEntryOffset;
+ ULONG FileIndex;
+ LARGE_INTEGER CreationTime;
+ LARGE_INTEGER LastAccessTime;
+ LARGE_INTEGER LastWriteTime;
+ LARGE_INTEGER ChangeTime;
+ LARGE_INTEGER EndOfFile;
+ LARGE_INTEGER AllocationSize;
+ ULONG FileAttributes;
+ ULONG FileNameLength;
+ ULONG EaSize;
+ CCHAR ShortNameLength;
+ WCHAR ShortName[12];
+ WCHAR FileName[1];
+} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
+
+#endif //NT_NATIVE_MODE
+
+typedef UCHAR KIRQL;
+typedef KIRQL *PKIRQL;
+
+typedef ULONG ERESOURCE;
+typedef ERESOURCE *PERESOURCE;
+
+#define KeRaiseIrql(irql, oldIrql) \
+{ \
+ *oldIrql = 0; \
+}
+
+#define KeLowerIrql(oldIrql) {;}
+
+#define KeInitializeSpinLock(sl) \
+{ \
+ *(sl) = 0; \
+}
+
+#define KeAcquireSpinLock(sl,irql) \
+{ \
+ ULONG isLocked = TRUE; \
+ while(isLocked) AcquireXLock(*(sl), isLocked, TRUE);\
+}
+
+#define ExAcquireResourceExclusiveLite(res, wait) \
+{ \
+ ULONG isLocked = TRUE; \
+ while(isLocked) AcquireXLock(*(res), isLocked, TRUE);\
+}
+
+#define ExAcquireResourceSharedLite(res, wait) \
+{ \
+ ULONG isLocked = TRUE; \
+ while(isLocked) AcquireXLock(*(res), isLocked, TRUE);\
+}
+
+#define KeReleaseSpinLock(sl,irql) \
+{ \
+ ULONG isLocked; \
+ AcquireXLock(*(sl), isLocked, FALSE); \
+}
+
+#define ExGetCurrentResourceThread() 0
+
+#define ExReleaseResourceForThreadLite(res, thrdID) \
+{ \
+ ULONG isLocked; \
+ AcquireXLock(*(res), isLocked, FALSE); \
+}
+
+NTSTATUS inline ExInitializeResourceLite(PULONG res)
+{
+ *(res) = 0;
+ return STATUS_SUCCESS;
+}
+
+#define ExDeleteResourceLite(res) \
+{ \
+ *(res) = 0; \
+}
+
+#define ExConvertExclusiveToSharedLite(res) {/* do nothing */}
+
+#ifndef CDRW_W32
+
+#define UDFAcquireResourceExclusive(Resource,CanWait) \
+ ExAcquireResourceExclusiveLite((Resource),(CanWait))
+#define UDFAcquireResourceShared(Resource,CanWait) \
+ ExAcquireResourceSharedLite((Resource),(CanWait))
+// a convenient macro (must be invoked in the context of the thread that acquired the resource)
+#define UDFReleaseResource(Resource) \
+ ExReleaseResourceForThreadLite((Resource), ExGetCurrentResourceThread())
+#define UDFDeleteResource(Resource) \
+ ExDeleteResourceLite((Resource))
+#define UDFConvertExclusiveToSharedLite(Resource) \
+ ExConvertExclusiveToSharedLite((Resource))
+#define UDFInitializeResourceLite(Resource) \
+ ExInitializeResourceLite((Resource))
+#define UDFAcquireSharedStarveExclusive(Resource,CanWait) \
+ ExAcquireSharedStarveExclusive((Resource),(CanWait))
+#define UDFAcquireSharedWaitForExclusive(Resource,CanWait) \
+ ExAcquireSharedWaitForExclusive((Resource),(CanWait))
+//#define UDFDebugAcquireResourceExclusiveLite(a,b,c,d) ExAcquireResourceExclusiveLite(a,b)
+
+#define UDFInterlockedIncrement(addr) \
+ ((*addr)++)
+#define UDFInterlockedDecrement(addr) \
+ ((*addr)--)
+int
+__inline
+UDFInterlockedExchangeAdd(PLONG addr, LONG i) {
+ LONG Old = (*addr);
+ (*addr) += i;
+ return Old;
+}
+
+#endif //CDRW_W32
+
+//
+// Interrupt Request Level definitions
+//
+
+#define PASSIVE_LEVEL 0 // Passive release level
+#define LOW_LEVEL 0 // Lowest interrupt level
+#define APC_LEVEL 1 // APC interrupt level
+#define DISPATCH_LEVEL 2 // Dispatcher level
+
+#define PROFILE_LEVEL 27 // timer used for profiling.
+#define CLOCK1_LEVEL 28 // Interval clock 1 level - Not used on x86
+#define CLOCK2_LEVEL 28 // Interval clock 2 level
+#define IPI_LEVEL 29 // Interprocessor interrupt level
+#define POWER_LEVEL 30 // Power failure level
+#define HIGH_LEVEL 31 // Highest interrupt level
+#define SYNCH_LEVEL (IPI_LEVEL-1) // synchronization level
+
+#define KeGetCurrentIrql() PASSIVE_LEVEL
+
+#ifndef NT_NATIVE_MODE
+
+typedef struct _TIME_FIELDS {
+ USHORT Year; // range [1601...]
+ USHORT Month; // range [1..12]
+ USHORT Day; // range [1..31]
+ USHORT Hour; // range [0..23]
+ USHORT Minute; // range [0..59]
+ USHORT Second; // range [0..59]
+ USHORT Milliseconds;// range [0..999]
+ USHORT Weekday; // range [0..6] == [Sunday..Saturday]
+} TIME_FIELDS;
+typedef TIME_FIELDS *PTIME_FIELDS;
+
+//#define RtlTimeFieldsToTime(a,b) TRUE
+BOOLEAN
+RtlTimeFieldsToTime(
+ IN PTIME_FIELDS TimeFields,
+ IN PLARGE_INTEGER Time
+ );
+
+#define ExSystemTimeToLocalTime(SysTime, LocTime) FileTimeToLocalFileTime((PFILETIME)(SysTime), (PFILETIME)(LocTime))
+
+//#define RtlTimeToTimeFields(a,b) {}
+BOOLEAN
+RtlTimeToTimeFields(
+ IN PLARGE_INTEGER Time,
+ IN PTIME_FIELDS TimeFields
+ );
+
+#define ExLocalTimeToSystemTime(LocTime, SysTime) LocalFileTimeToFileTime((PFILETIME)(LocTime), (PFILETIME)(SysTime))
+
+#endif //NT_NATIVE_MODE
+
+#ifndef CDRW_W32
+
+typedef struct _FSRTL_COMMON_FCB_HEADER {
+ SHORT NodeTypeCode;
+ SHORT NodeByteSize;
+ UCHAR Flags;
+ UCHAR IsFastIoPossible;
+#if (_WIN32_WINNT >= 0x0400)
+ UCHAR Flags2;
+ UCHAR Reserved;
+#endif // (_WIN32_WINNT >= 0x0400)
+ PERESOURCE Resource;
+ PERESOURCE PagingIoResource;
+ LARGE_INTEGER AllocationSize;
+ LARGE_INTEGER FileSize;
+ LARGE_INTEGER ValidDataLength;
+} FSRTL_COMMON_FCB_HEADER, *PFSRTL_COMMON_FCB_HEADER;
+
+typedef struct _SECTION_OBJECT_POINTERS {
+ PVOID DataSectionObject;
+ PVOID SharedCacheMap;
+ PVOID ImageSectionObject;
+} SECTION_OBJECT_POINTERS;
+typedef SECTION_OBJECT_POINTERS *PSECTION_OBJECT_POINTERS;
+
+
+extern NTSTATUS UDFPhReadSynchronous(
+ PDEVICE_OBJECT DeviceObject,
+ PVOID Buffer,
+ ULONG Length,
+ LONGLONG Offset,
+ PULONG ReadBytes,
+ ULONG Flags);
+
+extern NTSTATUS UDFPhWriteSynchronous(
+ PDEVICE_OBJECT DeviceObject, // the physical device object
+ PVOID Buffer,
+ ULONG Length,
+ LONGLONG Offset,
+ PULONG WrittenBytes,
+ ULONG Flags);
+
+#if 0
+extern NTSTATUS
+UDFPhWriteVerifySynchronous(
+ PDEVICE_OBJECT DeviceObject, // the physical device object
+ PVOID Buffer,
+ ULONG Length,
+ LONGLONG Offset,
+ PULONG WrittenBytes,
+ ULONG Flags
+ );
+#endif
+
+#define UDFPhWriteVerifySynchronous UDFPhWriteSynchronous
+
+extern 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);
+
+#endif //CDRW_W32
+
+VOID set_image_size(HANDLE h,
+// ULONG LBA);
+ int64 len);
+
+#ifdef UDF_FORMAT_MEDIA
+struct _UDFVolumeControlBlock;
+#endif
+
+#ifndef UDF_FORMAT_MEDIA
+ULONG write(
+ HANDLE h,
+ PCHAR buff,
+ ULONG len);
+#endif
+
+extern "C"
+HANDLE
+my_open(
+#ifndef CDRW_W32
+ struct _UDFVolumeControlBlock* Vcb,
+#endif //CDRW_W32
+ PWCHAR fn);
+
+#ifdef UDF_FORMAT_MEDIA
+struct _UDFFmtState;
+#endif //UDF_FORMAT_MEDIA
+
+extern
+void
+my_exit(
+#ifdef UDF_FORMAT_MEDIA
+ struct _UDFFmtState* fms,
+#endif //UDF_FORMAT_MEDIA
+ int rc
+ );
+
+#ifndef CDRW_W32
+uint64 udf_lseek64(HANDLE fd, uint64 offset, int whence);
+#endif //CDRW_W32
+
+#ifdef LIBUDFFMT
+BOOLEAN
+udf_get_sizes(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG* blocks
+ );
+#endif //LIBUDFFMT
+
+int64
+get_file_size(
+ HANDLE h
+ );
+
+int64
+set_file_pointer(
+ HANDLE h,
+ int64 sz
+ );
+
+#ifndef NT_NATIVE_MODE
+typedef struct _IO_STATUS_BLOCK {
+ ULONG Status;
+ ULONG Information;
+} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
+#endif //NT_NATIVE_MODE
+
+
+#ifndef UDF_FORMAT_MEDIA
+extern ULONG LockMode;
+extern BOOLEAN open_as_device;
+extern BOOLEAN opt_invalidate_volume;
+#endif //UDF_FORMAT_MEDIA
+
+extern "C"
+ULONG
+MyLockVolume(
+ HANDLE h,
+ ULONG* pLockMode // OUT
+ );
+
+extern "C"
+ULONG
+MyUnlockVolume(
+ HANDLE h,
+ ULONG* pLockMode // IN
+ );
+
+#ifndef CDRW_W32
+ULONG
+UDFGetDevType(PDEVICE_OBJECT DeviceObject);
+#endif //CDRW_W32
+
+#ifndef INVALID_HANDLE_VALUE
+#define INVALID_HANDLE_VALUE ((HANDLE)(-1))
+#endif
+
+#ifndef ANSI_DOS_STAR
+
+#define ANSI_DOS_STAR ('<')
+#define ANSI_DOS_QM ('>')
+#define ANSI_DOS_DOT ('"')
+
+#define DOS_STAR (L'<')
+#define DOS_QM (L'>')
+#define DOS_DOT (L'"')
+
+#endif //ANSI_DOS_STAR
+
+extern "C"
+BOOLEAN
+ProbeMemory(
+ PVOID MemPtr,
+ ULONG Length,
+ BOOLEAN ForWrite
+ );
+
+#ifdef NT_NATIVE_MODE
+#include "env_spec_nt.h"
+#endif //NT_NATIVE_MODE
+
+#ifndef InitializeListHead
+
+//
+// Doubly-linked list manipulation routines. Implemented as macros
+// but logically these are procedures.
+//
+
+//
+// VOID
+// InitializeListHead(
+// PLIST_ENTRY ListHead
+// );
+//
+
+#define InitializeListHead(ListHead) (\
+ (ListHead)->Flink = (ListHead)->Blink = (ListHead))
+
+//
+// BOOLEAN
+// IsListEmpty(
+// PLIST_ENTRY ListHead
+// );
+//
+
+#define IsListEmpty(ListHead) \
+ ((ListHead)->Flink == (ListHead))
+
+//
+// PLIST_ENTRY
+// RemoveHeadList(
+// PLIST_ENTRY ListHead
+// );
+//
+
+#define RemoveHeadList(ListHead) \
+ (ListHead)->Flink;\
+ {RemoveEntryList((ListHead)->Flink)}
+
+//
+// PLIST_ENTRY
+// RemoveTailList(
+// PLIST_ENTRY ListHead
+// );
+//
+
+#define RemoveTailList(ListHead) \
+ (ListHead)->Blink;\
+ {RemoveEntryList((ListHead)->Blink)}
+
+//
+// VOID
+// RemoveEntryList(
+// PLIST_ENTRY Entry
+// );
+//
+
+#define RemoveEntryList(Entry) {\
+ PLIST_ENTRY _EX_Blink;\
+ PLIST_ENTRY _EX_Flink;\
+ _EX_Flink = (Entry)->Flink;\
+ _EX_Blink = (Entry)->Blink;\
+ _EX_Blink->Flink = _EX_Flink;\
+ _EX_Flink->Blink = _EX_Blink;\
+ }
+
+//
+// VOID
+// InsertTailList(
+// PLIST_ENTRY ListHead,
+// PLIST_ENTRY Entry
+// );
+//
+
+#define InsertTailList(ListHead,Entry) {\
+ PLIST_ENTRY _EX_Blink;\
+ PLIST_ENTRY _EX_ListHead;\
+ _EX_ListHead = (ListHead);\
+ _EX_Blink = _EX_ListHead->Blink;\
+ (Entry)->Flink = _EX_ListHead;\
+ (Entry)->Blink = _EX_Blink;\
+ _EX_Blink->Flink = (Entry);\
+ _EX_ListHead->Blink = (Entry);\
+ }
+
+//
+// VOID
+// InsertHeadList(
+// PLIST_ENTRY ListHead,
+// PLIST_ENTRY Entry
+// );
+//
+
+#define InsertHeadList(ListHead,Entry) {\
+ PLIST_ENTRY _EX_Flink;\
+ PLIST_ENTRY _EX_ListHead;\
+ _EX_ListHead = (ListHead);\
+ _EX_Flink = _EX_ListHead->Flink;\
+ (Entry)->Flink = _EX_Flink;\
+ (Entry)->Blink = _EX_ListHead;\
+ _EX_Flink->Blink = (Entry);\
+ _EX_ListHead->Flink = (Entry);\
+ }
+
+#endif //InitializeListHead
+
+#endif // __ENV_SPEC_W32__H_
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+/// Initial drive selection from command line.
+CHAR szDisc[4] = "";
+BOOL bChanger = FALSE;
+
+/// Return CD-RW device type
+JS_DEVICE_TYPE
+CheckCDType(
+ PCHAR m_szFile,
+ PCHAR VendorId
+ )
+{
+ HANDLE hDevice;
+ CHAR szDeviceName[256];
+ CHAR ioBuf[4096];
+ ULONG RC;
+ BOOL DvdRW = false;
+ BOOL DvdpRW = false;
+ BOOL DvdRAM = false;
+ BOOL DvdpR = false;
+ BOOL DvdR = false;
+
+ bChanger = FALSE;
+
+ // Make string representing full path
+ sprintf(szDeviceName, "\\\\.\\%s", m_szFile);
+ if (szDeviceName[strlen(szDeviceName)-1] == '\\') szDeviceName[strlen(szDeviceName)-1] = '\0';
+
+ // Open device volume
+ hDevice = OpenOurVolume(szDeviceName);
+
+ if (hDevice == ((HANDLE)-1)) {
+ strcpy(VendorId,"");
+ return BUSY;
+ } else {
+
+ // Get our cdrw.sys signature
+ RC = UDFPhSendIOCTL(IOCTL_CDRW_GET_SIGNATURE,hDevice,
+ &ioBuf,sizeof(GET_SIGNATURE_USER_OUT),
+ &ioBuf,sizeof(GET_SIGNATURE_USER_OUT),FALSE,NULL);
+
+ if (RC == 1) {
+ // Get device information
+ RC = UDFPhSendIOCTL(IOCTL_CDRW_GET_DEVICE_INFO,hDevice,
+ &ioBuf,sizeof(GET_DEVICE_INFO_USER_OUT),
+ &ioBuf,sizeof(GET_DEVICE_INFO_USER_OUT),FALSE,NULL);
+ if (RC != 1) {
+ strcpy(VendorId,"Unknown Vendor");
+ } else {
+ if(((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features & CDRW_FEATURE_CHANGER)
+ bChanger = TRUE;
+ strcpy(VendorId,(PCHAR)&(((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->VendorId[0]));
+ if (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features & CDRW_FEATURE_GET_CFG) {
+ DvdRW = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDRW_RESTRICTED_OVERWRITE) & 1;
+ DvdRAM = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDRAM) & 1;
+ DvdpRW = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDpRW) & 1;
+ DvdR = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDR) & 1;
+ DvdpR = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDpR) & 1;
+ }
+ }
+
+ // Get device capabilities
+ RC = UDFPhSendIOCTL(IOCTL_CDRW_GET_CAPABILITIES,hDevice,
+ &ioBuf,sizeof(GET_CAPABILITIES_USER_OUT),
+ &ioBuf,sizeof(GET_CAPABILITIES_USER_OUT),FALSE,NULL);
+ if(RC != 1) {
+ CloseHandle(hDevice);
+ return OTHER;
+ }
+
+ // Check capabilities
+ if(((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & (DevCap_write_cd_r | DevCap_write_cd_rw | DevCap_write_dvd_ram | DevCap_write_dvd_r) ||
+ DvdRW || DvdpRW || DvdRAM) {
+
+ if (DvdRAM || ((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & DevCap_write_dvd_ram) {
+ CloseHandle(hDevice);
+ return DVDRAM;
+ }
+/* if (DvdR) {
+ CloseHandle(hDevice);
+ return DVDR;
+ }*/
+ if (DvdRW) {
+ CloseHandle(hDevice);
+ return DVDRW;
+ }
+ if (DvdpRW) {
+ CloseHandle(hDevice);
+ return DVDPRW;
+ }
+/* if (DvdpR) {
+ CloseHandle(hDevice);
+ return DVDPR;
+ }*/
+ if (((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & DevCap_write_dvd_r) {
+ CloseHandle(hDevice);
+ return DVDR;
+ }
+ if (((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & DevCap_write_cd_rw) {
+ CloseHandle(hDevice);
+ return CDRW;
+ }
+ if (((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & DevCap_write_cd_r) {
+ CloseHandle(hDevice);
+ return CDR;
+ }
+ }
+ else {
+ CloseHandle(hDevice);
+ return OTHER;
+ }
+ } else {
+ strcpy(VendorId,"Unknown Vendor");
+ }
+ CloseHandle(hDevice);
+ }
+
+ return OTHER;
+} // end CheckCDType()
+
+/** Intialize asbtract device list via calls to CallBack function.
+ \param hDlg Not used.
+ \param hwndControl Passed to the CallBack function. See #PADD_DEVICE.
+ \param CallBack Callback function. Called on each CD device in system.
+*/
+void
+InitDeviceList(
+ HWND hDlg,
+ HWND hwndControl,
+ PADD_DEVICE CallBack
+ )
+{
+ char Buffer[MAX_PATH] = "";
+ char VendorId[25];
+ char seps[] = ",";
+ char* token;
+ char info[MAX_PATH];
+ bool add_drive = false;
+
+ JS_DEVICE_TYPE drive_type;
+
+ // Get all device letter in system
+ GetLogicalDriveStrings((DWORD)MAX_PATH,(LPTSTR)&Buffer);
+ token = (char *)&Buffer;
+ // Replace all zeroes with comma.
+ while (token != NULL) {
+ token = (char *)memchr(Buffer,'\0',MAX_PATH);
+ if (token) {
+ if (*(token-1) == ',') {
+ token = NULL;
+ } else {
+ *token=',';
+ }
+ }
+ }
+ // Parse string of drive letters separated by comma
+ token = strtok((char *)&Buffer,seps);
+ while (token != NULL) {
+ add_drive = false;
+ switch (GetDriveType(token)) {
+/*
+ case DRIVE_FIXED:
+ add_drive = true;
+ break;
+*/
+ case DRIVE_CDROM:
+ // Determine CD/DVD-ROM type (R,RW,RAM,other)
+ drive_type = CheckCDType(token,&VendorId[0]);
+ add_drive = true;
+ break;
+ }
+ if (add_drive) {
+
+ // Append to drive letter VendorId
+ strncpy(info,token,strlen(token)-1);
+ info[strlen(token)-1]='\0';
+ strcat(info," ");
+ strcat(info,VendorId);
+
+ BOOL bSelect = !strcmp(strupr(szDisc),strupr(token));
+ if (drive_type != OTHER) {
+ CallBack(hwndControl,token,info,MediaTypeStrings[drive_type],bSelect);
+ } else {
+ CallBack(hwndControl,token,info,"[Unsupported]",FALSE);
+ }
+
+ }
+ // Move to the next drive letter in string
+ token = strtok(NULL,seps);
+ }
+} // end InitDeviceList()
+
+HANDLE
+FmtAcquireDrive_(
+ PCHAR _Drive,
+ CHAR Level
+ )
+{
+ WCHAR LockName[32];
+ HANDLE evt;
+
+ WCHAR Drive[1];
+ Drive[0] = _Drive[0] & ~('a' ^ 'A');
+
+ swprintf(LockName, L"DwFmtLock_%1.1S%d", Drive, Level);
+ evt = CreatePublicEvent(LockName);
+ if(!evt) {
+ return NULL;
+ }
+ if(GetLastError() == ERROR_ALREADY_EXISTS) {
+ CloseHandle(evt);
+ return INVALID_HANDLE_VALUE;
+ }
+ return evt;
+} // end FmtAcquireDrive_()
+
+HANDLE
+FmtAcquireDrive(
+ PCHAR Drive,
+ CHAR Level
+ )
+{
+ HANDLE evt;
+
+ evt = FmtAcquireDrive_(Drive, Level);
+ if(!evt || evt == INVALID_HANDLE_VALUE) {
+ return NULL;
+ }
+ return evt;
+} // end FmtAcquireDrive()
+
+BOOLEAN
+FmtIsDriveAcquired(
+ PCHAR Drive,
+ CHAR Level
+ )
+{
+ HANDLE evt;
+
+ evt = FmtAcquireDrive_(Drive, Level);
+ if(evt == INVALID_HANDLE_VALUE) {
+ return TRUE;
+ }
+ if(evt) {
+ CloseHandle(evt);
+ }
+ return FALSE;
+} // end FmtIsDriveAcquired()
+
+VOID
+FmtReleaseDrive(
+ HANDLE evt
+ )
+{
+ if(evt) {
+ CloseHandle(evt);
+ }
+} // end FmtReleaseDrive()
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+JS_DEVICE_TYPE
+CheckCDType(
+ PCHAR m_szFile,
+ PCHAR VendorId
+ );
+
+typedef void (*PADD_DEVICE)(HWND hwndControl, PCHAR Drive, PCHAR Line1, PCHAR Line2,BOOL bSelect);
+
+void
+InitDeviceList(
+ HWND hDlg,
+ HWND hwndControl,
+ PADD_DEVICE CallBack
+ );
+
+extern CHAR szDisc[4];
+extern BOOL bChanger;
+
+HANDLE
+FmtAcquireDrive(
+ PCHAR Drive,
+ CHAR Level
+ );
+
+#define FmtAcquireDriveW(Drive, Level) FmtAcquireDrive((PCHAR)(Drive), Level)
+
+VOID
+FmtReleaseDrive(
+ HANDLE evt
+ );
+
+BOOLEAN
+FmtIsDriveAcquired(
+ PCHAR Drive,
+ CHAR Level
+ );
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#include "getopt.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return EOF with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+#define my_index wcschr
+
+#define my_strtoul wcstoul
+#define my_strlen wcslen
+#define my_strncmp wcsncmp
+#define my_strcpy wcscpy
+#define my_strcat wcscat
+#define my_strcmp wcscmp
+
+/* Handle permutation of arguments. */
+
+
+void
+getopt_init(optarg_ctx* o) {
+
+ o->optarg = NULL;
+ o->optind = 0;
+ o->optopt = BAD_OPTION;
+ o->opterr = 1;
+}
+
+static void
+exchange (
+ optarg_ctx* o,
+ WCHAR **argv
+ )
+{
+ WCHAR *temp, **first, **last;
+
+ /* Reverse all the elements [first_nonopt, optind) */
+ first = &argv[o->first_nonopt];
+ last = &argv[o->optind-1];
+ while (first < last) {
+ temp = *first; *first = *last; *last = temp; first++; last--;
+ }
+ /* Put back the options in order */
+ first = &argv[o->first_nonopt];
+ o->first_nonopt += (o->optind - o->last_nonopt);
+ last = &argv[o->first_nonopt - 1];
+ while (first < last) {
+ temp = *first; *first = *last; *last = temp; first++; last--;
+ }
+
+ /* Put back the non options in order */
+ first = &argv[o->first_nonopt];
+ o->last_nonopt = o->optind;
+ last = &argv[o->last_nonopt-1];
+ while (first < last) {
+ temp = *first; *first = *last; *last = temp; first++; last--;
+ }
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns `EOF'.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return BAD_OPTION after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return BAD_OPTION.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal(
+ optarg_ctx* o,
+ int argc,
+ WCHAR *const *argv,
+ const WCHAR *optstring,
+ const struct option *longopts,
+ int *longind,
+ int long_only)
+{
+ int option_index;
+
+ o->optarg = 0;
+
+ /* Initialize the internal data when the first call is made.
+ Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ if (o->optind == 0)
+ {
+ o->first_nonopt = o->last_nonopt = o->optind = 1;
+
+ o->nextchar = NULL;
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-') {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ } else if (optstring[0] == '+') {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+/* } else if (getenv ("POSIXLY_CORRECT") != NULL) {
+ ordering = REQUIRE_ORDER;*/
+ } else {
+ ordering = PERMUTE;
+ }
+ }
+
+ if (o->nextchar == NULL || *(o->nextchar) == '\0')
+ {
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (o->first_nonopt != o->last_nonopt && o->last_nonopt != o->optind) {
+ exchange (o, (WCHAR **) argv);
+ } else if (o->last_nonopt != o->optind) {
+ o->first_nonopt = o->optind;
+ }
+
+ /* Now skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (o->optind < argc
+ && (argv[o->optind][0] != '-' || argv[o->optind][1] == '\0')
+ ) {
+ o->optind++;
+ }
+ o->last_nonopt = o->optind;
+ }
+
+ /* Special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (o->optind != argc && !my_strcmp (argv[o->optind], L"--"))
+ {
+ o->optind++;
+
+ if (o->first_nonopt != o->last_nonopt && o->last_nonopt != o->optind) {
+ exchange (o, (WCHAR **) argv);
+ } else if (o->first_nonopt == o->last_nonopt) {
+ o->first_nonopt = o->optind;
+ }
+ o->last_nonopt = argc;
+
+ o->optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (o->optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (o->first_nonopt != o->last_nonopt)
+ o->optind = o->first_nonopt;
+ return EOF;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if ((argv[o->optind][0] != '-' || argv[o->optind][1] == '\0'))
+ {
+ if (ordering == REQUIRE_ORDER)
+ return EOF;
+ o->optarg = argv[o->optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Start decoding its characters. */
+ o->nextchar = (argv[o->optind] + 1
+ + (longopts != NULL && argv[o->optind][1] == '-'));
+ }
+
+ if (longopts != NULL
+ && ((argv[o->optind][0] == '-'
+ && (argv[o->optind][1] == '-' || long_only))
+ ))
+ {
+ const struct option *p;
+ WCHAR *s = o->nextchar;
+ int exact = 0;
+ int ambig = 0;
+ const struct option *pfound = NULL;
+ int indfound = 0;
+
+ while (*s && *s != '=')
+ s++;
+
+ /* Test all options for either exact match or abbreviated matches. */
+ for (p = longopts, option_index = 0;
+ p->name;
+ p++, option_index++)
+ if ( (p->val) && (!my_strncmp (p->name, o->nextchar, s - o->nextchar)) )
+ {
+ if (s - o->nextchar == (int)my_strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ } else if (pfound == NULL) {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ } else {
+ /* Second nonexact match found. */
+ ambig = 1;
+ }
+ }
+
+ if (ambig && !exact) {
+ if (o->opterr) {
+ KdPrint(("%ws: option `%s' is ambiguous\n",
+ argv[0], argv[o->optind]));
+ }
+ o->nextchar += my_strlen (o->nextchar);
+ o->optind++;
+ return BAD_OPTION;
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ o->optind++;
+ if (*s) {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg) {
+ o->optarg = s + 1;
+ } else {
+ if (o->opterr) {
+ if (argv[o->optind - 1][1] == '-') {
+ /* --option */
+ KdPrint((
+ "%ws: option `--%ws' doesn't allow an argument\n",
+ argv[0], pfound->name));
+ } else {
+ /* +option or -option */
+ KdPrint((
+ "%ws: option `%c%ws' doesn't allow an argument\n",
+ argv[0], argv[o->optind - 1][0], pfound->name));
+ }
+ }
+ o->nextchar += my_strlen (o->nextchar);
+ return BAD_OPTION;
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (o->optind < argc) {
+ o->optarg = argv[(o->optind)++];
+ } else {
+ if (o->opterr)
+ KdPrint(("%ws: option `%ws' requires an argument\n",
+ argv[0], argv[o->optind - 1]));
+ o->nextchar += my_strlen (o->nextchar);
+ return optstring[0] == ':' ? ':' : BAD_OPTION;
+ }
+ }
+ o->nextchar += my_strlen (o->nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag) {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[o->optind][1] == '-'
+ || my_index (optstring, *(o->nextchar)) == NULL)
+ {
+ if (o->opterr)
+ {
+ if (argv[o->optind][1] == '-') {
+ /* --option */
+ KdPrint(("%ws: unrecognized option `--%ws'\n",
+ argv[0], o->nextchar));
+ } else {
+ /* +option or -option */
+ KdPrint(("%ws: unrecognized option `%c%ws'\n",
+ argv[0], argv[o->optind][0], o->nextchar));
+ }
+ }
+ o->nextchar = (WCHAR *) L"";
+ o->optind++;
+ return BAD_OPTION;
+ }
+ }
+
+ /* Look at and handle the next option-character. */
+
+ {
+ WCHAR c = *(o->nextchar)++;
+ WCHAR *temp = my_index (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*(o->nextchar) == '\0')
+ ++(o->optind);
+
+ if (temp == NULL || c == ':')
+ {
+ if (o->opterr)
+ {
+ KdPrint(("%ws: illegal option -- %c\n", argv[0], c));
+ }
+ o->optopt = c;
+ return BAD_OPTION;
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*(o->nextchar) != '\0') {
+ o->optarg = o->nextchar;
+ o->optind++;
+ } else {
+ o->optarg = 0;
+ }
+ o->nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*(o->nextchar) != '\0')
+ {
+ o->optarg = o->nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ o->optind++;
+ }
+ else if (o->optind == argc)
+ {
+ if (o->opterr)
+ {
+ KdPrint(("%ws: option requires an argument -- %c\n",
+ argv[0], c));
+ }
+ o->optopt = c;
+ if (optstring[0] == ':') {
+ c = ':';
+ } else {
+ c = BAD_OPTION;
+ }
+ }
+ else
+ {
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ o->optarg = argv[o->optind++];
+ }
+ o->nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+getopt (
+ optarg_ctx* o,
+ int argc,
+ WCHAR *const *argv,
+ const WCHAR *optstring)
+{
+ return _getopt_internal (o, argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+int
+getopt_long (
+ optarg_ctx* o,
+ int argc,
+ WCHAR *const *argv,
+ const WCHAR *options,
+ const struct option *long_options,
+ int *opt_index)
+{
+ return _getopt_internal (o, argc, argv, options, long_options, opt_index, 0);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifndef _GETOPT_H
+#define _GETOPT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BAD_OPTION '\0'
+
+typedef struct _optarg_ctx {
+ /* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+ WCHAR* optarg;
+
+ /* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns EOF, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+ int optind;
+
+ /* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+ WCHAR *nextchar;
+
+ /* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+ int opterr;
+
+ /* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+ int optopt;
+
+ /* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+ int first_nonopt;
+ int last_nonopt;
+
+ /* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved.
+
+ To perform the swap, we first reverse the order of all elements. So
+ all options now come before all non options, but they are in the
+ wrong order. So we put back the options and non options in original
+ order by reversing them again. For example:
+ original input: a b c -x -y
+ reverse all: -y -x c b a
+ reverse options: -x -y c b a
+ reverse non options: -x -y a b c
+ */
+
+} optarg_ctx, *P_optarg_ctx;
+
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+ WCHAR *name;
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+extern void getopt_init(optarg_ctx* o);
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+extern int getopt (optarg_ctx* o, int argc, WCHAR *const *argv, const WCHAR *shortopts);
+extern int getopt_long (optarg_ctx* o, int argc, WCHAR *const *argv, const WCHAR *shortopts,
+ const struct option *longopts, int *longind);
+extern int getopt_long_only (optarg_ctx* o, int argc, WCHAR *const *argv,
+ const WCHAR *shortopts,
+ const struct option *longopts, int *longind);
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal (optarg_ctx* o, int argc, WCHAR *const *argv,
+ const WCHAR *shortopts,
+ const struct option *longopts, int *longind,
+ int long_only);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+static const char XPEHb[] = "zfvbgt^&*()aq,lpwdenjsxnygv!@yhuhb#$%chimuokbr";
+
+UDF_FibonachiNum(
+ int n,
+ int* f
+ )
+{
+ int a=0xff557788;
+ int i;
+ // do something
+ n <<= 8;
+ for(i=0; i<n; i = i++) {
+ a = ((a+i)*2) ^ ((a+n) * (XPEHb[i % (sizeof(XPEHb)-1)]) & 0xfffffffe) + 1;
+ if(i*2 >= n) {
+ n >>= 4;
+ (*f) = (*f) ^ (a+n);
+ n >>= 1;
+ a = n & a;
+ }
+ }
+ n >>= 3;
+ // if(n < 2)
+ if(!(n & ~1))
+ return 1;
+ n--;
+ if(!(n+1))
+ return 1;
+ a = UDF_FibonachiNum(n, f);
+ return UDF_FibonachiNum(n-1, f) + a;
+}
+
+void
+UDF_build_long_key(
+ char* buffer,
+ int blen,
+ char* key_str,
+ int klen
+ )
+{
+ int i, k, j;
+ int r[32];
+ int* tmp = (int*)buffer;
+ int f, fn;
+
+ memcpy(buffer, key_str, klen);
+ for(i=0; i<klen/4; i++) {
+ r[i%32] = tmp[i];
+ }
+ f = 0xf4acb89e;
+ for(k=0, fn=1, j=0; i<blen/4; i++) {
+ if(!fn) {
+ tmp[i] = tmp[k%(klen/4)];
+ fn = UDF_FibonachiNum(k, &f);
+ k++;
+ continue;
+ }
+ if(i>=blen/4)
+ break;
+ r[j%(klen/4)] = (int32)( ((int64)r[j%(klen/4)] * 0x8088405 + 1) >> 3 );
+ tmp[i] = r[j%(klen/4)] ^ f;
+ j++;
+ fn--;
+ }
+} // end UDF_build_long_key()
+
+
+void
+UDF_build_hash_by_key(
+ char* longkey_buffer,
+ int longkey_len,
+ char* key_hash,
+ char* key_str
+ )
+{
+ UDF_MD5_CTX context;
+ char key1[16];
+ int m;
+
+ UDF_build_long_key(longkey_buffer, longkey_len, key_str, 16);
+ UDF_MD5Init(&context);
+ UDF_MD5Update(&context, (PUCHAR)longkey_buffer, longkey_len);
+ UDF_MD5Pad (&context);
+ UDF_MD5Final((PUCHAR)key_hash, &context);
+ memcpy(key1, key_hash, 16);
+ for(m = 0; m<113; m++) {
+ UDF_build_long_key(longkey_buffer, longkey_len, key_hash, 16);
+ UDF_MD5Init(&context);
+ UDF_MD5Update(&context, (PUCHAR)longkey_buffer, longkey_len);
+ UDF_MD5Pad (&context);
+ UDF_MD5Final((PUCHAR)key_hash, &context);
+ }
+ for(m=0; m<16; m++) {
+ key_hash[m] = key_hash[m] ^ key1[m];
+ }
+} // end UDF_build_hash_by_key()
+
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#include "platform.h"
+#include "md5.h"
+
+#define UDF_LONG_KEY_SIZE 1024
+
+extern void
+UDF_build_long_key(
+ char* buffer,
+ int blen,
+ char* key_str,
+ int klen
+ );
+
+extern void
+UDF_build_hash_by_key(
+ char* longkey_buffer,
+ int longkey_len,
+ char* key_hash,
+ char* key_str
+ );
--- /dev/null
+{0x464eb272,0x9f4d726f,0x40f95d9c,0x3987ae09},
+{0x456423b2,0x6b084fb2,0x779f232e,0x3433bcb2},
+{0x120b2a5f,0xa015659c,0x37d3a35b,0xedddc7c6},
+{0x58eb88c0,0x93b4d904,0x39289e8c,0x485c18d0},
+{0x05da8341,0x1a37a08a,0xab5b9093,0xc1ad8dd0},
+{0x9f157c9c,0xeefec917,0x14f2f336,0x717fcc0c},
+{0x6b7a8089,0xa2097489,0x45dbe485,0x37d0f63b},
+{0xe28ba237,0xb97e5d70,0xb07696bc,0xa506a664},
+{0xd19ad8eb,0x7a0f236a,0xf80290c1,0x71f2b5b2},
+{0x2b0ec7d5,0x88271955,0xa90f3199,0x9dc098da},
+{0x5b0fcd3e,0x5778354a,0xda5e2509,0xf396b58b},
+{0xdf75eeeb,0xba02b001,0x68c29e6f,0xc5514d9c},
+{0x7c6ea336,0x41cbcd58,0xb777e433,0x664ab6d1},
+{0x960026ce,0x9cbd1c87,0xfa1a7818,0x84c673b6},
+{0x2ac852ac,0x8eaa9681,0x6819f875,0x6fc551a9},
+{0xc518549b,0x7a0a8230,0x5a1bfb84,0xa46f9027},
+{0x9e5eaa05,0xb9cdb6c6,0xccd325d7,0xf4d9c68f},
+{0x41b3b128,0xc3c8ce01,0x5f42b5e3,0x91b0d7e6},
+{0x0db18065,0x7e263df0,0xce72309b,0xcd15c548},
+{0x8fa12a15,0xf034c880,0x462828da,0x30720e25},
+{0xe4580867,0xc4323a04,0x2aad1d4a,0xabb5f2ae},
+{0x2d409ac0,0xca426d96,0xb6cff690,0x7ed609b1},
+{0x846bc82a,0xa2c5220b,0xfc8f9e6e,0x90cbb453},
+{0xe4461b74,0x9ebbf4ab,0x35d634e6,0xc026a6e8},
+{0x6f1aad49,0xf6812aef,0x0ee812a4,0xf878c9fc},
+{0xf5f1e6c0,0xffb384c5,0xea5fc9ab,0x4489c71c},
+{0x0a992ebb,0xd335a4ef,0x7d804a9e,0xcb7712fe},
+{0x27973f49,0x98b65183,0xecc6eb21,0xd7562406},
+{0xde9aa2fe,0x0a8ba7a6,0x762f5c9e,0x85dfc7e1},
+{0x9eb2a02a,0x08b8013e,0x58414587,0x14075bd0},
+{0xd6d2aa52,0xa5776692,0xd654a793,0xf8b2cd1e},
+{0x39acbf3c,0x91cfaedf,0xcda41b5a,0xbd1f43d9},
+{0xcb4e4068,0xfde0605e,0xa200dfa8,0x55a179d7},
+{0x505783e6,0xccd8c3bf,0x6f533151,0xb70b4ba9},
+{0x5dc7eeac,0xc3170129,0x942820e0,0x39663808},
+{0xc42d92cb,0xd32fc416,0x9b0e7e03,0x1d06b84c},
+{0x03f18479,0x7415b991,0x45fdb32f,0xfad21e67},
+{0x3bbcc977,0xcdceddc3,0x3087028f,0x3931f927},
+{0x3f600fc9,0x117dd904,0x53517eea,0x0f9063d1},
+{0xa23d715c,0x0da00448,0x7b397ad1,0x9fd7dd2a},
+{0x0d663599,0x4ff3e55d,0xe699dd5f,0x67d8cda1},
+{0x1fc05d79,0x5ef1a023,0x3541c6ca,0x5c087e48},
+{0x4bcbadc0,0xf2dafc5d,0x36ae4de2,0x3a360d1d},
+{0xae6a5788,0x1af7450b,0x10016900,0x6dca6aa3},
+{0xe8f6ff62,0xd2d9648c,0x3a914a56,0x887e6f02},
+{0x94a20036,0xd2ad657d,0x131df7d6,0xda27739d},
+{0x3ad80c90,0xc88d6b6a,0xed0c5936,0xb7848cff},
+{0xe85b07f9,0x43ef69a7,0x0649cac1,0x3724d61c},
+{0x7a6b0657,0x0fbb8c0d,0xe58e7262,0xf91c8036},
+{0x712b77b4,0xe4b1b0be,0xeb63ffd5,0x92bf033c},
+{0x54f1a982,0x83b6eb99,0x0b867758,0x2f213a25},
+{0x4e8c8976,0x1164dcac,0x53fbe278,0xad869afd},
+{0x05b566d7,0x467e202a,0xde861a33,0x73cd0c01},
+{0x50be1f0d,0xaf750eb0,0x55b8f755,0x5acb4ee7},
+{0x6f50daef,0x8537a233,0xb66ee044,0x2826c9a9},
+{0x942ddb0b,0xf5cb9067,0x78b2d2df,0x247d59b3},
+{0x90c659cf,0x444b27f5,0xe594e04a,0x4bb89ef2},
+{0x166e744e,0xeb9a0b8e,0x5ed79141,0x16c03653},
+{0x9da99fe5,0x1aef04a2,0x166a6d89,0x20fe85cc},
+{0x659a562e,0xc6a1d311,0x27d436b8,0xdf880426},
+{0x3c01541a,0x4dcdedf2,0x26bf4d05,0x9d7b80a1},
+{0x547cce62,0xdffbe77d,0xbc465468,0xab8813d5},
+{0xe8e5fe73,0x0a99255e,0x0f1848ac,0x9249c412},
+{0xb7c8f524,0x14016b68,0x92bf5ba9,0xd9860a34},
+{0xf3987bec,0xabc1d48f,0xc2295390,0x920807fd},
+{0x21f31bc9,0xdd912f06,0x04d4b523,0x511c166a},
+{0xd314e200,0x122253bc,0x586860a4,0xbdefecb0},
+{0x81e3b97f,0x5a34322e,0x901f12da,0x96ac5962},
+{0xbe70be25,0x9708c176,0x40515add,0x6670a8c6},
+{0x5a55b6bf,0xc41d077b,0x2be20a8b,0xa9346d1d},
+{0xf0940335,0x2dba5988,0x2b8de508,0xf10f90c4},
+{0x0858b635,0x98de0a2f,0xeb8826ee,0x99cccb5a},
+{0xf5970be7,0xa6206cae,0xa37967e4,0x7e3bdc8a},
+{0x620fd372,0x073b8288,0xeab77455,0xcfac4b96},
+{0x5a06daad,0x4d4f13f9,0x8815aa2d,0x418dba52},
+{0x5592b759,0xc54bf215,0x4d77971f,0xa569eec6},
+{0x6870ac5d,0xe715f4e0,0x188dbd7f,0xa0382fe1},
+{0xe438b05d,0x3743cffb,0x248b2ef1,0x2f37a8e7},
+{0xd075a482,0x787d34f6,0x999fc5a6,0x72c85a6e},
+{0x8cd0f999,0x67df4221,0x5aed7b04,0xc1887d1b},
+{0x8c983d3e,0x659ea055,0xec19849b,0x6da93a70},
+{0xfa69945f,0xa01e9036,0x6d1aba4f,0x6e001f63},
+{0x2f4cac40,0x004cfb9e,0x90c69b60,0xf4b4e109},
+{0xea15c026,0x4020cba9,0x935c4015,0xcd05f40e},
+{0x02e36239,0x9e05673a,0x6ee41e8c,0xd0cda541},
+{0x73a11589,0x5353d35e,0xe5bcb258,0x5fdea079},
+{0x97399ffd,0x05f9dc63,0x726e96c1,0xdcb01c47},
+{0xda84fbbc,0xf2c3c339,0xc48b9dc3,0xa68c7944},
+{0x4ab14c3a,0x47fe735d,0x4655bc4e,0xbb012871},
+{0x59fe1d5e,0x3f384cb1,0x4c377278,0x1850c1b5},
+{0x894d4e2e,0xb10e74b4,0x5e66dfb6,0x11f2f75c},
+{0xea4c6df5,0x95977aa6,0x442ed4bf,0x00767341},
+{0x9d8de9e3,0xad5c1bff,0x7745fff8,0x84d8282d},
+{0x676ac7b5,0x7b86dcd8,0x04631a2e,0x87a89cbb},
+{0x1d5ff8bc,0x13867c85,0x744f5d2f,0x776b6be7},
+{0x2de75ec7,0xf934c55b,0x338e7ef9,0x7c2a4174},
+{0x2225c2da,0x29fe9067,0x49351267,0x74d2831e},
+{0x661146b1,0x98a6751f,0xaf2e7c12,0xfd68d646},
+{0xc355f1d4,0xb5969617,0xdafa73d5,0xc6d36593},
+{0xfaa00891,0xa50a94d5,0xa859ebf3,0x90c6b97d},
+{0xdf2655ad,0xa48b57c5,0xc98e0d75,0xb1eb6547},
+{0xedc5fcf9,0x94bb1c9e,0xd9a457bd,0xdaa1f872},
+{0x04610e08,0x39a2ae50,0xeeb1ef12,0x5e3c0b85},
+{0x80125cae,0x375dd9ab,0x39795460,0x8ef0b2a6},
+{0x7ba2a83d,0x3e1c749a,0x50441a9e,0xf3d9286b},
+{0x22b80ffd,0x5a90460b,0x37304e96,0x100d0c16},
+{0xfc036a30,0xf2f3e782,0x1a1c52e0,0x818e62e3},
+{0x8fb2a8f0,0x78180dd5,0xf0146702,0x25e00c6c},
+{0xec8df538,0x5c116a43,0xec5ea158,0xfdb3c321},
+{0xc1e5afd7,0x63697a31,0x1e851111,0x0527619a},
+{0xe2990e8a,0xbf60a048,0x3f4b4881,0xb6f2d454},
+{0xe81da5b7,0x1d07e924,0x466d4108,0xb92c1ddb},
+{0xba4b51c5,0xb59f9676,0x9f6dca34,0x5014ff20},
+{0xdff0815b,0xba3359a2,0x290a931e,0x6afe9b4d},
+{0x488cead2,0xb5eba54c,0xab40db01,0x63ddaeb7},
+{0xb003cb57,0x3d0aa6ae,0x163fb5fd,0x2d1e180f},
+{0x8a661121,0x6fdcee1e,0x1d523b8f,0x04b6fb93},
+{0xba0611da,0x35b5cb6e,0x104a28bf,0x14816580},
+{0x1646b6c1,0x821ce88e,0xf5dcb33a,0xa502e55c},
+{0x943a0578,0x13a11f1d,0xb88506e0,0x2103d157},
+{0x99f2bd0a,0xe4557ea2,0x0607eb79,0x7661c9b7},
+{0x8e107dd4,0xec16b306,0xaeeb6102,0x5bed2e1c},
+{0xa0a91efa,0x373cf627,0xfeff21f0,0x15a26e9f},
+{0xa65100d1,0x0c1f1ea1,0x16473e4d,0xed2cd7ba},
+{0xb24fea09,0x18e8d920,0x49a53cac,0xf6854d17},
+{0xb5614dea,0x94e20a25,0x6b7233e8,0x1d9c3206},
+{0xf4a92d75,0x5f85c883,0xab122f23,0x437ca5d0},
+{0x374dd522,0xaac5ad1a,0x38f909f6,0xcc12fee2},
+{0xc2a96679,0xc0bb18fb,0xcd6d815c,0xbe637fe2},
+{0x652ce71f,0xe9425870,0xa42108df,0x68b4ccf0},
+{0xe5bbe5c4,0xfd090753,0xdac4efd2,0x5ea56477},
+{0x8f67d8a0,0x8fd61beb,0x0be2ff50,0x77078ab9},
+{0x71b68a44,0x75b34d51,0x885fd1d0,0x1b3f28ab},
+{0x670800ed,0x2802d7d8,0x23e22f3e,0xfdf3fb80},
+{0xcf519664,0xd9a4d453,0xd2623c20,0xa9a80f2d},
+{0x5f7af403,0xf859e86a,0xc7098674,0x8e46ebb8},
+{0x188c447b,0x94c207aa,0xd493db27,0x67f11959},
+{0x39f6f669,0xe07725e8,0x11e48861,0x6a2e8fac},
+{0xce335586,0xc6516c67,0xf65ef1c4,0xe9069f25},
+{0x75b2f286,0x0c8c4720,0xd63d60ea,0xe4340b83},
+{0x7d98ea1e,0x9da042ba,0x00a7c496,0x973aeaef},
+{0x8586cbb6,0x6c621b59,0xb5786657,0x143dd33c},
+{0x8c5da8f3,0x4c5aa120,0xc446424a,0x346681cf},
+{0x3df341bd,0xa9bbf625,0xcc0d6b59,0x5bce0859},
+{0x1cf1de06,0xc423eb66,0xe2a84cc1,0x8aa424e3},
+{0x8ab60890,0x2a032b4c,0xb564278f,0xb6eff9d4},
+{0x85e25a8f,0xfc8e7dc7,0xb94c8d7e,0xbd92faaa},
+{0x9849a0b5,0x9a6c8a7a,0x60b658e6,0x73c26c6d},
+{0xc6508f66,0xf39b1a2b,0xe9b4b7d5,0x42e524df},
+{0x98b3efb4,0x0515335d,0x56ea9c83,0xb09d656e},
+{0xe8390256,0x127e9239,0x0df5c7f7,0x2aaf968c},
+{0x62e426fb,0xf23ae4e1,0x23cc1adf,0x903c2634},
+{0x13a2b181,0x28a68411,0x033514ce,0x6f2d392c},
+{0x96d0993c,0xc95e6371,0xa3ecb3d7,0x32c580c2},
+{0xdbdd9789,0x4b063cf0,0xd3ca705d,0xff1dde9e},
+{0x744210fe,0xb47cb775,0xe9209529,0x5d92fb9d},
+{0x576aa312,0x4b7fde61,0xba2b3590,0xe1919c0b},
+{0x8c414c99,0x8d2f9965,0x70e75b2e,0x201daf0c},
+{0xe74c5ce2,0xe0730812,0x32ac229b,0x8b574aab},
+{0x6a27385e,0xf7e62ce0,0x996569f5,0xca9d3768},
+{0x51583907,0x2375d2d2,0x511db2d8,0xed73b351},
+{0xc2181bce,0xded144b4,0x4121147a,0xfc367633},
+{0xaa9dac85,0x25346819,0x3077443f,0x54c0227c},
+{0x2fefcbd5,0x74ce5196,0x96971fc5,0x6c8f60ac},
+{0xff990570,0xcc61f389,0x3fd1992c,0xd0c617e7},
+{0x67a4f115,0x12d1de80,0x13d0a638,0x39616006},
+{0xd9ce36a8,0x18818b09,0x3e12c13b,0xb941cefe},
+{0xcc118030,0xff2b39f9,0x9ec14ffb,0x75be156a},
+{0x1124525b,0x507b707e,0xb2c2f2ab,0x7fd1545e},
+{0x222288f9,0xc44b221e,0xffd6cbd0,0xb128a234},
+{0xe71aa36b,0x35b1b1a1,0x040ca92d,0x5f33f73f},
+{0x4869432d,0x268e6b9d,0x6151a2c3,0x9cf7b4f2},
+{0x38ff5534,0x75588fd1,0x52502688,0x9d516413},
+{0xf64add9b,0x1dddd827,0x88fea8ad,0xa2d1af76},
+{0x0fe4a7e7,0xd6fe3fc2,0xba6d6256,0xa4fd8553},
+{0x285bd0aa,0x9f53a7b8,0x0302a4fe,0x12ba4a22},
+{0xf0a02afe,0x5669141a,0x05958a39,0xe87f04ea},
+{0xdac350d0,0xd29fb016,0x5c5f0b02,0x01f143b2},
+{0x4d20fe77,0xadcbb181,0xc0f04454,0x64b2be37},
+{0xfe0212a7,0x718abe5e,0x98061ae2,0x0dd9e431},
+{0x191a152f,0x87f27de9,0xd054af43,0x00d6b04d},
+{0xc0735210,0x0bd58b3f,0x96ac6912,0x2eb53fcd},
+{0x796f04fa,0xd2689737,0xddc044ff,0x508cb995},
+{0x733e1ee7,0xf579535e,0x9ae30c09,0x1ee0f7e9},
+{0x627b1ebf,0x1604bd39,0x75ffe5f5,0x0c8ca8f1},
+{0x11d7f6fd,0xe86e800b,0x9339f931,0x9798ad9d},
+{0xed7bd57d,0x0db9e1c5,0x2df8a441,0x4a4aab0c},
+{0x69822c06,0xafd7902e,0xb5f897cd,0x2fefbc9d},
+{0x1ae2a0a3,0x71413064,0x53df291b,0x5579b863},
+{0xfdd3de57,0x63d05fd0,0x9fa32952,0x9b84c9c0},
+{0xebecac20,0xbf9f67cb,0x61210e29,0x2d110b22},
+{0x5e1aa86b,0xf928b1bb,0xc43dc3f0,0x5e7a53ca},
+{0x6aeb61c7,0x30acacaa,0x0a758d2f,0x7761a984},
+{0xce30d965,0x4a288c7d,0x7fe3d287,0x805912b1},
+{0x8201f728,0x690c296c,0x41e25b06,0x6ef30ed1},
+{0xd18879df,0x901a3eb3,0xb4e2e516,0x6a25ef09},
+{0x16dea57b,0x874d54b7,0xe7f33a53,0x803701c3},
+{0x16acef19,0xfbe1905c,0xd412145a,0xf25ac334},
+{0x6037cdfc,0x6f33a11b,0x145d5f39,0x5413eeda},
+{0x5aa2bc9f,0xa19c6a1d,0xd6389f34,0x2dd08f8f},
+{0xd6bb0e57,0x148bc047,0x0ba7bca1,0xf0f96f47},
+{0x6a6f0b8d,0x9f713a8d,0x080c8048,0x8fd9d3c5},
+{0x0541a5cb,0x78cebc1d,0xcbbac10d,0xecb49da3},
+{0x2648b918,0x05cf1b76,0xa71b29de,0x4cd4bd85},
+{0x8aca0fef,0x882360fe,0x574f3705,0xffab6346},
+{0xe27847e3,0x4c840db1,0x4cb1ad0d,0xa1502e7f},
+{0x26f3dbef,0xb8586678,0x6ac33e62,0xa79d4883},
+{0x5cf8424b,0xa8d5bdd7,0xdf8e2aff,0x03c2452b},
+{0x04a4e58c,0x586ea473,0xac19957b,0x3cd1808f},
+{0x2276c1ae,0x0f1672e8,0x6ccccefa,0xb474d276},
+{0xca4b83aa,0x5ca07ca6,0x7bad899f,0xcb9cd680},
+{0xaaa3c07a,0x52028a10,0x9921d96c,0xd606e704},
+{0xf7872f1f,0xaf05198d,0x57349b0b,0x7b8bb956},
+{0xf04908e0,0x8f7d2b71,0xcd8689b7,0x08994cb9},
+{0x67be9e79,0x959f2850,0xdfa2ea88,0x2d34c458},
+{0x51066f0f,0x0ecf8473,0x442592e0,0x2a208172},
+{0xb1443065,0xcb4b6c99,0x08fbe6db,0x2dc08b9b},
+{0x68b653df,0x3597e82c,0xb66feb5f,0x6f338761},
+{0x3f660aae,0x121166ba,0xd365615e,0x495b3451},
+{0xe20162e5,0xb5e6c7f3,0x53205114,0x1dd3aa7f},
+{0x6298b11b,0xbb89ed63,0x2d5103e8,0x4fa81473},
+{0xa3d1e970,0x7d4c2764,0x8b8c3d1c,0x8092e54a},
+{0x127eae63,0xacb401d8,0xcc2534f2,0x82678387},
+{0xfead8828,0xd383c70c,0xb01e6836,0x0956c3d6},
+{0x79cc0594,0xb15be42c,0x7f80de1f,0x949636be},
+{0xee08f04d,0x71733158,0x59a04640,0x3efe92c9},
+{0x7c40cc35,0x80211f91,0xe16f901d,0x1664733f},
+{0x4243fc5b,0xf59972ad,0xc2b2d815,0xd4ec83e0},
+{0xd0cce67b,0xc9ed8a0b,0x6938f254,0x26d8a0c6},
+{0xdf14738a,0x22793292,0xca1b8f93,0x5678362f},
+{0x0802182d,0x7c924a03,0xfe99f175,0x15272607},
+{0xc07a61dc,0x383e9160,0x4cf2de36,0xc4112b3b},
+{0x403e1c63,0xd95077ad,0xf70d08ab,0x724e9745},
+{0xf6598de8,0xc024e2b9,0x3ab423f4,0x49238fa9},
+{0xe8869cb8,0xfd517256,0x6c26c298,0x420a6993},
+{0xe9435dbb,0x7ad6419b,0xfa941963,0x3c14b6d6},
+{0x771916a1,0x48ae53cd,0x7d9bd148,0xa2116f9e},
+{0x717b6010,0x08d2ed76,0x7ab952c4,0x2300bf03},
+{0x670d8997,0x09e23cdb,0xeff00f50,0x1698ffad},
+{0xfcb0552c,0x1ad81994,0x643e8022,0xa6a6b588},
+{0x792f05fe,0x10c4910d,0xfcc6d591,0xe8d946aa},
+{0xfa26c441,0xda604668,0x6eaf7282,0x06a523b4},
+{0x534d6d76,0x7c08ddd1,0xdc0b23e5,0x69c7a581},
+{0x308dbe91,0x516877f5,0xe16cb6e6,0xe7947f22},
+{0x677b572b,0x89a23727,0xff1e80f3,0xb5fb00c6},
+{0x9831a920,0x8352bd61,0x79e2867d,0x961d16f3},
+{0x49681542,0xde5393c5,0x8e64217d,0xa4787fcc},
+{0xa5a6f59e,0xeb8826ab,0xfe76dc57,0x3c91e330},
+{0x11b4ff07,0x3207b417,0x4e3a90ff,0xced4c105},
+{0x055f738b,0xd090f472,0x2793925e,0x069c3c9d},
+{0x34895169,0x969a4bac,0x8152a1ec,0x7a429a21},
+{0xabb398b9,0xd1b8b55b,0x2f27435a,0x3b35827e},
+{0x1e5395c7,0xb2f1e9fb,0xd6be7903,0xb139b803},
+{0x0ced7375,0x43f670c1,0x8490f305,0xf953c4ee},
+{0x98ea2ac8,0xed9c2790,0x688551f7,0x88677401},
+{0x6d19e99a,0x17ebf706,0x63e71abb,0x5150811e},
+{0x16ee26fd,0x3cae3d22,0x8bf06d71,0xbdaf50b1},
+{0xd737dfd3,0x6bf72882,0x22455b57,0x6da57325},
+{0x5e062082,0xc8fcf42d,0x7050da6d,0x5ee62bc1},
+{0x762f7783,0xd7f0d368,0x5a424857,0x7f371f3d},
+{0x0c9298a1,0x4685bc48,0x625f5e47,0x74b8c5d7},
+{0xe0157161,0x8c82749c,0x38d25bd2,0x82740065},
+{0x6639d77d,0x3dcc6db6,0x5677ed3e,0xc92f1f5b},
+{0x4e4ffe36,0xd09f9e04,0x35cbaecc,0x635f0f29},
+{0xf27a1827,0x35021b69,0x0b2fec9b,0x3832c35b},
+{0x9370fa61,0x648e4484,0x874a687a,0xff15f1fa},
+{0x6552b060,0xe1eea13c,0x79a81141,0x125a731b},
+{0xcf74e28c,0x361d99cf,0x735ad0d7,0x17781338},
+{0x64c55a26,0x8cf2b57f,0xcffb0eed,0xd44b664b},
+{0x897dbf3e,0xa73d5b3f,0x606eba0b,0x7fea83eb},
+{0xa6cfa45a,0x8e19869e,0xb35b4a59,0xda9790f0},
+{0x5381db83,0xf3e06cca,0xceb51e21,0x806546a5},
+{0x7079e3c7,0x7081515b,0x5d0f2805,0x42077d2e},
+{0x9ebbc897,0x13dea72b,0xe7520b89,0xa0f70f23},
+{0xdc8d587f,0x1563c103,0x752ef3ee,0x3a8aa821},
+{0x8587cf23,0x1a160e5c,0x01a29306,0x8c84e4df},
+{0xb4ef90bd,0x896818ac,0xf6320f47,0xe584a06e},
+{0x5edc16f9,0xda75c31f,0xd73d791f,0x08fc05fb},
+{0x7d9676a7,0x48483537,0x87377025,0xd477e615},
+{0xf9648730,0xbfc1f99a,0xf84247ee,0xf3fbbdd6},
+{0xce336727,0xd9fbc28b,0x173622e8,0xe50427b0},
+{0xb22da76a,0x2f56a7b5,0x9c4a5304,0x26b61345},
+{0x12b2e9f7,0xd91b9ee3,0xc50c580b,0x11bfbf8e},
+{0x5b68aca6,0x9f9c45cc,0x4226003c,0x5033387f},
+{0xcc0b7db1,0x0cbd30ef,0x040fbb96,0xff92790f},
+{0xd8441e4b,0x506feedd,0xf0ef7ef6,0x5278dac5},
+{0xa586b239,0x9057d034,0x045a10d4,0xff0a4501},
+{0x44c84aca,0x72c7e534,0x9d8b762e,0x09ce7080},
+{0xb19f89f4,0x64807b1b,0x5fc256f5,0x484beaed},
+{0xdeee7e78,0xf7953521,0x5ab0d38a,0xd9c5ccf2},
+{0x2752ba06,0xb149df6a,0xa86bdf71,0x98177806},
+{0x0b165963,0x80c9e332,0x45b05eb9,0x56436678},
+{0x07db7854,0xafbfa56c,0xd598aef9,0x20291690},
+{0x34105580,0x3ebff180,0xb54f0d9f,0x5aac4179},
+{0x9216b3c1,0x0ea2ccc3,0x15e72dba,0x8109567c},
+{0xf3f71644,0x8300bfa8,0xc7762650,0x52cffa43},
+{0xf0e3fcd9,0x0692f957,0x29cb6333,0x6551e83e},
+{0xaf299261,0x0fd8ad80,0x953d045a,0xdcdc0dd8},
+{0xe4e0e616,0x5697b667,0x739cdf50,0x1632e015},
+{0xa463afb0,0x00037812,0xe0ff4e3b,0x7f9370d4},
+{0x8d0dcddd,0xa0222788,0x75a07e11,0x928890db},
+{0xfae0d7f6,0x547c9f6c,0xcaa46153,0x26151c95},
+{0xf09671ce,0x39c5ad01,0x503458f5,0x55c989c9},
+{0xa0be3f26,0x8e164850,0xf62f453b,0x15763688},
+{0x6277b34d,0x5cf05538,0xf98f5180,0xaac7a458},
+{0x194be347,0xe9652177,0x4c76c864,0x43b90beb},
+{0x04334387,0x6c9a1c64,0xb478b652,0xa68a0530},
+{0xe0b5287c,0xdd5fa3c9,0x18ac0290,0x6355f990},
+{0xfb975657,0x11030bd2,0xf873a64b,0xe908982b},
+{0x0c039dcc,0xb4a27dcd,0x7f91df01,0x6ca660cf},
+{0x4a5f70c7,0x08d66dad,0xbaeb303d,0xeaf6ac62},
+{0x6134df3f,0x4346c32d,0x0ccef492,0x80d58162},
+{0x3f9e9cb8,0xa3008f54,0xf7022502,0x096aa2db},
+{0x09643405,0x0bef72e1,0x7a0161e3,0x02b6800d},
+{0x4a9fd7b2,0x2ff2c6e7,0xb0e0f0d6,0x22c5dd5e},
+{0x065c8abe,0x3a54cf26,0x08376d5d,0xd7cdfe40},
+{0xddde7842,0xf5ac25cd,0x2c3a8ba3,0xd8475b2e},
+{0xcb7569f8,0x91c35be9,0x4f235518,0x01922f3b},
+{0x37d9967b,0xfec674e7,0x37ba068d,0xbe1e5473},
+{0xf015ccfa,0x273f9622,0x5b01fa82,0x57b49d65},
+{0xcedfafa7,0xf839a339,0x39de9cb8,0x92af53c7},
+{0xf3a0db2a,0xe94cfc32,0x97d7ba1e,0x63b49741},
+{0xb2b87d08,0x1f1f6080,0xfd768ea4,0x4a975140},
+{0xd81d6db5,0xc8963e38,0x16410bb1,0x2ea27c76},
+{0x8a93e2f6,0x62fbb98e,0x56f90e07,0xbe9e0de9},
+{0x38e10de8,0x39b0022d,0x912eb927,0x8932e981},
+{0x26342052,0xd9b8fc21,0xefb02a6c,0xc904b8aa},
+{0xde4a82f1,0x3bb922f5,0x9b7d98b1,0xa94ba85b},
+{0xacd0ce2c,0xdd191a60,0x0ced9791,0x2ca62c1e},
+{0xc29af305,0xe13d427b,0x37dbd054,0x4c9e741d},
+{0xf835ce44,0xaf77c79a,0x888dd7f4,0x2488e20c},
+{0x08790953,0xe1e8b06a,0x5779d964,0x231b9d94},
+{0xd09a2d81,0x4c3bf9c8,0xda6a82c5,0x1ed5874c},
+{0x264cfcca,0xa15fd61f,0x44a36e1e,0xbff8e65a},
+{0xac7f9e1c,0x93a018cd,0xf946989e,0xdf35f7bd},
+{0xe6b78c52,0x1ab4250b,0xaf864921,0xb2d6cbff},
+{0xc1d932c6,0xd21fc917,0xe80769ea,0x547f1728},
+{0x446a0ef9,0xcd05936a,0xd5b01469,0xb217ad15},
+{0x5b6d04c3,0x4062fa77,0xac7e474f,0x14183152},
+{0x18715a09,0xb425c049,0x271a175e,0xaba13a20},
+{0xe5784f5a,0x06a69f91,0x55c31430,0x1d3c1e03},
+{0x89d90d35,0x9799d79d,0x1aba6e3e,0x5f4820cb},
+{0xc10a24ab,0xbe37d72e,0x4470cb4a,0x238cb818},
+{0xb66ab610,0xa32b76ec,0x35b42469,0x8768088b},
+{0x834bf11c,0x893041a6,0xfbd260d6,0x2d944658},
+{0xa0aafe39,0xb2e78a0a,0x9787b679,0xabad282d},
+{0x83fa9fd0,0x95534f4b,0xc81cd185,0x55f60b8a},
+{0xea82a5e9,0x677b0bf1,0x4930061d,0x9f678be0},
+{0x735dda06,0xba8cf349,0xf70ade7d,0x1202d45d},
+{0xcb40ce40,0x490c44e6,0xadf1af60,0xccb1f81a},
+{0xd93e9fec,0xe32f636a,0xb93d1fa7,0x3a6b765e},
+{0xdf0c87ca,0x3a529193,0x851b2f76,0x0bc7141c},
+{0x05b2f330,0x9f69b5fa,0xaa428d31,0xac88d110},
+{0x1c0c4dca,0xa35f3c72,0xa956c31b,0x7dbe7fad},
+{0xeed1e431,0x1166648f,0xb492d014,0x25592e6f},
+{0xbaca3593,0x4b0f7ba4,0xf9ad5aee,0xb7aa1606},
+{0x230f76b5,0x1139fcbc,0xaf6da823,0x2a007b46},
+{0xe10cc036,0x80bff8dd,0xc487d20f,0x3ff07911},
+{0x2810fe5d,0x738a616f,0x31fcab25,0x8471cfee},
+{0x637d7bf9,0xe6e44c83,0x72c7b44c,0x13ffd522},
+{0xcd8c080e,0x501a9f44,0x96bcb5cf,0x35c7eb31},
+{0x4d2f89e5,0x53dabfa2,0xb4688261,0xc16eed4e},
+{0x93b9050b,0x5be7fa5d,0x18670a44,0x3d2e8456},
+{0x6366c565,0xe2637cc2,0x81991664,0x5f23f909},
+{0x1bd3abdd,0x006e052a,0x15a0ed8c,0xd8ada32f},
+{0xc994c0f7,0xece89aa1,0x246e02f6,0x4cee3b85},
+{0xc6ef8878,0xa1d76898,0xce6168d7,0xdfa16b1f},
+{0x700da326,0x2619930e,0x4caa5968,0x59e3abe6},
+{0x856a3cad,0xacc2c33d,0x3bc61929,0x2eae13e9},
+{0x07f819d2,0xd5606875,0x4f6b2e6b,0x1eeca72a},
+{0x3d18ea86,0xdbb4bd42,0x78075765,0xd667bfe4},
+{0xbe81f615,0xec5e88aa,0x988871bb,0xa58383db},
+{0xaffa1f4e,0x65a0d22e,0xe9392773,0x4b3b6ea8},
+{0x879b6826,0x0f2d90af,0x9c0faa68,0x23c50814},
+{0x16a8fa7f,0xd28e39db,0xe1bf1689,0x81141b58},
+{0x08f20f2e,0x5e7c0849,0xcf82126c,0x55d3f2dc},
+{0x29df49ad,0x6b7075b9,0x80c5d50e,0x9376d286},
+{0x61d7bfc9,0xc391104a,0x457a6f72,0xa4e39391},
+{0x8de80652,0x5792608d,0xf78d1f46,0x1b30848e},
+{0x6cfd4338,0x1ee527a3,0xc36d8800,0x4c3a3fa6},
+{0xfc20c838,0x5f905fe3,0x3262dad2,0x3f4d786c},
+{0xbac1bbd1,0xa9d88edf,0x2540bf26,0x7f7bb536},
+{0xb340a716,0x04477c62,0x8cbd399b,0x49ae3e82},
+{0xe5122fda,0x06f8a717,0x6a74fb7f,0x16dc278f},
+{0xdd97bb16,0x717bb119,0x1c532e28,0x9c60744c},
+{0x3822693b,0x4162c166,0x07d7cfd2,0xe0fd0dcb},
+{0xe7409a2c,0x63fdfae9,0x746cb10a,0x6bf0ad2b},
+{0xd465cd1a,0x5b05a503,0xd54d2a40,0x6f98eedc},
+{0xcf46323a,0xe866b318,0xed155930,0xe5bde5b2},
+{0xe3b07639,0x0b8d6324,0x760e29b3,0x70b0757e},
+{0x71afca08,0x0d27921c,0x19dfe2f1,0xf760a29c},
+{0x39846278,0x3e267cee,0x8212650a,0x1354830b},
+{0xeff59b41,0xd0b5c3fe,0xc1d4602f,0x1ad0a73f},
+{0xbe877473,0x1719120f,0x74ea6b4b,0x2c1f737f},
+{0x089a47bf,0x55a03027,0x05cd7451,0xec378f17},
+{0x309fea5d,0x5e501bc9,0xa7e66bd3,0x22119872},
+{0x2e2245c7,0xc95928d1,0x3cfe99b7,0x493ae7a1},
+{0x89034178,0x27a730e9,0xfcb8ac5c,0x08fc2f6d},
+{0x163f98de,0x97dba8a7,0x85ca93cb,0xeb5dc3e5},
+{0x063e1a1c,0xbf70e24c,0xfa44aff1,0xea79a794},
+{0x62fd1b79,0xabdbfb2c,0x294391ec,0x4e548903},
+{0x81f82bdf,0xc1e2212f,0xeb323e47,0x8a035ea9},
+{0x938f17f2,0xd7b4f4e3,0xa6524903,0xce90d4c7},
+{0xc2c3d170,0x4e92a96b,0x3dc642d6,0x7428a035},
+{0x42ffc9c6,0xe6956db6,0x3c5b5056,0xbe1dc1dd},
+{0xfdb57f6d,0xb473be55,0x77da9d50,0xfc4deaeb},
+{0xaf9410d4,0x7617347b,0xbc5c959a,0xde3aa1e5},
+{0x7af9bd37,0xf6ee13d9,0x0e878d33,0xad754b13},
+{0x61a1a037,0x5d60be5a,0x5318c92d,0x0d2defde},
+{0xdecd4ee1,0x1b3939a5,0x42c58f49,0xffcb5d9a},
+{0x4f38706e,0xbbff414a,0x1522130f,0x2fe1a225},
+{0x2ec120f9,0x56863c05,0x8dae9599,0x8cbf5dbd},
+{0xcb99e13d,0xbd111b43,0x2bfddfbd,0x9453c9d8},
+{0xb3131a0b,0x1b8ed229,0x698e033c,0x83753dde},
+{0x21f17fb0,0x92346c94,0xb8530322,0x8e804091},
+{0x5896fde5,0xd77f371c,0x355261a1,0x69aba8b4},
+{0x9d805551,0xf7d104c3,0xf3403eac,0xbef10cbd},
+{0xe203631e,0xd52a8eb3,0x99977810,0xa154635c},
+{0xb53d09dc,0x47282d39,0xa6b9bc46,0x5a41cbda},
+{0x8b42f8a6,0x54fb5062,0x98d98f2c,0x4048d568},
+{0x6b2bf36a,0xf410b33e,0x8ea5418d,0x52a57797},
+{0xc9229186,0xe31d6507,0x58b4743e,0x2e1713d2},
+{0xaa2f03cb,0x738073d9,0xf0cf1f6b,0x1107acbb},
+{0x1f9f0ad0,0x6768e414,0xd7491dc2,0x96edd0e2},
+{0xe3573f40,0x0e0e17ec,0xf20a8a3f,0x9b87cc8f},
+{0x0c0b0394,0xba487373,0x7ae81327,0xe8d96e96},
+{0xd030039d,0x3e749d93,0x5d8d4d0e,0xf15318e9},
+{0x868c16e8,0x88a83024,0x122c2ba1,0xf96dd833},
+{0x8721acf3,0x7bd8a9be,0x58bfae5c,0xa5e7fed7},
+{0x92a49adc,0x95f4060a,0x76e7e096,0xf352adec},
+{0x2345cb15,0x4a4fb7c2,0x228b9490,0x20a4cf00},
+{0x7b57e2b2,0x0f6c9c4e,0x45ee2dea,0x99f99fab},
+{0x7a4cf357,0x784f4592,0x91f103bd,0x238a8489},
+{0xa91b67db,0xe1adabff,0x70022b11,0xf982c541},
+{0x09d612af,0x15f64357,0x4de883fb,0x6169f8a8},
+{0x22f42165,0xf107c715,0xad84f19a,0xaaa5b394},
+{0xce988ac8,0x34d6e092,0xc81b1d7a,0xc2c0b4e2},
+{0xdc3ea10c,0x8b9f3b3e,0x45320d28,0x4bcab7fa},
+{0x7b7a73b3,0x6832cba1,0x84c9ccf5,0x1679377f},
+{0x3ea8a972,0x92bec59b,0x4250cb29,0xe1cec2b7},
+{0xa4b2f347,0xe0748dd3,0xd23b83d1,0xe74a5af6},
+{0x547fb502,0xf754ad91,0x24350364,0x15fe666c},
+{0xdd5d6c6b,0x061c403a,0x6c38ce6b,0xebaf2e4a},
+{0x8f923f07,0x1a414df0,0x009b4394,0x62afb2c5},
+{0x9569e4f9,0xed87c1d7,0x6331e5b0,0x18cb1f0b},
+{0x30919430,0x8a60b6cc,0xc862a0fb,0x821625ea},
+{0xda80a2d4,0xa76d27ad,0x8d09c4b1,0x1ad8f187},
+{0x043c2f3e,0x79345a4d,0xbe736946,0x7e91d31c},
+{0x507371f8,0x4413bbe9,0xd9b1b1e6,0x810ebfec},
+{0xb03133fe,0xbb3a2ed0,0xd0e672be,0x2ce8c128},
+{0xb0a7215c,0xc7f9727f,0x4d165329,0x2ca5fe24},
+{0x804cfc2c,0xa4a5ebd7,0xa998a8d8,0xc085faf4},
+{0x22f1e6ee,0xf21b641a,0x2be9b979,0xdadd02e4},
+{0xa4fb4025,0x175dfd91,0x7bb8d0bb,0x99ca1700},
+{0x1f958be3,0x8b4a81dd,0x7b0f3c55,0x6b5900c7},
+{0x2850ddee,0x482430dc,0x19c4e3fc,0x149326d4},
+{0x610f8f14,0xfb509efe,0x72660a7b,0xaf9b5c86},
+{0x41600abd,0xde1bba77,0x8aa48714,0x528d5b5c},
+{0xf77ea87f,0xee4bacbe,0x081b8a19,0xad4e3ac1},
+{0x08612899,0x3a80b5f4,0x52cf8a9b,0x66bbef0e},
+{0xf6a6cbf9,0xe95a98cb,0x48229a41,0xc29b1616},
+{0x38aa4210,0xf661366a,0x23fabb55,0xa98a077d},
+{0x7f62945c,0xc81629a5,0x85f18dd9,0x9ba7a22b},
+{0x3f122bb9,0x3f58df3c,0xaffad9d7,0x54e96057},
+{0x93156fd6,0xd3c8e163,0x695d5798,0xf9bfe0ad},
+{0x1e88d32f,0x3476812d,0xea5b5bbd,0x345ab38c},
+{0x7ed6ac4b,0xe7a02cdb,0xe1fc0196,0xabbd50f1},
+{0xe5c3b1c7,0xd50597dc,0xb373364d,0xcf9d612e},
+{0xb53982da,0xe44ce6dc,0xc1cf016a,0xd5b743e5},
+{0x848d5379,0x594cc3e5,0xec8cde6b,0x8b3b0a90},
+{0xafdf7a90,0xd6dd709e,0xa1e2cd85,0xb36883de},
+{0x5f38fb38,0x9ed4ef55,0xd931a44e,0x968f7c1e},
+{0xbd8340f0,0x45dc35bc,0x7dee4bee,0x6619f26a},
+{0x009443c0,0xbd75deff,0x1f67b14a,0xd72cd8d0},
+{0x4df2a323,0x36cc5cd2,0xfb31ff63,0x2b6cb70e},
+{0x5f00903c,0x7b4f16f8,0x3638f65b,0x08d1f343},
+{0xff140de1,0x975278c6,0x8c8c99c0,0xeee649d1},
+{0x99d07ff0,0x7c118702,0x003fbef3,0x866fc947},
+{0x200e93c9,0x0da381e7,0x192133a9,0xf7a68932},
+{0x1e19e29e,0x39ae8c0f,0xb9d35b74,0x7885c910},
+{0xbab75a0a,0x23e6588a,0x54d41722,0x9ff5a933},
+{0x445e3f24,0xa19c14f0,0x61b86fdf,0x66ba5cde},
+{0x9c87212f,0xc213ca35,0x8e628c29,0x1467b5ad},
+{0x50e2ea04,0xf5423dea,0xf0cda44f,0xe7f292a4},
+{0x03b3223b,0xcb9575f7,0xfceb53ac,0x5f4b8d44},
+{0xbf74eda8,0x787dfaa0,0x10f158b9,0x44dc2d7e},
+{0x1fe91a85,0x5e8f979b,0xed50a89c,0x92b652d1},
+{0x89d4883c,0xde28579b,0x9b6b7d66,0xa00cbc26},
+{0x548ecb0d,0xa8a8c49b,0x17719db6,0x302e7673},
+{0xe8d040ef,0x5431091a,0x883af6cd,0xf60d77c9},
+{0x2e88e4ae,0xeb4ddd4c,0xdf2c8a1c,0x49766a25},
+{0xa7f6df0e,0x6c24a6b1,0x463bbe9e,0x0383f419},
+{0x070da0df,0x1a13457f,0x4d46ccb3,0xdc5da545},
+{0x7dbc10d3,0xf0f6f6fa,0x11b20467,0xf1c57633},
+{0x5275c183,0xd1aa76ea,0x1ee695c3,0xeeb67943},
+{0x2bdbc34e,0x386f49d1,0xe331e3ba,0x4f0f91ac},
+{0x14bed861,0xbd18d697,0x02963076,0xddbc03b4},
+{0x39aec481,0x29748962,0xebb2989f,0xa0b873d2},
+{0x0202df24,0x2b36b9d5,0xe069f74b,0xae89a4c7},
+{0x8fbefc48,0xb68a6c2e,0x9c5fcd06,0x5fdc97bc},
+{0xede610bc,0xd1e0d1dd,0x7f7fec84,0x9fb297e0},
+{0xc6723f15,0xcc01ba4e,0x076c641e,0xee2cc9ef},
+{0x22e2b2cc,0xff9fb668,0xb002f1df,0xfbef9e6f},
+{0x6c8bde6d,0xc1cfdb1a,0xeffdbcdb,0xd74ea82d},
+{0x1f3ffa1d,0x5c07754f,0x44d4b8bc,0x56596d99},
+{0xcbb70edb,0xe55af523,0x1846a284,0x0cbf213c},
+{0xf8341166,0xd2c69100,0x70f4304a,0x0fbd0f25},
+{0x90800913,0x94d5e5ed,0xa62431e6,0xab8ad463},
+{0x164eadbb,0x79e26abc,0x416a7056,0x3d8a3921},
+{0x16061f80,0xa33b2975,0xb218851d,0x0d369d49},
+{0xac24d8c4,0x4fe97c8e,0xd09dd89e,0x56d03033},
+{0xce78ce65,0x1e161951,0x0d7405f9,0xeaef2b3b},
+{0xcab7fe13,0x480487fb,0xb0a886f2,0x27b7b925},
+{0x5e27d951,0x746f1313,0xd755c000,0x64d3d793},
+{0xe1fe9327,0xa3f984c5,0xbf1ce31e,0x7193e590},
+{0x248b08e1,0x779a5f02,0x0b77278f,0x8184ce7f},
+{0x08b866d3,0xee8515d3,0x075d381e,0xf890f9ef},
+{0x89a70dd2,0x19993506,0x3c6c8d22,0x27d74b52},
+{0x481a0e47,0xbf04a70f,0x9d7b25fc,0x10a05e73},
+{0x8f177f27,0x98e90f5c,0xe4725c4e,0xc5e4c4f6},
+{0xf261602b,0x70ec416b,0xdf26c965,0xd2e16c42},
+{0xa7d0f663,0xfe1f418d,0xbfd13549,0xa7eadf55},
+{0xcda4caf5,0xb00ad62a,0xcab58e7f,0x905c5a0b},
+{0x885c3809,0xbc088ea2,0x264398d4,0x2c6f88f3},
+{0x54d01c16,0x631a11cb,0xf8892267,0xfb5390d1},
+{0x36a23cdf,0xdaa2f9ba,0x76f7ad35,0x86a948ac},
+{0xf0405bab,0x048ea965,0x69b4bcef,0x2d41cea7},
+{0x2c3561cc,0x9de5633d,0xb3f9f2b2,0x90f0e610},
+{0x4eebddfe,0x39afd2ce,0xd45aa43d,0x940bf668},
+{0x79838fec,0x73d9fb07,0xc8f222da,0x6ac76ad4},
+{0x38d355f0,0x1f1cc653,0x9851e321,0xc03fdaff},
+{0x85dfe841,0xe2b7aa03,0x080e0a18,0x37a1b0f2},
+{0xa315ecf9,0xa746581d,0x05b3c66c,0xa9b6e4aa},
+{0x7ef4a582,0xea2bd629,0x82e42dbc,0xa15b8a38},
+{0xa3615d4a,0x3ea8f313,0xb6539584,0x6d523306},
+{0x1a7c85d2,0xc429859f,0x9dbdbd86,0x19830572},
+{0xdfd77bda,0x9b4c4876,0x2e18a4b1,0x1a27b66f},
+{0x59ab3712,0x68e173ce,0xc67b2c68,0xef155823},
+{0x2de46d99,0x21c21137,0xdf3c62a9,0x7f4ea769},
+{0xcc4136e6,0x69e15d06,0xfc4cf50f,0x4d3bfe8b},
+{0xbd3f0175,0x83eff59d,0x1c45d456,0xcc9530df},
+{0x8cd582d8,0xa6147f4c,0xd3f749d6,0xd0c19e53},
+{0xde01c733,0xb0796358,0x6294065d,0xc7761457},
+{0xbdae5087,0x76eb5294,0x0306327b,0x35a5283e},
+{0x93426b44,0x7a2278ac,0xb90b5f95,0xc08d5aaf},
+{0x7096d988,0x636eab87,0x94416c92,0x65621336},
+{0xe9468627,0x0891e6cd,0x35188a42,0x6ce8b12a},
+{0xd0a68588,0x7bf1403a,0xbf72d8f7,0xa12d5120},
+{0xa418663a,0x830c6326,0xfe00a86f,0x5932135b},
+{0x1d2ce956,0x95f9f5fd,0x2ef30d0e,0x3890c2c1},
+{0x5e98ce4a,0x69f1bbb0,0xd59d25e5,0x3f9f5c8d},
+{0xfe8fed92,0xa91d4c69,0x4919f42a,0x6774466d},
+{0x0fa149aa,0x852b931d,0x44e82356,0x210b28af},
+{0x083985e8,0x0085a625,0xff7a8bda,0x1984b3b9},
+{0x6d97bde7,0x7bbfd0ae,0xea7b36c5,0x4a0580b2},
+{0xbaae4f30,0xe1aa01c1,0x187eb9be,0x86111457},
+{0x307dd97a,0xd014e4de,0x951c1923,0x783a099c},
+{0xca7150de,0xdc0d51d6,0x4b4c0871,0x9f1088bb},
+{0xa6e2180d,0x930635d1,0x7a6057df,0x03a7c0b1},
+{0x7791c086,0xda5aa454,0x9a6e7ac2,0xed7279d0},
+{0xa2b8fb40,0xcdb48947,0xbd1c99c4,0xe728b4a3},
+{0x18cd2ffb,0xcd8c1ad9,0x51c9b2ed,0xb9c439d6},
+{0x64c6ffd0,0x0347766c,0xdc78263d,0x5be61d3f},
+{0xcff092ea,0xf311410a,0xe9e212d1,0xc08fd9cf},
+{0xdb5a3aee,0x9cef0126,0x0bccea65,0xb9534b67},
+{0x476d8ff6,0x4499938c,0xe7f59508,0x3570ab02},
+{0x77c1c2c6,0xaae01b5f,0xcd3cd74a,0x925fd46f},
+{0x1edf2d06,0x28f28308,0xb1f57d3a,0x73fa0a8a},
+{0xe95b317b,0xe8548938,0x1c0f57a2,0x2467a337},
+{0xf5569647,0xa53b9496,0xf8564c17,0xc99fa57b},
+{0xd09e2e97,0xfd93dbab,0xbe5df18d,0x2f407e27},
+{0x35a8cd56,0x96a4d06d,0xac3affbd,0xe17beffc},
+{0,0,0,0}
+};
+
+#define UDF_NUMBER_OF_KEYS 572
+UCHAR RegKeyName0[] =
+ "\x2b\x03\x01\x0c\x0b\x0d\x01\x03\x0b\x0c"
+ "\x89\x8e\x94\x81\x80\xdc\x88\x93\xde\x8e"
+ "\x8a\xde\xd9\x8a\x83\xcf\x89\x8e\xd4\xcc"
+ "\x88\x98\x8b\xd8\x95\x9b\xe3\xce\xd9\xcb"
+ "\x1f\x11\x02\x15\x09\x5f\x5f\x4d\x5f\x5f"
+ "\xc1\xc1\xb4\x83\x81\x94\xb7\xb6\xb0\x9f"
+ "\x82\xeb\xff\xe8\xd5\xd9\xdf\x8a\x93\x91"
+ "\xc5\xde\x9d\xd4\xcf\xd8\x9d\xf6\xce\xd9"
+ "\x4d\x03\x03\x01\x4c\x03\x01\x05\x02\x1e"
+ "\x94\x83\x81\xdf\x90\x82\x89\x82\x95\x9e"
+ ;
+
--- /dev/null
+/* MD5.H - header file for MD5C.C
+ * $FreeBSD: src/sys/sys/md5.h,v 1.16 2002/06/24 14:18:39 mux Exp $
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#ifndef _SYS_MD5_H_
+#define _SYS_MD5_H_
+/* MD5 context. */
+typedef struct UDF_MD5Context {
+ uint32 state[4]; /* state (ABCD) */
+ uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ unsigned char buffer[64]; /* input buffer */
+} UDF_MD5_CTX;
+
+#ifdef __cplusplus
+#define MD5_DECL extern "C"
+#else
+#define MD5_DECL extern
+#endif
+
+MD5_DECL
+void UDF_MD5Init (UDF_MD5_CTX *);
+
+MD5_DECL
+void UDF_MD5Update (UDF_MD5_CTX *, const unsigned char *, unsigned int);
+
+MD5_DECL
+void UDF_MD5Pad (UDF_MD5_CTX *);
+
+MD5_DECL
+void UDF_MD5Final (unsigned char [16], UDF_MD5_CTX *);
+
+MD5_DECL
+char * UDF_MD5End(UDF_MD5_CTX *, char *);
+
+typedef struct _UDF_MD5_DIGEST {
+ uint8 d[16];
+} UDF_MD5_DIGEST , *PUDF_MD5_DIGEST;
+
+/*char * MD5File(const char *, char *);
+char * MD5FileChunk(const char *, char *, off_t, off_t);
+char * MD5Data(const unsigned char *, unsigned int, char *);*/
+
+#endif /* _SYS_MD5_H_ */
--- /dev/null
+/*
+ * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD5 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ *
+ * This code is the same as the code published by RSA Inc. It has been
+ * edited for clarity and style only.
+ */
+
+/*
+ * This file should be kept in sync with src/lib/libmd/md5c.c
+ */
+//#include "md5.h"
+
+void UDF_MD5Transform(uint32 [4], const unsigned char [64]);
+
+/*
+ * Encodes input (uint32) into output (unsigned char). Assumes len is
+ * a multiple of 4.
+ */
+
+#define htole32(a) (a)
+#define le32dec(a) (*(a))
+
+void
+UDF_Encode (unsigned char *output, uint32 *input, unsigned int len)
+{
+ unsigned int i;
+ unsigned int *op = (unsigned int *)output;
+
+ for (i = 0; i < len / 4; i++)
+ op[i] = htole32(input[i]);
+}
+
+/*
+ * Decodes input (unsigned char) into output (uint32). Assumes len is
+ * a multiple of 4.
+ */
+
+void
+UDF_Decode (uint32 *output, const unsigned char *input, unsigned int len)
+{
+ unsigned int i;
+ const unsigned int *ip = (const unsigned int *)input;
+
+ for (i = 0; i < len / 4; i++)
+ output[i] = le32dec(&ip[i]);
+}
+
+static const unsigned char PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions. */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits. */
+#ifdef _X86_
+__declspec (naked)
+uint32
+__fastcall
+ROTATE_LEFT(
+ uint32 x, // ECX
+ uint32 n // EDX
+ )
+{
+ _asm {
+ push ecx
+ mov eax,ecx
+ mov ecx,edx
+ rol eax,cl
+ pop ecx
+ ret
+ }
+}
+#else // NO X86 optimization , use generic C/C++
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+#endif // _X86_
+
+/*
+ * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+ * Rotation is separate from addition to prevent recomputation.
+ */
+
+void
+FF(
+/* uint32 &a,
+ uint32 b,
+ uint32 c,
+ uint32 d,*/
+ uint32 a[4],
+ uint32 x,
+ uint32 s,
+ uint32 ac
+ )
+{
+ a[0] += F (a[1], a[2], a[3]) + (x) + (uint32)(ac);
+ a[0] = ROTATE_LEFT (a[0], (s));
+ a[0] += (a[1]);
+}
+
+void
+GG(
+/* uint32 &a,
+ uint32 b,
+ uint32 c,
+ uint32 d,*/
+ uint32 a[4],
+ uint32 x,
+ uint32 s,
+ uint32 ac
+ )
+{
+/* a += G ((b), (c), (d)) + (x) + (uint32)(ac);
+ a = ROTATE_LEFT ((a), (s));
+ a += (b);*/
+ a[0] += G (a[1], a[2], a[3]) + (x) + (uint32)(ac);
+ a[0] = ROTATE_LEFT (a[0], (s));
+ a[0] += (a[1]);
+}
+
+void
+HH(
+/* uint32 &a,
+ uint32 b,
+ uint32 c,
+ uint32 d,*/
+ uint32 a[4],
+ uint32 x,
+ uint32 s,
+ uint32 ac
+ )
+{
+/* a += H ((b), (c), (d)) + (x) + (uint32)(ac);
+ a = ROTATE_LEFT ((a), (s));
+ a += (b);*/
+ a[0] += H (a[1], a[2], a[3]) + (x) + (uint32)(ac);
+ a[0] = ROTATE_LEFT (a[0], (s));
+ a[0] += (a[1]);
+}
+
+void
+II(
+/* uint32 &a,
+ uint32 b,
+ uint32 c,
+ uint32 d,*/
+ uint32 a[4],
+ uint32 x,
+ uint32 s,
+ uint32 ac
+ )
+{
+/* a += I ((b), (c), (d)) + (x) + (uint32)(ac);
+ a = ROTATE_LEFT ((a), (s));
+ a += (b);*/
+ a[0] += I (a[1], a[2], a[3]) + (x) + (uint32)(ac);
+ a[0] = ROTATE_LEFT (a[0], (s));
+ a[0] += (a[1]);
+}
+
+#if 0 // NO X86 optimization , use generic C/C++
+
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (uint32)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (uint32)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (uint32)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (uint32)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#endif // _X86_
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context. */
+
+static const uint32 UDF_MD5Init_state[4] = {
+ 0x67452301,
+ 0xefcdab89,
+ 0x98badcfe,
+ 0x10325476
+ };
+
+void
+UDF_MD5Init (
+ UDF_MD5_CTX *context
+ )
+{
+
+ context->count[0] = context->count[1] = 0;
+
+ /* Load magic initialization constants. */
+#if 0
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+#endif
+ memcpy(context->state, UDF_MD5Init_state, sizeof(UDF_MD5Init_state));
+}
+
+/*
+ * MD5 block update operation. Continues an MD5 message-digest
+ * operation, processing another message block, and updating the
+ * context.
+ */
+
+void
+UDF_MD5Update (
+ UDF_MD5_CTX *context,
+ const unsigned char *input,
+ unsigned int inputLen
+ )
+{
+ unsigned int i, index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+ /* Update number of bits */
+ if ((context->count[0] += ((uint32)inputLen << 3))
+ < ((uint32)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((uint32)inputLen >> 29);
+
+ partLen = 64 - index;
+
+ /* Transform as many times as possible. */
+ if (inputLen >= partLen) {
+ memcpy((void *)&context->buffer[index], (const void *)input,
+ partLen);
+ UDF_MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ UDF_MD5Transform (context->state, &input[i]);
+
+ index = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ memcpy ((void *)&context->buffer[index], (const void *)&input[i],
+ inputLen-i);
+}
+
+/*
+ * MD5 padding. Adds padding followed by original length.
+ */
+
+void
+UDF_MD5Pad (
+ UDF_MD5_CTX *context
+ )
+{
+ unsigned char bits[8];
+ unsigned int index, padLen;
+
+ /* Save number of bits */
+ UDF_Encode (bits, context->count, 8);
+
+ /* Pad out to 56 mod 64. */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ UDF_MD5Update (context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ UDF_MD5Update (context, bits, 8);
+}
+
+/*
+ * MD5 finalization. Ends an MD5 message-digest operation, writing the
+ * the message digest and zeroizing the context.
+ */
+
+void
+UDF_MD5Final (
+ unsigned char digest[16],
+ UDF_MD5_CTX *context
+ )
+{
+ /* Do padding. */
+ UDF_MD5Pad (context);
+
+ /* Store state in digest */
+ UDF_Encode (digest, context->state, 16);
+
+ /* Zeroize sensitive information. */
+ memset ((void *)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block. */
+
+static const uint32 UDF_MD5Transform_dwords[4][16] = {
+ {
+ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821
+ },
+ {
+ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+ 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
+ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a
+ },
+ {
+ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
+ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665
+ },
+ {
+ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+ }
+};
+
+static const uint32 UDF_MD5Transform_idx[4][16] = {
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15
+ },
+ {
+ 1, 6, 11, 0, 5, 10, 15, 4,
+ 9, 14, 3, 8, 13, 2, 7, 12
+ },
+ {
+ 5, 8, 11, 14, 1, 4, 7, 10,
+ 13, 0, 3, 6, 9, 12, 15, 2
+ },
+ {
+ 0, 7, 14, 5, 12, 3, 10, 1,
+ 8, 15, 6, 13, 4, 11, 2, 9
+ }
+};
+
+static const uint32 UDF_MD5Transform_Sxx[4][4] = {
+ { 7 , 12, 17, 22 },
+ { 5 , 9 , 14, 20 },
+ { 4 , 11, 16, 23 },
+ { 6 , 10, 15, 21 }
+};
+
+void
+UDF_MD5Rotate (
+ uint32 state[4]
+ )
+{
+ uint32 a = state[3];
+ /* Load magic initialization constants. */
+#if 0
+ state[3] = state[0];
+ state[2] = state[3];
+ state[1] = state[4];
+#endif
+ memmove(&state[1], &state[0], sizeof(state[0])*3);
+ state[0] = a;
+}
+
+typedef void (*P_MD5_XX)
+ (
+/* uint32 &a,
+ uint32 b,
+ uint32 c,
+ uint32 d,*/
+ uint32 a[4],
+ uint32 x,
+ uint32 s,
+ uint32 ac
+ );
+
+void
+UDF_MD5Transform (
+ uint32 state[4],
+ const unsigned char block[64]
+ )
+{
+// uint32 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+ uint32 x[16];
+ uint32 state1[4];
+ uint32 i, j, k;
+
+ P_MD5_XX MD5_func[] = {FF, GG, HH, II};
+
+ memcpy(state1, state, sizeof(state1));
+
+ UDF_Decode (x, block, 64);
+
+ for(j=0; j<4; j++) {
+ for(i=0; i<16;) {
+ for(k=0; k<4; k++, i++) {
+ MD5_func[j] (state1, x[UDF_MD5Transform_idx[j][i]], UDF_MD5Transform_Sxx[j][k], UDF_MD5Transform_dwords[j][i]); /* 1 */
+ UDF_MD5Rotate(state1);
+ }
+ }
+ }
+#if 0
+ for(i=0; i<16;) {
+ #define j 0
+ for(k=0; k<4; k++, i++) {
+ FF (state1, x[UDF_MD5Transform_idx[j][i]], UDF_MD5Transform_Sxx[j][k], UDF_MD5Transform_dwords[j][i]); /* 1 */
+ UDF_MD5Rotate(state1);
+ }
+ #undef j
+ }
+ for(i=0; i<16;) {
+ #define j 1
+ for(k=0; k<4; k++, i++) {
+ GG (state1, x[UDF_MD5Transform_idx[j][i]], UDF_MD5Transform_Sxx[j][k], UDF_MD5Transform_dwords[j][i]); /* 1 */
+ UDF_MD5Rotate(state1);
+ }
+ #undef j
+ }
+ for(i=0; i<16;) {
+ #define j 2
+ for(k=0; k<4; k++, i++) {
+ HH (state1, x[UDF_MD5Transform_idx[j][i]], UDF_MD5Transform_Sxx[j][k], UDF_MD5Transform_dwords[j][i]); /* 1 */
+ UDF_MD5Rotate(state1);
+ }
+ #undef j
+ }
+ for(i=0; i<16;) {
+ #define j 3
+ for(k=0; k<4; k++, i++) {
+ II (state1, x[UDF_MD5Transform_idx[j][i]], UDF_MD5Transform_Sxx[j][k], UDF_MD5Transform_dwords[j][i]); /* 1 */
+ UDF_MD5Rotate(state1);
+ }
+ #undef j
+ }
+#endif //0
+
+#if 0
+ /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+#endif //0
+
+ state[0] += state1[0];
+ state[1] += state1[1];
+ state[2] += state1[2];
+ state[3] += state1[3];
+
+ /* Zeroize sensitive information. */
+ memset ((void *)x, 0, sizeof (x));
+}
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifdef MY_USE_INTERNAL_MEMMANAGER
+
+#ifdef _X86_
+
+__inline VOID DbgTouch(IN PVOID addr)
+{
+ __asm {
+ mov eax,addr
+ mov al,[byte ptr eax]
+ }
+}
+
+#else // NO X86 optimization , use generic C/C++
+
+__inline VOID DbgTouch(IN PVOID addr)
+{
+ UCHAR a = ((PUCHAR)addr)[0];
+}
+
+#endif // _X86_
+
+//MEM_ALLOC_DESC Allocs[MY_HEAP_MAX_BLOCKS];
+
+MEM_FRAME_ALLOC_DESC FrameList[MY_HEAP_MAX_FRAMES];
+#ifdef MEM_LOCK_BY_SPINLOCK
+KSPIN_LOCK FrameLock;
+KIRQL oldIrql;
+#define LockMemoryManager() KeAcquireSpinLock(&FrameLock, &oldIrql)
+#define UnlockMemoryManager() KeReleaseSpinLock(&FrameLock, oldIrql)
+__inline
+NTSTATUS
+InitLockMemoryManager() {
+ KeInitializeSpinLock(&FrameLock);
+ return STATUS_SUCCESS;
+}
+#define DeinitLockMemoryManager() {NOTHING;}
+#else //MEM_LOCK_BY_SPINLOCK
+ERESOURCE FrameLock;
+#define LockMemoryManager() ExAcquireResourceExclusiveLite(&FrameLock, TRUE)
+#define UnlockMemoryManager() ExReleaseResourceForThreadLite(&FrameLock, ExGetCurrentResourceThread())
+#define InitLockMemoryManager() ExInitializeResourceLite(&FrameLock)
+#define DeinitLockMemoryManager() ExDeleteResourceLite(&FrameLock)
+#endif //MEM_LOCK_BY_SPINLOCK
+ULONG FrameCount;
+ULONG LastFrame;
+BOOLEAN MyMemInitialized = FALSE;
+
+#define MyAllocIsFrameFree(FrameList, i) \
+ (!(FrameList[i].LastUsed || FrameList[i].FirstFree))
+
+#ifdef UDF_DBG
+ULONG MemTotalAllocated;
+PCHAR BreakAddr;
+
+VOID
+MyAllocDumpDescr(
+ PMEM_ALLOC_DESC Allocs,
+ ULONG i
+ )
+{
+ BOOLEAN Used;
+
+ Used = (Allocs[i].Len & MY_HEAP_FLAG_USED) ? TRUE : FALSE;
+ KdPrint(("block %x \t%s addr %x len %x \t", i, Used ? "used" : "free", Allocs[i].Addr, (Allocs[i].Len) & MY_HEAP_FLAG_LEN_MASK));
+#ifdef MY_HEAP_TRACK_OWNERS
+ KdPrint(("src %x \t line %d \t", Allocs[i].Src, Allocs[i].Line));
+#endif
+#ifdef MY_HEAP_TRACK_REF
+ KdPrint(("%s%s", Used ? " " : "-", Allocs[i].Tag ? Allocs[i].Tag : ""));
+#endif
+ KdPrint(("\n"));
+}
+
+//#define CHECK_ALLOC_FRAMES
+
+#define DUMP_MEM_FRAMES
+
+#ifdef DUMP_MEM_FRAMES
+ULONG MyDumpMem = FALSE;
+#endif //DUMP_MEM_FRAMES
+
+#define DUMP_MEM_FRAMES2
+
+//#ifdef CHECK_ALLOC_FRAMES
+VOID
+MyAllocDumpFrame(
+ ULONG Frame
+ )
+{
+ ULONG i;
+ PMEM_ALLOC_DESC Allocs;
+ Allocs = FrameList[Frame].Frame;
+ ULONG k=0;
+ BOOLEAN Used;
+#ifdef DUMP_MEM_FRAMES
+ if(!MyDumpMem)
+#endif //DUMP_MEM_FRAMES
+ return;
+
+ KdPrint(("Dumping frame %x\n",Frame));
+ KdPrint(("FirstFree %x LastUsed %x ", FrameList[Frame].FirstFree, FrameList[Frame].LastUsed));
+ KdPrint(("Type %x\n", FrameList[Frame].Type));
+ if(Allocs) {
+ for(i=0;i< (MY_HEAP_MAX_BLOCKS/*-1*/);i++) {
+ Used = (Allocs[i].Len & MY_HEAP_FLAG_USED) ? TRUE : FALSE;
+ KdPrint(("block %x \t%s addr %x len %x \t", i, Used ? "used" : "free", Allocs[i].Addr, (Allocs[i].Len) & MY_HEAP_FLAG_LEN_MASK));
+#ifdef MY_HEAP_TRACK_OWNERS
+ KdPrint(("src %x \t line %d \t", Allocs[i].Src, Allocs[i].Line));
+#endif
+#ifdef MY_HEAP_TRACK_REF
+ KdPrint(("%s%s", Used ? " " : "-", Allocs[i].Tag ? Allocs[i].Tag : ""));
+#endif
+ KdPrint(("\n"));
+ if(!(Allocs[i].Len) && !(Allocs[i].Addr)) {
+ break;
+ }
+ if(Allocs[i].Len & MY_HEAP_FLAG_USED)
+ k += ((Allocs[i].Len) & MY_HEAP_FLAG_LEN_MASK);
+ }
+ }
+ KdPrint((" Wasted %x bytes from %x\n", MY_HEAP_FRAME_SIZE - k, MY_HEAP_FRAME_SIZE));
+} // end MyAllocDumpFrame()
+
+VOID
+MyAllocDumpFrames(
+ VOID
+ )
+{
+ ULONG i;
+
+ for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
+ if(FrameList[i].Frame) {
+ MyAllocDumpFrame(i);
+ }
+ }
+
+ KdPrint(("\n"));
+
+ for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
+ if(FrameList[i].Frame) {
+ KdPrint(("Addr %x ", FrameList[i].Frame));
+ KdPrint(("Type %x\n" , FrameList[i].Type));
+ }
+ }
+
+} // end MyAllocDumpFrame()
+
+VOID
+MyAllocCheck(
+ ULONG Frame
+ )
+{
+ ULONG i, j;
+ PMEM_ALLOC_DESC Allocs;
+ Allocs = FrameList[Frame].Frame;
+ ULONG len, addr;
+
+ for(i=0;i< (MY_HEAP_MAX_BLOCKS-1);i++) {
+ len = (Allocs[i].Len & MY_HEAP_FLAG_LEN_MASK);
+ addr = Allocs[i].Addr;
+ if( len != (Allocs[i+1].Addr - addr) ) {
+ if(Allocs[i+1].Addr) {
+ KdPrint(("ERROR! Memory block aliasing\n"));
+ KdPrint(("block %x, frame %x\n", i, Frame));
+ KdPrint(("block descriptor %x\n", &(Allocs[i]) ));
+ BrutePoint();
+ MyAllocDumpFrame(Frame);
+ }
+ }
+#ifdef MY_HEAP_CHECK_BOUNDS
+ if(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) != 0xBAADF00D) {
+ MyAllocDumpDescr(Allocs, i);
+ }
+#endif //MY_HEAP_CHECK_BOUNDS
+ }
+} // end MyAllocCheck()
+
+//#endif //CHECK_ALLOC_FRAMES
+#else
+
+#define MyAllocDumpFrame(a) {}
+#define MyAllocCheck(a) {}
+#define MyAllocDumpFrames() {}
+
+#endif // UDF_DBG
+
+PCHAR
+#ifndef MY_HEAP_TRACK_OWNERS
+__fastcall
+#endif
+MyAllocatePoolInFrame(
+ ULONG Frame,
+ ULONG size
+#ifdef MY_HEAP_TRACK_OWNERS
+ ,USHORT Src,
+ USHORT Line
+#endif
+#ifdef MY_HEAP_TRACK_REF
+ ,PCHAR Tag
+#endif //MY_HEAP_TRACK_REF
+ )
+{
+ ULONG addr;
+ ULONG i;
+ ULONG min_len;
+ ULONG best_i;
+ PMEM_ALLOC_DESC Allocs;
+ PMEM_ALLOC_DESC Allocs0;
+ ULONG LastUsed, FirstFree;
+ ULONG l;
+
+#ifdef CHECK_ALLOC_FRAMES
+ MyAllocCheck(Frame);
+#endif
+
+ if(!size) return NULL;
+#ifdef MY_HEAP_CHECK_BOUNDS
+ size+=MY_HEAP_CHECK_BOUNDS_BSZ;
+#endif
+
+/* if(size == 0x70) {
+ BrutePoint();
+ }*/
+ // lock frame
+ Allocs0 = FrameList[Frame].Frame;
+ if(!Allocs0) return NULL;
+ best_i = MY_HEAP_MAX_BLOCKS;
+ min_len = 0;
+ LastUsed = FrameList[Frame].LastUsed;
+ FirstFree = FrameList[Frame].FirstFree;
+
+ if(LastUsed >= (MY_HEAP_MAX_BLOCKS-1))
+ return NULL;
+
+ for(i=FirstFree, Allocs = &(Allocs0[i]);i<=LastUsed;i++, Allocs++) {
+ if( !((l = Allocs->Len) & MY_HEAP_FLAG_USED) &&
+ ((l &= MY_HEAP_FLAG_LEN_MASK) >= size) ) {
+ // check if minimal
+ // check for first occurence
+ if(l < min_len || !min_len) {
+ min_len = l;
+ best_i = i;
+ }
+ if(l == size)
+ break;
+ }
+ }
+ // not enough resources
+ if(best_i >= MY_HEAP_MAX_BLOCKS) return NULL;
+ // mark as used
+ Allocs = Allocs0+best_i;
+ addr = Allocs->Addr;
+ // create entry for unallocated tail
+ if(Allocs->Len != size) { // this element is always FREE
+ if(Allocs[1].Len) {
+ if(Allocs0[MY_HEAP_MAX_BLOCKS-1].Len) return NULL;
+/* for(i=MY_HEAP_MAX_BLOCKS-1;i>best_i;i--) {
+ Allocs[i] = Allocs[i-1];
+ }*/
+ RtlMoveMemory(&(Allocs[1]), &(Allocs[0]), (LastUsed-best_i+1)*sizeof(MEM_ALLOC_DESC));
+ }
+ Allocs[1].Addr = Allocs->Addr + size;
+ if(Allocs[1].Len) {
+ Allocs[1].Len -= size;
+ } else {
+ Allocs[1].Len = MY_HEAP_FRAME_SIZE - (addr - Allocs0[0].Addr) - size;
+ }
+// Allocs[best_i+1].Used = FALSE; // this had been done by prev. ops.
+ FrameList[Frame].LastUsed++;
+ }
+ // update FirstFree pointer
+ if(FirstFree == best_i) {
+ for(i=best_i+1, Allocs++; (i<=LastUsed) && (Allocs->Len & MY_HEAP_FLAG_USED);i++, Allocs++) {
+ // do nothing but scan
+ }
+ FrameList[Frame].FirstFree = i;
+ Allocs = Allocs0+best_i;
+ }
+ Allocs->Len = size | MY_HEAP_FLAG_USED;
+#ifdef MY_HEAP_TRACK_OWNERS
+ Allocs->Src = Src;
+ Allocs->Line = Line;
+#endif
+#ifdef MY_HEAP_TRACK_REF
+ Allocs->Tag = Tag;
+#endif //MY_HEAP_TRACK_REF
+
+// KdPrint(( "Mem: Allocated %x at addr %x\n", size, (ULONG)addr ));
+ // this will set IntegrityTag to zero
+ *((PULONG)addr) = 0x00000000;
+#ifdef MY_HEAP_CHECK_BOUNDS
+ for(i=0; i<MY_HEAP_CHECK_BOUNDS_SZ; i++) {
+ *((PULONG)(addr+size+(i*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) = 0xBAADF00D;
+ }
+#endif //MY_HEAP_CHECK_BOUNDS
+
+#ifdef UDF_DBG
+ MemTotalAllocated += size;
+#endif
+ return (PCHAR)addr;
+} // end MyAllocatePoolInFrame()
+
+LONG
+__fastcall
+MyFindMemDescByAddr(
+ ULONG Frame,
+ PCHAR addr
+ )
+{
+ ULONG i;
+ ULONG left;
+ ULONG right;
+ PMEM_ALLOC_DESC Allocs;
+
+ Allocs = FrameList[Frame].Frame;
+// i = FrameList[Frame].LastUsed >> 1;
+// KdPrint(("Mem: Freeing %x\n", (ULONG)addr)); DEADDA7A
+// for(i=0;i<MY_HEAP_MAX_BLOCKS;i++) {
+ left = 0;
+ right = FrameList[Frame].LastUsed;
+ if(!right && FrameList[Frame].FirstFree)
+ right = 1;
+ while(left != right) {
+ i = (right + left) >> 1;
+ if( (Allocs[i].Len & MY_HEAP_FLAG_USED) && (Allocs[i].Addr == (ULONG)addr) ) {
+FIF_Found:
+ return i;
+ }
+ if(right - left == 1) {
+ if( (Allocs[i+1].Len & MY_HEAP_FLAG_USED) && (Allocs[i+1].Addr == (ULONG)addr) ) {
+ i++;
+ goto FIF_Found;
+ }
+ break;
+ }
+ if(Allocs[i].Addr && (Allocs[i].Addr < (ULONG)addr)) {
+ left = i;
+ } else {
+ right = i;
+ }
+ }
+ return -1;
+} // end MyFindMemDescByAddr()
+
+VOID
+__fastcall
+MyFreePoolInFrame(
+ ULONG Frame,
+ PCHAR addr
+ )
+{
+ LONG i, j;
+ ULONG pc;
+ ULONG len, len2;
+ PMEM_ALLOC_DESC Allocs;
+
+ Allocs = FrameList[Frame].Frame;
+ pc = 0;
+ i = MyFindMemDescByAddr(Frame, addr);
+ if(i < 0) {
+ KdPrint(("Mem: <<<*** WARNING ***>>> Double deallocation at %x !!! ;( \n", addr));
+ MyAllocDumpFrame(Frame);
+ BrutePoint();
+ return;
+ }
+ Allocs[i].Len &= ~MY_HEAP_FLAG_USED;
+ len = Allocs[i].Len; // USED bit is already cleared
+
+#ifdef MY_HEAP_CHECK_BOUNDS
+ for(j=0; j<MY_HEAP_CHECK_BOUNDS_SZ; j++) {
+ ASSERT(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) == 0xBAADF00D);
+ if(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) != 0xBAADF00D) {
+ MyAllocDumpDescr(Allocs, i);
+ }
+ }
+#endif //MY_HEAP_CHECK_BOUNDS
+
+#ifdef UDF_DBG
+ // this is a marker of deallocated blocks
+ // some structures have DWORD IntegrityTag as a first member
+ // so, if IntegrityTag is equal to 0xDEADDA7A we shall return
+ // a <<<*** BIG ERROR MESSAGE ***>>> when somebody try to use it
+ *((PULONG)addr) = 0xDEADDA7A;
+ MemTotalAllocated -= len;
+#endif
+ if((i<MY_HEAP_MAX_BLOCKS-1) && !((len2 = Allocs[i+1].Len) & MY_HEAP_FLAG_USED)) {
+ // pack up
+ if((len2 &= MY_HEAP_FLAG_LEN_MASK)) {
+ len += len2;
+ } else {
+ len = MY_HEAP_FRAME_SIZE - (Allocs[i].Addr - Allocs[0].Addr);
+ }
+ pc++;
+ }
+ if((i>0) && !((len2 = Allocs[i-1].Len) & MY_HEAP_FLAG_USED)) {
+ // pack down
+ len += (len2 & MY_HEAP_FLAG_LEN_MASK);
+ pc++;
+ i--;
+ }
+ if(pc) {
+ // pack
+
+ Allocs[i+pc].Addr = Allocs[i].Addr;
+ Allocs[i+pc].Len = len;
+/* for(;i<MY_HEAP_MAX_BLOCKS-pc;i++) {
+ Allocs[i] = Allocs[i+pc];
+ }*/
+ RtlMoveMemory(&(Allocs[i]), &(Allocs[i+pc]), (MY_HEAP_MAX_BLOCKS-pc-i)*sizeof(MEM_ALLOC_DESC) );
+/* for(i=MY_HEAP_MAX_BLOCKS-pc;i<MY_HEAP_MAX_BLOCKS;i++) {
+ Allocs[i].Addr =
+ Allocs[i].Len =
+ Allocs[i].Used = 0;
+ }*/
+ RtlZeroMemory(&(Allocs[MY_HEAP_MAX_BLOCKS-pc]), pc*sizeof(MEM_ALLOC_DESC));
+ }
+ if(FrameList[Frame].FirstFree > (ULONG)i)
+ FrameList[Frame].FirstFree = (ULONG)i;
+ //ASSERT(FrameList[Frame].LastUsed >= pc);
+ if(FrameList[Frame].LastUsed < pc) {
+ FrameList[Frame].LastUsed = 0;
+ } else {
+ FrameList[Frame].LastUsed -= pc;
+ }
+ return;
+} // end MyFreePoolInFrame()
+
+BOOLEAN
+__fastcall
+MyResizePoolInFrame(
+ ULONG Frame,
+ PCHAR addr,
+ ULONG new_len
+#ifdef MY_HEAP_TRACK_REF
+ ,PCHAR* Tag
+#endif //MY_HEAP_TRACK_REF
+ )
+{
+ LONG i, j;
+ ULONG len, len2;
+ PMEM_ALLOC_DESC Allocs;
+
+ if(FrameList[Frame].LastUsed >= (MY_HEAP_MAX_BLOCKS-1))
+ return FALSE;
+ Allocs = FrameList[Frame].Frame;
+ i = MyFindMemDescByAddr(Frame, addr);
+ if(i < 0) {
+ KdPrint(("Mem: <<<*** WARNING ***>>> Double deallocation at %x !!! ;( \n", addr));
+ MyAllocDumpFrame(Frame);
+ BrutePoint();
+ return FALSE;
+ }
+ if(i>=(MY_HEAP_MAX_BLOCKS-2))
+ return FALSE;
+
+#ifdef MY_HEAP_TRACK_REF
+ *Tag = Allocs[i].Tag;
+#endif //MY_HEAP_TRACK_REF
+
+ len = (Allocs[i].Len & MY_HEAP_FLAG_LEN_MASK);
+
+#ifdef MY_HEAP_CHECK_BOUNDS
+ new_len += MY_HEAP_CHECK_BOUNDS_BSZ;
+ for(j=0; j<MY_HEAP_CHECK_BOUNDS_SZ; j++) {
+ ASSERT(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) == 0xBAADF00D);
+ if(*((PULONG)(addr+len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) != 0xBAADF00D) {
+ MyAllocDumpDescr(Allocs, i);
+ }
+ }
+#endif //MY_HEAP_CHECK_BOUNDS
+
+ if(new_len > len ) {
+ if(Allocs[i+1].Len & MY_HEAP_FLAG_USED)
+ return FALSE;
+ if(len + (Allocs[i+1].Len & MY_HEAP_FLAG_LEN_MASK) < new_len)
+ return FALSE;
+ Allocs[i].Len += (len2 = (new_len - len));
+ Allocs[i+1].Len -= len2;
+ Allocs[i+1].Addr += len2;
+
+#ifdef MY_HEAP_CHECK_BOUNDS
+ for(j=0; j<MY_HEAP_CHECK_BOUNDS_SZ; j++) {
+ *((PULONG)(addr+new_len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) = 0xBAADF00D;
+ }
+#endif //MY_HEAP_CHECK_BOUNDS
+
+ if(!Allocs[i+1].Len) {
+ i++;
+ RtlMoveMemory(&(Allocs[i]), &(Allocs[i+1]), (MY_HEAP_MAX_BLOCKS-1-i)*sizeof(MEM_ALLOC_DESC) );
+ RtlZeroMemory(&(Allocs[MY_HEAP_MAX_BLOCKS-1]), sizeof(MEM_ALLOC_DESC));
+ if((ULONG)i<FrameList[Frame].LastUsed)
+ FrameList[Frame].LastUsed--;
+ if(FrameList[Frame].FirstFree == (ULONG)i) {
+ for(;i<MY_HEAP_MAX_BLOCKS;i++) {
+ if(!(Allocs[i].Len & MY_HEAP_FLAG_USED))
+ break;
+ }
+ FrameList[Frame].FirstFree = i;
+ }
+ }
+#ifdef UDF_DBG
+ MemTotalAllocated += len;
+#endif
+ } else {
+
+ len2 = len - new_len;
+ if(!len2) return TRUE;
+
+#ifdef MY_HEAP_CHECK_BOUNDS
+ for(j=0; j<MY_HEAP_CHECK_BOUNDS_SZ; j++) {
+ *((PULONG)(addr+new_len+(j*sizeof(ULONG))-MY_HEAP_CHECK_BOUNDS_BSZ)) = 0xBAADF00D;
+ }
+#endif //MY_HEAP_CHECK_BOUNDS
+
+ Allocs[i].Len -= len2;
+ if(Allocs[i+1].Len & MY_HEAP_FLAG_USED) {
+ i++;
+ RtlMoveMemory(&(Allocs[i+1]), &(Allocs[i]), (MY_HEAP_MAX_BLOCKS-i-1)*sizeof(MEM_ALLOC_DESC) );
+
+ Allocs[i].Len = len2;
+ Allocs[i].Addr = Allocs[i-1].Addr + new_len;
+
+ if(FrameList[Frame].FirstFree > (ULONG)i)
+ FrameList[Frame].FirstFree = i;
+ FrameList[Frame].LastUsed++;
+
+ } else {
+ Allocs[i+1].Len += len2;
+ Allocs[i+1].Addr -= len2;
+ }
+#ifdef UDF_DBG
+ MemTotalAllocated -= len2;
+#endif
+ }
+
+ return TRUE;
+} // end MyResizePoolInFrame()
+
+VOID
+__fastcall
+MyAllocInitFrame(
+ ULONG Type,
+ ULONG Frame
+ )
+{
+ PMEM_ALLOC_DESC Allocs;
+
+ Allocs = (PMEM_ALLOC_DESC)DbgAllocatePool(NonPagedPool, sizeof(MEM_ALLOC_DESC)*(MY_HEAP_MAX_BLOCKS+1));
+ if(!Allocs) {
+ KdPrint(("Insufficient resources to allocate frame descriptor\n"));
+ FrameList[Frame].Frame = NULL;
+ MyAllocDumpFrames();
+ BrutePoint();
+ return;
+ }
+ RtlZeroMemory(Allocs, sizeof(MEM_ALLOC_DESC)*(MY_HEAP_MAX_BLOCKS+1));
+ // alloc heap
+ Allocs[0].Addr = (ULONG)DbgAllocatePool((POOL_TYPE)Type, MY_HEAP_FRAME_SIZE);
+ if(!Allocs[0].Addr) {
+ KdPrint(("Insufficient resources to allocate frame\n"));
+ DbgFreePool(Allocs);
+ FrameList[Frame].Frame = NULL;
+ MyAllocDumpFrames();
+ BrutePoint();
+ return;
+ }
+ Allocs[0].Len = MY_HEAP_FRAME_SIZE;
+// Allocs[0].Used = FALSE;
+ FrameList[Frame].Frame = Allocs;
+ FrameList[Frame].LastUsed =
+ FrameList[Frame].FirstFree = 0;
+ FrameList[Frame].Type = Type;
+ FrameCount++;
+ if(LastFrame < Frame)
+ LastFrame = Frame;
+} // end MyAllocInitFrame()
+
+VOID
+__fastcall
+MyAllocFreeFrame(
+ ULONG Frame
+ )
+{
+ // check if already deinitialized
+ if(!FrameList[Frame].Frame) {
+ BrutePoint();
+ return;
+ }
+ DbgFreePool((PVOID)(FrameList[Frame].Frame)[0].Addr);
+ DbgFreePool((PVOID)(FrameList[Frame].Frame));
+ FrameList[Frame].Frame = NULL;
+ FrameCount--;
+ if(LastFrame == Frame) {
+ LONG i;
+ for(i=LastFrame; i>0; i--) {
+ if(FrameList[i].Frame)
+ break;
+ }
+ LastFrame = i;
+ }
+} // end MyAllocFreeFrame()
+
+PCHAR
+#ifndef MY_HEAP_TRACK_OWNERS
+__fastcall
+#endif
+MyAllocatePool(
+ ULONG type,
+ ULONG size
+#ifdef MY_HEAP_TRACK_OWNERS
+ ,USHORT Src,
+ USHORT Line
+#endif
+#ifdef MY_HEAP_TRACK_REF
+ ,PCHAR Tag
+#endif //MY_HEAP_TRACK_REF
+ )
+{
+ ULONG i;
+ ULONG addr;
+
+// KdPrint(("MemFrames: %x\n",FrameCount));
+
+ if(!size || (size > MY_HEAP_FRAME_SIZE)) return NULL;
+
+#ifdef DUMP_MEM_FRAMES2
+ if(MyDumpMem)
+ MyAllocDumpFrames();
+#endif
+
+ LockMemoryManager();
+ for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
+ if( FrameList[i].Frame &&
+ (FrameList[i].Type == type) &&
+ (addr = (ULONG)MyAllocatePoolInFrame(i,size
+#ifdef MY_HEAP_TRACK_OWNERS
+ ,Src,Line
+#endif
+#ifdef MY_HEAP_TRACK_REF
+ ,Tag
+#endif //MY_HEAP_TRACK_REF
+ )) ) {
+
+#ifdef UDF_DBG
+// if(addr >= (ULONG)BreakAddr && addr < sizeof(UDF_FILE_INFO) + (ULONG)BreakAddr) {
+// if(addr<=(ULONG)BreakAddr && addr+sizeof(UDF_FILE_INFO) > (ULONG)BreakAddr) {
+// KdPrint(("ERROR !!! Allocating in examined block\n"));
+// KdPrint(("addr %x\n", addr));
+// MyAllocDumpFrame(i);
+// BrutePoint();
+// }
+#endif //UDF_DBG
+
+ UnlockMemoryManager();
+ DbgTouch((PVOID)addr);
+ return (PCHAR)addr;
+ }
+ }
+#ifdef DUMP_MEM_FRAMES2
+ MyAllocDumpFrames();
+#endif
+ addr = 0;
+ for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
+// MyAllocDumpFrame(i);
+ if(!(FrameList[i].Frame)) {
+ MyAllocInitFrame(type, i);
+ if(FrameList[i].Frame &&
+ (addr = (ULONG)MyAllocatePoolInFrame(i,size
+#ifdef MY_HEAP_TRACK_OWNERS
+ ,Src,Line
+#endif
+#ifdef MY_HEAP_TRACK_REF
+ ,Tag
+#endif //MY_HEAP_TRACK_REF
+ )) ) {
+
+#ifdef UDF_DBG
+// if(addr >= (ULONG)BreakAddr && addr < sizeof(UDF_FILE_INFO) + (ULONG)BreakAddr) {
+// if(addr<=(ULONG)BreakAddr && addr+sizeof(UDF_FILE_INFO) > (ULONG)BreakAddr) {
+// KdPrint(("ERROR !!! Allocating in examined block\n"));
+// KdPrint(("addr %x\n", addr));
+// MyAllocDumpFrame(i);
+// BrutePoint();
+// }
+// } else {
+// addr = 0;
+#endif //UDF_DBG
+ }
+#ifdef DUMP_MEM_FRAMES2
+ MyAllocDumpFrames();
+#endif
+ break;
+ }
+ }
+ UnlockMemoryManager();
+ return (PCHAR)addr;
+} // end MyAllocatePool()
+
+LONG
+__fastcall
+MyFindFrameByAddr(
+ PCHAR addr
+ )
+{
+ ULONG i;
+// ULONG j;
+ PMEM_ALLOC_DESC Allocs;
+
+ for(i=0;i<=LastFrame; i++) {
+ if( (Allocs = FrameList[i].Frame) &&
+ (Allocs[0].Addr <= (ULONG)addr) &&
+ (Allocs[0].Addr + MY_HEAP_FRAME_SIZE > (ULONG)addr) ) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+VOID
+__fastcall
+MyFreePool(
+ PCHAR addr
+ )
+{
+ LONG i;
+
+// KdPrint(("MemFrames: %x\n",FrameCount));
+
+ LockMemoryManager();
+ i = MyFindFrameByAddr(addr);
+ if(i < 0) {
+ UnlockMemoryManager();
+ KdPrint(("Mem: <<<*** WARNING ***>>> Double deallocation at %x !!! ;( \n", addr));
+ BrutePoint();
+ return;
+ }
+
+#ifdef UDF_DBG
+ // BreakAddr <= addr < BreakAddr + sizeof(UDF_FILE_INFO)
+// if((ULONG)addr >= (ULONG)BreakAddr && (ULONG)addr < sizeof(UDF_FILE_INFO) + (ULONG)BreakAddr) {
+// KdPrint(("Deallocating in examined block\n"));
+// KdPrint(("addr %x\n", addr));
+// MyAllocDumpFrame(i);
+// BrutePoint();
+// BreakAddr = NULL;
+// }
+#endif //UDF_DBG
+
+ MyFreePoolInFrame(i,addr);
+/* for(j=0;j<MY_HEAP_MAX_BLOCKS; j++) {
+ if((Allocs[j].Len & MY_HEAP_FLAG_USED) || (FrameCount<=1)) {
+ return;
+ }
+ }*/
+ if(MyAllocIsFrameFree(FrameList, i)) {
+ MyAllocFreeFrame(i);
+ }
+ UnlockMemoryManager();
+ return;
+} // end MyFreePool()
+
+ULONG
+#ifndef MY_HEAP_TRACK_OWNERS
+__fastcall
+#endif
+MyReallocPool(
+ IN PCHAR addr,
+ IN ULONG OldLength,
+ OUT PCHAR* NewBuff,
+ IN ULONG NewLength
+#ifdef MY_HEAP_TRACK_OWNERS
+ ,USHORT Src,
+ USHORT Line
+#endif
+ )
+{
+ ULONG i;
+ PCHAR new_buff;
+#ifdef MY_HEAP_TRACK_REF
+ PCHAR Tag;
+#endif
+
+// KdPrint(("MemFrames: %x\n",FrameCount));
+ (*NewBuff) = addr;
+ if(OldLength == NewLength) return OldLength;
+
+ if(!NewLength) {
+ BrutePoint();
+ return 0;
+ }
+
+ LockMemoryManager();
+ i = MyFindFrameByAddr(addr);
+ if(i < 0) {
+ UnlockMemoryManager();
+ KdPrint(("Mem: <<<*** WARNING ***>>> Double deallocation at %x !!! ;( \n", addr));
+ BrutePoint();
+ return 0;
+ }
+
+ if(MyResizePoolInFrame(i,addr,NewLength
+#ifdef MY_HEAP_TRACK_REF
+ , &Tag
+#endif
+ )) {
+#ifdef CHECK_ALLOC_FRAMES
+MyAllocCheck(i);
+#endif
+
+ (*NewBuff) = addr;
+ DbgTouch((PVOID)addr);
+ UnlockMemoryManager();
+ return NewLength;
+ }
+
+ new_buff = MyAllocatePool(FrameList[i].Type, MyAlignSize__(NewLength)
+#ifdef MY_HEAP_TRACK_OWNERS
+ ,Src,Line
+#endif
+#ifdef MY_HEAP_TRACK_REF
+ ,Tag
+#endif //MY_HEAP_TRACK_REF
+ );
+ if(!new_buff) {
+ UnlockMemoryManager();
+ return 0;
+ }
+
+ if(OldLength > NewLength) OldLength = NewLength;
+ RtlCopyMemory(new_buff, addr, OldLength);
+
+ MyFreePoolInFrame(i,addr);
+
+ if(MyAllocIsFrameFree(FrameList, i)) {
+ MyAllocFreeFrame(i);
+ }
+ UnlockMemoryManager();
+
+ DbgTouch((PVOID)new_buff);
+ (*NewBuff) = new_buff;
+ return OldLength;
+
+} // end MyReallocPool()
+
+#ifdef UDF_DBG
+LONG
+MyFindMemDescByRangeInFrame(
+ ULONG Frame,
+ PCHAR addr
+ )
+{
+ ULONG i;
+ ULONG left;
+ ULONG right;
+ PMEM_ALLOC_DESC Allocs;
+ ULONG curaddr;
+ ULONG curlen;
+
+ Allocs = FrameList[Frame].Frame;
+// i = FrameList[Frame].LastUsed >> 1;
+// KdPrint(("Mem: Freeing %x\n", (ULONG)addr)); DEADDA7A
+// for(i=0;i<MY_HEAP_MAX_BLOCKS;i++) {
+ left = 0;
+ right = FrameList[Frame].LastUsed;
+ if(!right && FrameList[Frame].FirstFree)
+ right = 1;
+ while(left != right) {
+ i = (right + left) >> 1;
+ curaddr = Allocs[i].Addr;
+ curlen = Allocs[i].Len;
+ if( (curlen & MY_HEAP_FLAG_USED) &&
+ (curaddr <= (ULONG)addr) &&
+ ((curaddr+(curlen & MY_HEAP_FLAG_LEN_MASK)) > (ULONG)addr) ) {
+FIF_Found:
+ return i;
+ }
+ if(right - left == 1) {
+ if( (Allocs[i+1].Len & MY_HEAP_FLAG_USED) && (Allocs[i+1].Addr == (ULONG)addr) ) {
+ i++;
+ goto FIF_Found;
+ }
+ break;
+ }
+ if(Allocs[i].Addr && (Allocs[i].Addr < (ULONG)addr)) {
+ left = i;
+ } else {
+ right = i;
+ }
+ }
+ return -1;
+} // end MyFindMemDescByRangeInFrame()
+
+LONG
+MyFindMemBaseByAddr(
+ PCHAR addr
+ )
+{
+ ULONG Frame, Base, i;
+
+ LockMemoryManager();
+ Frame = MyFindFrameByAddr(addr);
+ if(Frame < 0) {
+ UnlockMemoryManager();
+ KdPrint(("Mem: <<<*** WARNING ***>>> Unknown base for %x !!! ;( \n", addr));
+ BrutePoint();
+ return -1;
+ }
+ i = MyFindMemDescByRangeInFrame(Frame, addr);
+ Base = FrameList[Frame].Frame[i].Addr;
+ UnlockMemoryManager();
+ return Base;
+} // end MyFindMemBaseByAddr()
+#endif //UDF_DBG
+
+BOOLEAN
+MyAllocInit(VOID)
+{
+ RtlZeroMemory(&FrameList, sizeof(FrameList));
+ if(!OS_SUCCESS(InitLockMemoryManager())) {
+ return FALSE;
+ }
+ MyAllocInitFrame(NonPagedPool, 0);
+ LastFrame = 0;
+ return (MyMemInitialized = TRUE);
+} // end MyAllocInit()
+
+VOID
+MyAllocRelease(VOID)
+{
+ ULONG i;
+ PMEM_ALLOC_DESC Allocs;
+
+ if(!MyMemInitialized)
+ return;
+ LockMemoryManager();
+ for(i=0;i<MY_HEAP_MAX_FRAMES; i++) {
+ if(Allocs = FrameList[i].Frame) {
+ MyAllocFreeFrame(i);
+ }
+ }
+ RtlZeroMemory(&FrameList, sizeof(FrameList));
+ UnlockMemoryManager();
+ DeinitLockMemoryManager();
+ MyMemInitialized = FALSE;
+} // end MyAllocRelease()
+
+#endif //MY_USE_INTERNAL_MEMMANAGER
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+#ifndef __MY_MEM_TOOLS_H__
+#define __MY_MEM_TOOLS_H__
+
+#define MY_HEAP_FLAG_USED 0x00000001
+#define MY_HEAP_FLAG_LEN_MASK 0xfffffffe
+
+#define MyFreeMemoryAndPointer(ptr) \
+ if(ptr) { \
+ MyFreePool__(ptr); \
+ ptr = NULL; \
+ }
+
+#define MY_USE_ALIGN
+//#define MY_MEM_BOUNDS_CHECK
+
+typedef struct _MEM_ALLOC_DESC {
+ ULONG Addr;
+ ULONG Len;
+#ifdef MY_HEAP_TRACK_OWNERS
+ USHORT Src;
+ USHORT Line;
+#endif
+#ifdef MY_HEAP_TRACK_REF
+// PCHAR Ref;
+ PCHAR Tag;
+#endif
+} MEM_ALLOC_DESC, *PMEM_ALLOC_DESC;
+
+typedef struct _MEM_FRAME_ALLOC_DESC {
+ PMEM_ALLOC_DESC Frame;
+ ULONG LastUsed;
+ ULONG FirstFree;
+ ULONG Type;
+} MEM_FRAME_ALLOC_DESC, *PMEM_FRAME_ALLOC_DESC;
+
+extern PCHAR BreakAddr;
+extern ULONG MemTotalAllocated;
+
+#define MY_HEAP_FRAME_SIZE (256*1024)
+#define MY_HEAP_MAX_FRAMES 512
+#define MY_HEAP_MAX_BLOCKS 4*1024 // blocks per frame
+
+#ifdef USE_THREAD_HEAPS
+//extern HANDLE MemLock;
+extern "C" VOID ExInitThreadPools();
+extern "C" VOID ExDeInitThreadPools();
+extern "C" VOID ExFreeThreadPool();
+#endif //USE_THREAD_HEAPS
+
+// Mem
+BOOLEAN MyAllocInit(VOID);
+VOID MyAllocRelease(VOID);
+#ifdef MY_HEAP_TRACK_OWNERS
+PCHAR MyAllocatePool(ULONG Type, ULONG size, USHORT Src, USHORT Line
+ #ifdef MY_HEAP_TRACK_REF
+ ,PCHAR Tag
+ #endif //MY_HEAP_TRACK_REF
+ );
+ULONG MyReallocPool( PCHAR addr, ULONG OldLength, PCHAR* NewBuff, ULONG NewLength, USHORT Src, USHORT Line);
+#else
+PCHAR __fastcall MyAllocatePool(ULONG Type, ULONG size
+ #ifdef MY_HEAP_TRACK_REF
+ ,PCHAR Tag
+ #endif //MY_HEAP_TRACK_REF
+ );
+ULONG __fastcall MyReallocPool( PCHAR addr, ULONG OldLength, PCHAR* NewBuff, ULONG NewLength);
+#endif
+VOID __fastcall MyFreePool(PCHAR addr);
+
+#ifdef MY_HEAP_CHECK_BOUNDS
+ #define MY_HEAP_ALIGN 63
+#else
+ #define MY_HEAP_ALIGN 63
+#endif
+#define PAGE_SIZE_ALIGN (PAGE_SIZE - 1)
+
+#define AlignToPageSize(size) (((size)+PAGE_SIZE_ALIGN)&(~PAGE_SIZE_ALIGN))
+#define MyAlignSize__(size) (((size)+MY_HEAP_ALIGN)&(~MY_HEAP_ALIGN))
+#ifdef MY_HEAP_FORCE_NONPAGED
+#define MyFixMemType(type) NonPagedPool
+#else //MY_HEAP_FORCE_NONPAGED
+#define MyFixMemType(type) (type)
+#endif //MY_HEAP_FORCE_NONPAGED
+
+#ifdef MY_USE_INTERNAL_MEMMANAGER
+
+#ifdef MY_HEAP_TRACK_OWNERS
+ #ifdef MY_HEAP_TRACK_REF
+ #define MyAllocatePool__(type,size) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__, NULL)
+ #define MyAllocatePoolTag__(type,size,tag) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__, (PCHAR)(tag))
+ #else
+ #define MyAllocatePool__(type,size) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__)
+ #define MyAllocatePoolTag__(type,size,tag) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__)
+ #endif //MY_HEAP_TRACK_REF
+#else //MY_HEAP_TRACK_OWNERS
+ #ifdef MY_HEAP_TRACK_REF
+ #define MyAllocatePool__(type,size) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size), NULL)
+ #define MyAllocatePoolTag__(type,size,tag) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size), (PCHAR)(tag))
+ #else
+ #define MyAllocatePool__(type,size) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size))
+ #define MyAllocatePoolTag__(type,size,tag) MyAllocatePool(MyFixMemType(type), MyAlignSize__(size))
+ #endif //MY_HEAP_TRACK_REF
+#endif //MY_HEAP_TRACK_OWNERS
+
+#define MyFreePool__(addr) MyFreePool((PCHAR)(addr))
+
+#ifdef MY_HEAP_TRACK_OWNERS
+#define MyReallocPool__(addr, len, pnewaddr, newlen) MyReallocPool((PCHAR)(addr), MyAlignSize__(len), pnewaddr, MyAlignSize__(newlen), UDF_BUG_CHECK_ID, __LINE__)
+#else
+#define MyReallocPool__(addr, len, pnewaddr, newlen) MyReallocPool((PCHAR)(addr), MyAlignSize__(len), pnewaddr, MyAlignSize__(newlen))
+#endif
+
+#ifdef UDF_DBG
+LONG
+MyFindMemBaseByAddr(
+ PCHAR addr
+ );
+
+#define MyCheckArray(base, index) \
+ ASSERT(MyFindMemBaseByAddr((PCHAR)(base)) == MyFindMemBaseByAddr((PCHAR)(base+(index))))
+
+#else
+#define MyCheckArray(base, index)
+#endif //UDF_DBG
+
+
+#else //MY_USE_INTERNAL_MEMMANAGER
+
+#ifndef MY_USE_ALIGN
+#undef MyAlignSize__
+#define MyAlignSize__(size) (size)
+#endif
+
+BOOLEAN inline MyAllocInit(VOID) {return TRUE;}
+#define MyAllocRelease()
+
+#ifndef MY_MEM_BOUNDS_CHECK
+
+ #ifdef TRACK_SYS_ALLOC_CALLERS
+ #define MyAllocatePool__(type,size) DebugAllocatePool(NonPagedPool,MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__)
+ #define MyAllocatePoolTag__(type,size,tag) DebugAllocatePool(NonPagedPool,MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__)
+ #else //TRACK_SYS_ALLOC_CALLERS
+ #define MyAllocatePool__(type,size) DbgAllocatePoolWithTag(NonPagedPool,MyAlignSize__(size), 'fNWD')
+ #define MyAllocatePoolTag__(type,size,tag) DbgAllocatePoolWithTag(NonPagedPool,MyAlignSize__(size), tag)
+ #endif //TRACK_SYS_ALLOC_CALLERS
+ #define MyFreePool__(addr) DbgFreePool((PCHAR)(addr))
+
+#else //MY_MEM_BOUNDS_CHECK
+
+ #ifdef TRACK_SYS_ALLOC_CALLERS
+ #define MyAllocatePool_(type,size) DebugAllocatePool(NonPagedPool,MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__)
+ #define MyAllocatePoolTag_(type,size,tag) DebugAllocatePool(NonPagedPool,MyAlignSize__(size), UDF_BUG_CHECK_ID, __LINE__)
+ #else //TRACK_SYS_ALLOC_CALLERS
+ #define MyAllocatePool_(type,size) DbgAllocatePoolWithTag(NonPagedPool,MyAlignSize__(size), 'mNWD')
+ #define MyAllocatePoolTag_(type,size,tag) DbgAllocatePoolWithTag(NonPagedPool,MyAlignSize__(size), tag)
+ #endif //TRACK_SYS_ALLOC_CALLERS
+ #define MyFreePool_(addr) DbgFreePool((PCHAR)(addr))
+
+#define MyAllocatePool__(type,size) MyAllocatePoolTag__(type,size,'mNWD')
+
+/*
+PVOID inline MyAllocatePool__(ULONG type, ULONG len) {
+ PCHAR newaddr;
+ ULONG i;
+// newaddr = (PCHAR)MyAllocatePool_(type, len+MY_HEAP_ALIGN+1);
+#ifdef TRACK_SYS_ALLOC_CALLERS
+ newaddr = (PCHAR)DebugAllocatePool(type,len+MY_HEAP_ALIGN+1, 0x202, __LINE__);
+#else //TRACK_SYS_ALLOC_CALLERS
+ newaddr = (PCHAR)MyAllocatePool_(type,len+MY_HEAP_ALIGN+1);
+#endif //TRACK_SYS_ALLOC_CALLERS
+ if(!newaddr)
+ return NULL;
+ for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+ newaddr[len+i] = (UCHAR)('A'+i);
+ }
+ return newaddr;
+}
+*/
+
+PVOID inline MyAllocatePoolTag__(ULONG type, ULONG len, /*PCHAR*/ULONG tag) {
+ PCHAR newaddr;
+ ULONG i;
+// newaddr = (PCHAR)MyAllocatePoolTag_(type, len+MY_HEAP_ALIGN+1, tag);
+#ifdef TRACK_SYS_ALLOC_CALLERS
+ newaddr = (PCHAR)DebugAllocatePool(type,len+MY_HEAP_ALIGN+1, 0x202, __LINE__);
+#else //TRACK_SYS_ALLOC_CALLERS
+ newaddr = (PCHAR)MyAllocatePoolTag_(type,len+MY_HEAP_ALIGN+1, tag);
+#endif //TRACK_SYS_ALLOC_CALLERS
+ if(!newaddr)
+ return NULL;
+ for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+ newaddr[len+i] = (UCHAR)('A'+i);
+ }
+ return newaddr;
+}
+
+VOID inline MyFreePool__(PVOID addr) {
+ PCHAR newaddr;
+// ULONG i;
+ newaddr = (PCHAR)addr;
+ if(!newaddr) {
+ __asm int 3;
+ return;
+ }
+/*
+ for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+ if(newaddr[len+i] != (UCHAR)('A'+i)) {
+ __asm int 3;
+ break;
+ }
+ }
+*/
+ MyFreePool_(newaddr);
+}
+
+#endif //MY_MEM_BOUNDS_CHECK
+
+ULONG inline MyReallocPool__(PCHAR addr, ULONG len, PCHAR *pnewaddr, ULONG newlen) {
+ ULONG _len, _newlen;
+ _newlen = MyAlignSize__(newlen);
+ _len = MyAlignSize__(len);
+ PCHAR newaddr;
+
+ ASSERT(len && newlen);
+
+#ifdef MY_MEM_BOUNDS_CHECK
+ ULONG i;
+
+ for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+ if((UCHAR)(addr[len+i]) != (UCHAR)('A'+i)) {
+ __asm int 3;
+ break;
+ }
+ }
+#endif //MY_MEM_BOUNDS_CHECK
+
+ if ((_newlen != _len)
+#ifdef MY_MEM_BOUNDS_CHECK
+ || TRUE
+#endif //MY_MEM_BOUNDS_CHECK
+ ) {
+#ifdef TRACK_SYS_ALLOC_CALLERS
+ newaddr = (PCHAR)DebugAllocatePool(NonPagedPool,_newlen, 0x202, __LINE__);
+#else //TRACK_SYS_ALLOC_CALLERS
+ newaddr = (PCHAR)MyAllocatePool__(NonPagedPool,_newlen);
+#endif //TRACK_SYS_ALLOC_CALLERS
+ if (!newaddr) {
+ __debugbreak();
+ *pnewaddr = addr;
+ return 0;
+ }
+#ifdef MY_MEM_BOUNDS_CHECK
+ for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+ newaddr[newlen+i] = (UCHAR)('A'+i);
+ }
+#endif //MY_MEM_BOUNDS_CHECK
+ *pnewaddr = newaddr;
+ if(_newlen <= _len) {
+ RtlCopyMemory(newaddr, addr, newlen);
+ } else {
+ RtlCopyMemory(newaddr, addr, len);
+ RtlZeroMemory(newaddr+len, newlen - len);
+ }
+#ifdef MY_MEM_BOUNDS_CHECK
+ for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+ if((UCHAR)(newaddr[newlen+i]) != (UCHAR)('A'+i)) {
+ __asm int 3;
+ break;
+ }
+ }
+#endif //MY_MEM_BOUNDS_CHECK
+
+ MyFreePool__(addr);
+ } else {
+ *pnewaddr = addr;
+ }
+ if(newlen > len) {
+ //RtlZeroMemory(newaddr+len, newlen - len);
+ }
+/*
+#ifdef MY_MEM_BOUNDS_CHECK
+ for(i=0; i<MY_HEAP_ALIGN+1; i++) {
+ newaddr[newlen+i] = (UCHAR)('A'+i);
+ }
+#endif //MY_MEM_BOUNDS_CHECK
+*/
+ return newlen;
+}
+
+#ifndef MY_USE_ALIGN
+#undef MyAlignSize__
+#define MyAlignSize__(size) (((size)+MY_HEAP_ALIGN)&(~MY_HEAP_ALIGN))
+#endif
+
+#define MyCheckArray(base, index)
+
+#endif // MY_USE_INTERNAL_MEMMANAGER
+
+#endif // __MY_MEM_TOOLS_H__
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+
+VOID
+UDFSetModified(
+ IN PVCB Vcb
+ )
+{
+ if(UDFInterlockedIncrement((PLONG)&(Vcb->Modified)) & 0x80000000)
+ Vcb->Modified = 2;
+} // end UDFSetModified()
+
+VOID
+UDFPreClrModified(
+ IN PVCB Vcb
+ )
+{
+ Vcb->Modified = 1;
+} // end UDFPreClrModified()
+
+VOID
+UDFClrModified(
+ IN PVCB Vcb
+ )
+{
+ KdPrint(("ClrModified\n"));
+ UDFInterlockedDecrement((PLONG)&(Vcb->Modified));
+} // end UDFClrModified()
+
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+/*++
+
+Copyright (c) 1997-1999 Microsoft Corporation
+
+Module Name:
+
+ mountmgr.h
+
+Abstract:
+
+ This file defines the external mount point interface for administering
+ mount points.
+
+Author:
+
+ norbertk
+
+Revision History:
+
+--*/
+
+#ifndef _MOUNTMGR_
+#define _MOUNTMGR_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#ifndef FAR
+#define FAR
+#endif
+
+
+#define MOUNTMGR_DEVICE_NAME L"\\Device\\MountPointManager"
+#define MOUNTMGR_DOS_DEVICE_NAME L"\\\\.\\MountPointManager"
+
+#define MOUNTMGRCONTROLTYPE ((ULONG) 'm')
+#define MOUNTDEVCONTROLTYPE ((ULONG) 'M')
+
+//
+// These are the IOCTLs supported by the mount point manager.
+//
+
+#define IOCTL_MOUNTMGR_CREATE_POINT CTL_CODE(MOUNTMGRCONTROLTYPE, 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_DELETE_POINTS CTL_CODE(MOUNTMGRCONTROLTYPE, 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_QUERY_POINTS CTL_CODE(MOUNTMGRCONTROLTYPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY CTL_CODE(MOUNTMGRCONTROLTYPE, 3, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER CTL_CODE(MOUNTMGRCONTROLTYPE, 4, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_AUTO_DL_ASSIGNMENTS CTL_CODE(MOUNTMGRCONTROLTYPE, 5, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED CTL_CODE(MOUNTMGRCONTROLTYPE, 6, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED CTL_CODE(MOUNTMGRCONTROLTYPE, 7, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_CHANGE_NOTIFY CTL_CODE(MOUNTMGRCONTROLTYPE, 8, METHOD_BUFFERED, FILE_READ_ACCESS)
+#define IOCTL_MOUNTMGR_KEEP_LINKS_WHEN_OFFLINE CTL_CODE(MOUNTMGRCONTROLTYPE, 9, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define IOCTL_MOUNTMGR_CHECK_UNPROCESSED_VOLUMES CTL_CODE(MOUNTMGRCONTROLTYPE, 10, METHOD_BUFFERED, FILE_READ_ACCESS)
+#define IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION CTL_CODE(MOUNTMGRCONTROLTYPE, 11, METHOD_BUFFERED, FILE_READ_ACCESS)
+
+//
+// Input structure for IOCTL_MOUNTMGR_CREATE_POINT.
+//
+
+typedef struct _MOUNTMGR_CREATE_POINT_INPUT {
+ USHORT SymbolicLinkNameOffset;
+ USHORT SymbolicLinkNameLength;
+ USHORT DeviceNameOffset;
+ USHORT DeviceNameLength;
+} MOUNTMGR_CREATE_POINT_INPUT, *PMOUNTMGR_CREATE_POINT_INPUT;
+
+//
+// Input structure for IOCTL_MOUNTMGR_DELETE_POINTS,
+// IOCTL_MOUNTMGR_QUERY_POINTS, and IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY.
+//
+
+typedef struct _MOUNTMGR_MOUNT_POINT {
+ ULONG SymbolicLinkNameOffset;
+ USHORT SymbolicLinkNameLength;
+ ULONG UniqueIdOffset;
+ USHORT UniqueIdLength;
+ ULONG DeviceNameOffset;
+ USHORT DeviceNameLength;
+} MOUNTMGR_MOUNT_POINT, *PMOUNTMGR_MOUNT_POINT;
+
+//
+// Output structure for IOCTL_MOUNTMGR_DELETE_POINTS,
+// IOCTL_MOUNTMGR_QUERY_POINTS, and IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY.
+//
+
+typedef struct _MOUNTMGR_MOUNT_POINTS {
+ ULONG Size;
+ ULONG NumberOfMountPoints;
+ MOUNTMGR_MOUNT_POINT MountPoints[1];
+} MOUNTMGR_MOUNT_POINTS, *PMOUNTMGR_MOUNT_POINTS;
+
+//
+// Input structure for IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER.
+//
+
+typedef struct _MOUNTMGR_DRIVE_LETTER_TARGET {
+ USHORT DeviceNameLength;
+ WCHAR DeviceName[1];
+} MOUNTMGR_DRIVE_LETTER_TARGET, *PMOUNTMGR_DRIVE_LETTER_TARGET;
+
+//
+// Output structure for IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER.
+//
+
+typedef struct _MOUNTMGR_DRIVE_LETTER_INFORMATION {
+ BOOLEAN DriveLetterWasAssigned;
+ UCHAR CurrentDriveLetter;
+} MOUNTMGR_DRIVE_LETTER_INFORMATION, *PMOUNTMGR_DRIVE_LETTER_INFORMATION;
+
+//
+// Input structure for IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED and
+// IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED.
+//
+
+typedef struct _MOUNTMGR_VOLUME_MOUNT_POINT {
+ USHORT SourceVolumeNameOffset;
+ USHORT SourceVolumeNameLength;
+ USHORT TargetVolumeNameOffset;
+ USHORT TargetVolumeNameLength;
+} MOUNTMGR_VOLUME_MOUNT_POINT, *PMOUNTMGR_VOLUME_MOUNT_POINT;
+
+//
+// Input structure for IOCTL_MOUNTMGR_CHANGE_NOTIFY.
+// Output structure for IOCTL_MOUNTMGR_CHANGE_NOTIFY.
+//
+
+typedef struct _MOUNTMGR_CHANGE_NOTIFY_INFO {
+ ULONG EpicNumber;
+} MOUNTMGR_CHANGE_NOTIFY_INFO, *PMOUNTMGR_CHANGE_NOTIFY_INFO;
+
+//
+// Input structure for IOCTL_MOUNTMGR_KEEP_LINKS_WHEN_OFFLINE and
+// IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION.
+//
+
+typedef struct _MOUNTMGR_TARGET_NAME {
+ USHORT DeviceNameLength;
+ WCHAR DeviceName[1];
+} MOUNTMGR_TARGET_NAME, *PMOUNTMGR_TARGET_NAME;
+
+//
+// The following IOCTL is supported by mounted devices.
+//
+
+#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME CTL_CODE(MOUNTDEVCONTROLTYPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+//
+// Output structure for IOCTL_MOUNTDEV_QUERY_DEVICE_NAME.
+//
+
+typedef struct _MOUNTDEV_NAME {
+ USHORT NameLength;
+ WCHAR Name[1];
+} MOUNTDEV_NAME, *PMOUNTDEV_NAME;
+
+//
+// Devices that wish to be mounted should report this GUID in
+// IoRegisterDeviceInterface.
+//
+
+//DEFINE_GUID(MOUNTDEV_MOUNTED_DEVICE_GUID, 0x53f5630d, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
+
+#endif
+
--- /dev/null
+////////////////////////////////////////////////////////////////////
+// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
+// All rights reserved
+////////////////////////////////////////////////////////////////////
+
+//======================================================================
+//
+// NT_Native.h
+//
+//======================================================================
+
+#ifndef __NT_NATIVE_DEFS__H__
+#define __NT_NATIVE_DEFS__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif //__cplusplus
+
+#include <excpt.h>
+#include <ntdef.h>
+#include <ntstatus.h>
+#include <string.h>
+#include <DEVIOCTL.H>
+#include <NTDDSTOR.H>
+#include <NTDDDISK.H>
+
+typedef struct _KTHREAD *PKTHREAD;
+typedef struct _ETHREAD *PETHREAD;
+typedef struct _EPROCESS *PEPROCESS;
+typedef struct _PEB *PPEB;
+typedef struct _KINTERRUPT *PKINTERRUPT;
+typedef struct _IO_TIMER *PIO_TIMER;
+typedef struct _OBJECT_TYPE *POBJECT_TYPE;
+typedef struct _CALLBACK_OBJECT *PCALLBACK_OBJECT;
+typedef struct _DEVICE_HANDLER_OBJECT *PDEVICE_HANDLER_OBJECT;
+typedef struct _BUS_HANDLER *PBUS_HANDLER;
+
+
+typedef ULONG ACCESS_MASK;
+typedef ACCESS_MASK *PACCESS_MASK;
+
+#define BOOL BOOLEAN
+#define DWORD ULONG
+#define LPVOID PVOID
+#define LPDWORD PULONG
+
+#define APIENTRY __stdcall
+
+#define FASTCALL _fastcall
+
+// end_winnt
+//
+// The following are masks for the predefined standard access types
+//
+
+#define DELETE (0x00010000L)
+#define READ_CONTROL (0x00020000L)
+#define WRITE_DAC (0x00040000L)
+#define WRITE_OWNER (0x00080000L)
+#define SYNCHRONIZE (0x00100000L)
+
+#define STANDARD_RIGHTS_REQUIRED (0x000F0000L)
+
+#define STANDARD_RIGHTS_READ (READ_CONTROL)
+#define STANDARD_RIGHTS_WRITE (READ_CONTROL)
+#define STANDARD_RIGHTS_EXECUTE (READ_CONTROL)
+
+#define STANDARD_RIGHTS_ALL (0x001F0000L)
+
+#define SPECIFIC_RIGHTS_ALL (0x0000FFFFL)
+
+//
+// AccessSystemAcl access type
+//
+
+#define ACCESS_SYSTEM_SECURITY (0x01000000L)
+
+//
+// MaximumAllowed access type
+//
+
+#define MAXIMUM_ALLOWED (0x02000000L)
+
+//
+// These are the generic rights.
+//
+
+#define GENERIC_READ (0x80000000L)
+#define GENERIC_WRITE (0x40000000L)
+#define GENERIC_EXECUTE (0x20000000L)
+#define GENERIC_ALL (0x10000000L)
+
+
+//
+// Subroutines for dealing with the Registry
+//
+
+typedef NTSTATUS (*PRTL_QUERY_REGISTRY_ROUTINE)(
+ IN PWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength,
+ IN PVOID Context,
+ IN PVOID EntryContext
+ );
+
+typedef struct _RTL_QUERY_REGISTRY_TABLE {
+ PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
+ ULONG Flags;
+ PWSTR Name;
+ PVOID EntryContext;
+ ULONG DefaultType;
+ PVOID DefaultData;
+ ULONG DefaultLength;
+
+} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;
+
+
+//
+// The following flags specify how the Name field of a RTL_QUERY_REGISTRY_TABLE
+// entry is interpreted. A NULL name indicates the end of the table.
+//
+
+#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 // Name is a subkey and remainder of
+ // table or until next subkey are value
+ // names for that subkey to look at.
+
+#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 // Reset current key to original key for
+ // this and all following table entries.
+
+#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 // Fail if no match found for this table
+ // entry.
+
+#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 // Used to mark a table entry that has no
+ // value name, just wants a call out, not
+ // an enumeration of all values.
+
+#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 // Used to suppress the expansion of
+ // REG_MULTI_SZ into multiple callouts or
+ // to prevent the expansion of environment
+ // variable values in REG_EXPAND_SZ
+
+#define RTL_QUERY_REGISTRY_DIRECT 0x00000020 // QueryRoutine field ignored. EntryContext
+ // field points to location to store value.
+ // For null terminated strings, EntryContext
+ // points to UNICODE_STRING structure that
+ // that describes maximum size of buffer.
+ // If .Buffer field is NULL then a buffer is
+ // allocated.
+ //
+
+#define RTL_QUERY_REGISTRY_DELETE 0x00000040 // Used to delete value keys after they
+ // are queried.
+
+//
+// The following values for the RelativeTo parameter determine what the
+// Path parameter to RtlQueryRegistryValues is relative to.
+//
+
+#define RTL_REGISTRY_ABSOLUTE 0 // Path is a full path
+#define RTL_REGISTRY_SERVICES 1 // \Registry\Machine\System\CurrentControlSet\Services
+#define RTL_REGISTRY_CONTROL 2 // \Registry\Machine\System\CurrentControlSet\Control
+#define RTL_REGISTRY_WINDOWS_NT 3 // \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion
+#define RTL_REGISTRY_DEVICEMAP 4 // \Registry\Machine\Hardware\DeviceMap
+#define RTL_REGISTRY_USER 5 // \Registry\User\CurrentUser
+#define RTL_REGISTRY_MAXIMUM 6
+#define RTL_REGISTRY_HANDLE 0x40000000 // Low order bits are registry handle
+#define RTL_REGISTRY_OPTIONAL 0x80000000 // Indicates the key node is optional
+
+
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlCharToInteger (
+ PCSZ String,
+ ULONG Base,
+ PULONG Value
+ );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlIntegerToUnicodeString (
+ ULONG Value,
+ ULONG Base,
+ PUNICODE_STRING String
+ );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlUnicodeStringToInteger (
+ PUNICODE_STRING String,
+ ULONG Base,
+ PULONG Value
+ );
+
+\f
+//
+// String manipulation routines
+//
+
+#ifdef _NTSYSTEM_
+
+#define NLS_MB_CODE_PAGE_TAG NlsMbCodePageTag
+#define NLS_MB_OEM_CODE_PAGE_TAG NlsMbOemCodePageTag
+
+#else
+
+#define NLS_MB_CODE_PAGE_TAG (*NlsMbCodePageTag)
+#define NLS_MB_OEM_CODE_PAGE_TAG (*NlsMbOemCodePageTag)
+
+#endif // _NTSYSTEM_
+
+extern BOOLEAN NLS_MB_CODE_PAGE_TAG; // TRUE -> Multibyte CP, FALSE -> Singlebyte
+extern BOOLEAN NLS_MB_OEM_CODE_PAGE_TAG; // TRUE -> Multibyte CP, FALSE -> Singlebyte
+
+NTSYSAPI
+VOID
+NTAPI
+RtlInitString(
+ PSTRING DestinationString,
+ PCSZ SourceString
+ );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlInitAnsiString(
+ PANSI_STRING DestinationString,
+ PCSZ SourceString
+ );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlInitUnicodeString(
+ PUNICODE_STRING DestinationString,
+ PCWSTR SourceString
+ );
+
+
+NTSYSAPI
+VOID
+NTAPI
+RtlCopyString(
+ PSTRING DestinationString,
+ PSTRING SourceString
+ );
+
+NTSYSAPI
+CHAR
+NTAPI
+RtlUpperChar (
+ CHAR Character
+ );
+
+NTSYSAPI
+LONG
+NTAPI
+RtlCompareString(
+ PSTRING String1,
+ PSTRING String2,
+ BOOLEAN CaseInSensitive
+ );
+
+NTSYSAPI
+BOOLEAN
+NTAPI
+RtlEqualString(
+ PSTRING String1,
+ PSTRING String2,
+ BOOLEAN CaseInSensitive
+ );
+
+
+NTSYSAPI
+VOID
+NTAPI
+RtlUpperString(
+ PSTRING DestinationString,
+ PSTRING SourceString
+ );
+
+//
+// NLS String functions
+//
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlAnsiStringToUnicodeString(
+ PUNICODE_STRING DestinationString,
+ PANSI_STRING SourceString,
+ BOOLEAN AllocateDestinationString
+ );
+
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlUnicodeStringToAnsiString(
+ PANSI_STRING DestinationString,
+ PUNICODE_STRING SourceString,
+ BOOLEAN AllocateDestinationString
+ );
+
+
+NTSYSAPI
+LONG
+NTAPI
+RtlCompareUnicodeString(
+ PUNICODE_STRING String1,
+ PUNICODE_STRING String2,
+ BOOLEAN CaseInSensitive
+ );
+
+NTSYSAPI
+BOOLEAN
+NTAPI
+RtlEqualUnicodeString(
+ PUNICODE_STRING String1,
+ PUNICODE_STRING String2,
+ BOOLEAN CaseInSensitive
+ );
+
+NTSYSAPI
+BOOLEAN
+NTAPI
+RtlPrefixUnicodeString(
+ IN PUNICODE_STRING String1,
+ IN PUNICODE_STRING String2,
+ IN BOOLEAN CaseInSensitive
+ );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlUpcaseUnicodeString(
+ PUNICODE_STRING DestinationString,
+ PUNICODE_STRING SourceString,
+ BOOLEAN AllocateDestinationString
+ );
+
+
+NTSYSAPI
+VOID
+NTAPI
+RtlCopyUnicodeString(
+ PUNICODE_STRING DestinationString,
+ PUNICODE_STRING SourceString
+ );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlAppendUnicodeStringToString (
+ PUNICODE_STRING Destination,
+ PUNICODE_STRING Source
+ );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlAppendUnicodeToString (
+ PUNICODE_STRING Destination,
+ PWSTR Source
+ );
+
+
+NTSYSAPI
+VOID
+NTAPI
+RtlFreeUnicodeString(
+ PUNICODE_STRING UnicodeString
+ );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlFreeAnsiString(
+ PANSI_STRING AnsiString
+ );
+
+
+NTSYSAPI
+ULONG
+NTAPI
+RtlxAnsiStringToUnicodeSize(
+ PANSI_STRING AnsiString
+ );
+
+//
+// NTSYSAPI
+// ULONG
+// NTAPI
+// RtlAnsiStringToUnicodeSize(
+// PANSI_STRING AnsiString
+// );
+//
+
+#define RtlAnsiStringToUnicodeSize(STRING) ( \
+ NLS_MB_CODE_PAGE_TAG ? \
+ RtlxAnsiStringToUnicodeSize(STRING) : \
+ ((STRING)->Length + sizeof((UCHAR)NULL)) * sizeof(WCHAR) \
+)
+
+#if DBG
+NTSYSAPI
+VOID
+NTAPI
+RtlAssert(
+ PVOID FailedAssertion,
+ PVOID FileName,
+ ULONG LineNumber,
+ PCHAR Message
+ );
+
+#define ASSERT( exp ) \
+ if (!(exp)) \
+ RtlAssert( #exp, __FILE__, __LINE__, NULL )
+
+#define ASSERTMSG( msg, exp ) \
+ if (!(exp)) \
+ RtlAssert( #exp, __FILE__, __LINE__, msg )
+
+#else
+#define ASSERT( exp )
+#define ASSERTMSG( msg, exp )
+#endif // DBG
+
+//
+// Fast primitives to compare, move, and zero memory
+//
+
+// begin_winnt begin_ntndis
+#if defined(_M_IX86) || defined(_M_MRX000) || defined(_M_ALPHA)
+
+#if defined(_M_MRX000)
+NTSYSAPI
+ULONG
+NTAPI
+RtlEqualMemory (
+ CONST VOID *Source1,
+ CONST VOID *Source2,
+ ULONG Length
+ );
+
+#else
+#define RtlEqualMemory(Destination,Source,Length) (!memcmp((Destination),(Source),(Length)))
+#endif
+
+#define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length))
+#define RtlCopyMemory(Destination,Source,Length) memcpy((Destination),(Source),(Length))
+#define RtlFillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
+#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
+
+#else // _M_PPC
+
+NTSYSAPI
+ULONG
+NTAPI
+RtlEqualMemory (
+ CONST VOID *Source1,
+ CONST VOID *Source2,
+ ULONG Length
+ );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlCopyMemory (
+ VOID UNALIGNED *Destination,
+ CONST VOID UNALIGNED *Source,
+ ULONG Length
+ );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlCopyMemory32 (
+ VOID UNALIGNED *Destination,
+ CONST VOID UNALIGNED *Source,
+ ULONG Length
+ );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlMoveMemory (
+ VOID UNALIGNED *Destination,
+ CONST VOID UNALIGNED *Source,
+ ULONG Length
+ );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlFillMemory (
+ VOID UNALIGNED *Destination,
+ ULONG Length,
+ UCHAR Fill
+ );
+
+NTSYSAPI
+VOID
+NTAPI
+RtlZeroMemory (
+ VOID UNALIGNED *Destination,
+ ULONG Length
+ );
+#endif
+// end_winnt end_ntndis
+
+NTSYSAPI
+ULONG
+NTAPI
+RtlCompareMemory (
+ PVOID Source1,
+ PVOID Source2,
+ ULONG Length
+ );
+
+typedef struct _TIME_FIELDS {
+ CSHORT Year; // range [1601...]
+ CSHORT Month; // range [1..12]
+ CSHORT Day; // range [1..31]
+ CSHORT Hour; // range [0..23]
+ CSHORT Minute; // range [0..59]
+ CSHORT Second; // range [0..59]
+ CSHORT Milliseconds;// range [0..999]
+ CSHORT Weekday; // range [0..6] == [Sunday..Saturday]
+} TIME_FIELDS;
+typedef TIME_FIELDS *PTIME_FIELDS;
+
+
+NTSYSAPI
+VOID
+NTAPI
+RtlTimeToTimeFields (
+ PLARGE_INTEGER Time,
+ PTIME_FIELDS TimeFields
+ );
+
+//
+// A time field record (Weekday ignored) -> 64 bit Time value
+//
+
+NTSYSAPI
+BOOLEAN
+NTAPI
+RtlTimeFieldsToTime (
+ PTIME_FIELDS TimeFields,
+ PLARGE_INTEGER Time
+ );
+
+//
+// Define the generic mapping array. This is used to denote the
+// mapping of each generic access right to a specific access mask.
+//
+
+typedef struct _GENERIC_MAPPING {
+ ACCESS_MASK GenericRead;
+ ACCESS_MASK GenericWrite;
+ ACCESS_MASK GenericExecute;
+ ACCESS_MASK GenericAll;
+} GENERIC_MAPPING;
+typedef GENERIC_MAPPING *PGENERIC_MAPPING;
+
+//
+// Define the various device type values. Note that values used by Microsoft
+// Corporation are in the range 0-32767, and 32768-65535 are reserved for use
+// by customers.
+//
+
+#define DEVICE_TYPE ULONG
+
+#define FILE_DEVICE_BEEP 0x00000001
+#define FILE_DEVICE_CD_ROM 0x00000002
+#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
+#define FILE_DEVICE_CONTROLLER 0x00000004
+#define FILE_DEVICE_DATALINK 0x00000005
+#define FILE_DEVICE_DFS 0x00000006
+#define FILE_DEVICE_DISK 0x00000007
+#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
+#define FILE_DEVICE_FILE_SYSTEM 0x00000009
+#define FILE_DEVICE_INPORT_PORT 0x0000000a
+#define FILE_DEVICE_KEYBOARD 0x0000000b
+#define FILE_DEVICE_MAILSLOT 0x0000000c
+#define FILE_DEVICE_MIDI_IN 0x0000000d
+#define FILE_DEVICE_MIDI_OUT 0x0000000e
+#define FILE_DEVICE_MOUSE 0x0000000f
+#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010
+#define FILE_DEVICE_NAMED_PIPE 0x00000011
+#define FILE_DEVICE_NETWORK 0x00000012
+#define FILE_DEVICE_NETWORK_BROWSER 0x00000013
+#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
+#define FILE_DEVICE_NULL 0x00000015
+#define FILE_DEVICE_PARALLEL_PORT 0x00000016
+#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
+#define FILE_DEVICE_PRINTER 0x00000018
+#define FILE_DEVICE_SCANNER 0x00000019
+#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a
+#define FILE_DEVICE_SERIAL_PORT 0x0000001b
+#define FILE_DEVICE_SCREEN 0x0000001c
+#define FILE_DEVICE_SOUND 0x0000001d
+#define FILE_DEVICE_STREAMS 0x0000001e
+#define FILE_DEVICE_TAPE 0x0000001f
+#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
+#define FILE_DEVICE_TRANSPORT 0x00000021
+#define FILE_DEVICE_UNKNOWN 0x00000022
+#define FILE_DEVICE_VIDEO 0x00000023
+#define FILE_DEVICE_VIRTUAL_DISK 0x00000024
+#define FILE_DEVICE_WAVE_IN 0x00000025
+#define FILE_DEVICE_WAVE_OUT 0x00000026
+#define FILE_DEVICE_8042_PORT 0x00000027
+#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
+#define FILE_DEVICE_BATTERY 0x00000029
+#define FILE_DEVICE_BUS_EXTENDER 0x0000002a
+#define FILE_DEVICE_MODEM 0x0000002b
+#define FILE_DEVICE_VDM 0x0000002c
+//
+// Macro definition for defining IOCTL and FSCTL function control codes. Note
+// that function codes 0-2047 are reserved for Microsoft Corporation, and
+// 2048-4095 are reserved for customers.
+//
+
+#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
+ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
+)
+
+//
+// Define the method codes for how buffers are passed for I/O and FS controls
+//
+
+#define METHOD_BUFFERED 0
+#define METHOD_IN_DIRECT 1
+#define METHOD_OUT_DIRECT 2
+#define METHOD_NEITHER 3
+
+//
+// Define the access check value for any access
+//
+//
+// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
+// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
+// constants *MUST* always be in sync.
+//
+
+
+#define FILE_ANY_ACCESS 0
+#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe
+#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe
+
+
+// begin_winnt
+
+//
+// Define access rights to files and directories
+//
+
+//
+// The FILE_READ_DATA and FILE_WRITE_DATA constants are also defined in
+// devioctl.h as FILE_READ_ACCESS and FILE_WRITE_ACCESS. The values for these
+// constants *MUST* always be in sync.
+// The values are redefined in devioctl.h because they must be available to
+// both DOS and NT.
+//
+
+#define FILE_READ_DATA ( 0x0001 ) // file & pipe
+#define FILE_LIST_DIRECTORY ( 0x0001 ) // directory
+
+#define FILE_WRITE_DATA ( 0x0002 ) // file & pipe
+#define FILE_ADD_FILE ( 0x0002 ) // directory
+
+#define FILE_APPEND_DATA ( 0x0004 ) // file
+#define FILE_ADD_SUBDIRECTORY ( 0x0004 ) // directory
+#define FILE_CREATE_PIPE_INSTANCE ( 0x0004 ) // named pipe
+
+#define FILE_READ_EA ( 0x0008 ) // file & directory
+
+#define FILE_WRITE_EA ( 0x0010 ) // file & directory
+
+#define FILE_EXECUTE ( 0x0020 ) // file
+#define FILE_TRAVERSE ( 0x0020 ) // directory
+
+#define FILE_DELETE_CHILD ( 0x0040 ) // directory
+
+#define FILE_READ_ATTRIBUTES ( 0x0080 ) // all
+
+#define FILE_WRITE_ATTRIBUTES ( 0x0100 ) // all
+
+#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
+
+#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ |\
+ FILE_READ_DATA |\
+ FILE_READ_ATTRIBUTES |\
+ FILE_READ_EA |\
+ SYNCHRONIZE)
+
+
+#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |\
+ FILE_WRITE_DATA |\
+ FILE_WRITE_ATTRIBUTES |\
+ FILE_WRITE_EA |\
+ FILE_APPEND_DATA |\
+ SYNCHRONIZE)
+
+
+#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE |\
+ FILE_READ_ATTRIBUTES |\
+ FILE_EXECUTE |\
+ SYNCHRONIZE)
+
+// end_winnt
+
+
+//
+// Define share access rights to files and directories
+//
+
+#define FILE_SHARE_READ 0x00000001 // winnt
+#define FILE_SHARE_WRITE 0x00000002 // winnt
+#define FILE_SHARE_DELETE 0x00000004 // winnt
+#define FILE_SHARE_VALID_FLAGS 0x00000007
+
+//
+// Define the file attributes values
+//
+// Note: 0x00000008 is reserved for use for the old DOS VOLID (volume ID)
+// and is therefore not considered valid in NT.
+//
+// Note: 0x00000010 is reserved for use for the old DOS SUBDIRECTORY flag
+// and is therefore not considered valid in NT. This flag has
+// been disassociated with file attributes since the other flags are
+// protected with READ_ and WRITE_ATTRIBUTES access to the file.
+//
+// Note: Note also that the order of these flags is set to allow both the
+// FAT and the Pinball File Systems to directly set the attributes
+// flags in attributes words without having to pick each flag out
+// individually. The order of these flags should not be changed!
+//
+
+#define FILE_ATTRIBUTE_READONLY 0x00000001 // winnt
+#define FILE_ATTRIBUTE_HIDDEN 0x00000002 // winnt
+#define FILE_ATTRIBUTE_SYSTEM 0x00000004 // winnt
+#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 // winnt
+#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 // winnt
+#define FILE_ATTRIBUTE_NORMAL 0x00000080 // winnt
+#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 // winnt
+#define FILE_ATTRIBUTE_RESERVED0 0x00000200
+#define FILE_ATTRIBUTE_RESERVED1 0x00000400
+#define FILE_ATTRIBUTE_COMPRESSED 0x00000800 // winnt
+#define FILE_ATTRIBUTE_OFFLINE 0x00001000 // winnt
+#define FILE_ATTRIBUTE_PROPERTY_SET 0x00002000
+#define FILE_ATTRIBUTE_VALID_FLAGS 0x00003fb7
+#define FILE_ATTRIBUTE_VALID_SET_FLAGS 0x00003fa7
+
+//
+// Define the create disposition values
+//
+
+#define FILE_SUPERSEDE 0x00000000
+#define FILE_OPEN 0x00000001
+#define FILE_CREATE 0x00000002
+#define FILE_OPEN_IF 0x00000003
+#define FILE_OVERWRITE 0x00000004
+#define FILE_OVERWRITE_IF 0x00000005
+#define FILE_MAXIMUM_DISPOSITION 0x00000005
+
+
+//
+// Define the create/open option flags
+//
+
+#define FILE_DIRECTORY_FILE 0x00000001
+#define FILE_WRITE_THROUGH 0x00000002
+#define FILE_SEQUENTIAL_ONLY 0x00000004
+#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
+
+#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
+#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
+#define FILE_NON_DIRECTORY_FILE 0x00000040
+#define FILE_CREATE_TREE_CONNECTION 0x00000080
+
+#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
+#define FILE_NO_EA_KNOWLEDGE 0x00000200
+//UNUSED 0x00000400
+#define FILE_RANDOM_ACCESS 0x00000800
+
+#define FILE_DELETE_ON_CLOSE 0x00001000
+#define FILE_OPEN_BY_FILE_ID 0x00002000
+#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
+#define FILE_NO_COMPRESSION 0x00008000
+
+
+#define FILE_RESERVE_OPFILTER 0x00100000
+#define FILE_TRANSACTED_MODE 0x00200000
+#define FILE_OPEN_OFFLINE_FILE 0x00400000
+
+#define FILE_VALID_OPTION_FLAGS 0x007fffff
+#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032
+#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032
+#define FILE_VALID_SET_FLAGS 0x00000036
+
+//
+// Define the I/O status information return values for NtCreateFile/NtOpenFile
+//
+
+#define FILE_SUPERSEDED 0x00000000
+#define FILE_OPENED 0x00000001
+#define FILE_CREATED 0x00000002
+#define FILE_OVERWRITTEN 0x00000003
+#define FILE_EXISTS 0x00000004
+#define FILE_DOES_NOT_EXIST 0x00000005
+
+//
+// Define special ByteOffset parameters for read and write operations
+//
+
+#define FILE_WRITE_TO_END_OF_FILE 0xffffffff
+#define FILE_USE_FILE_POINTER_POSITION 0xfffffffe
+
+//
+// Define alignment requirement values
+//
+
+#define FILE_BYTE_ALIGNMENT 0x00000000
+#define FILE_WORD_ALIGNMENT 0x00000001
+#define FILE_LONG_ALIGNMENT 0x00000003
+#define FILE_QUAD_ALIGNMENT 0x00000007
+#define FILE_OCTA_ALIGNMENT 0x0000000f
+#define FILE_32_BYTE_ALIGNMENT 0x0000001f
+#define FILE_64_BYTE_ALIGNMENT 0x0000003f
+#define FILE_128_BYTE_ALIGNMENT 0x0000007f
+#define FILE_256_BYTE_ALIGNMENT 0x000000ff
+#define FILE_512_BYTE_ALIGNMENT 0x000001ff
+
+//
+// Define the maximum length of a filename string
+//
+
+#define MAXIMUM_FILENAME_LENGTH 256
+
+//
+// Define the various device characteristics flags
+//
+
+#define FILE_REMOVABLE_MEDIA 0x00000001
+#define FILE_READ_ONLY_DEVICE 0x00000002
+#define FILE_FLOPPY_DISKETTE 0x00000004
+#define FILE_WRITE_ONCE_MEDIA 0x00000008
+#define FILE_REMOTE_DEVICE 0x00000010
+#define FILE_DEVICE_IS_MOUNTED 0x00000020
+#define FILE_VIRTUAL_VOLUME 0x00000040
+
+#ifndef _FILESYSTEMFSCTL_
+#define _FILESYSTEMFSCTL_
+
+#endif // _FILESYSTEMFSCTL_
+
+//
+// The following is a list of the native file system fsctls followed by
+// additional network file system fsctls. Some values have been
+// decommissioned.
+//
+
+#define FSCTL_REQUEST_OPLOCK_LEVEL_1 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_REQUEST_OPLOCK_LEVEL_2 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_REQUEST_BATCH_OPLOCK CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_OPLOCK_BREAK_ACKNOWLEDGE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 3, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_OPBATCH_ACK_CLOSE_PENDING CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 4, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_OPLOCK_BREAK_NOTIFY CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 5, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_LOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_UNLOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_DISMOUNT_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
+// decommissioned fsctl value 9
+#define FSCTL_IS_VOLUME_MOUNTED CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 10, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_IS_PATHNAME_VALID CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 11, METHOD_BUFFERED, FILE_ANY_ACCESS) // PATHNAME_BUFFER,
+#define FSCTL_MARK_VOLUME_DIRTY CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
+// decommissioned fsctl value 13
+#define FSCTL_QUERY_RETRIEVAL_POINTERS CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 14, METHOD_NEITHER, FILE_ANY_ACCESS)
+#define FSCTL_GET_COMPRESSION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_SET_COMPRESSION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 16, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
+// decommissioned fsctl value 17
+// decommissioned fsctl value 18
+#define FSCTL_MARK_AS_SYSTEM_HIVE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 19, METHOD_NEITHER, FILE_ANY_ACCESS)
+#define FSCTL_OPLOCK_BREAK_ACK_NO_2 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 20, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_INVALIDATE_VOLUMES CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 21, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_QUERY_FAT_BPB CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 22, METHOD_BUFFERED, FILE_ANY_ACCESS) // FSCTL_QUERY_FAT_BPB_BUFFER
+#define FSCTL_REQUEST_FILTER_OPLOCK CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 23, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_FILESYSTEM_GET_STATISTICS CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 24, METHOD_BUFFERED, FILE_ANY_ACCESS) // FILESYSTEM_STATISTICS
+#if(_WIN32_WINNT >= 0x0400)
+#define FSCTL_GET_NTFS_VOLUME_DATA CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 25, METHOD_BUFFERED, FILE_ANY_ACCESS) // NTFS_VOLUME_DATA_BUFFER
+#define FSCTL_GET_NTFS_FILE_RECORD CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 26, METHOD_BUFFERED, FILE_ANY_ACCESS) // NTFS_FILE_RECORD_INPUT_BUFFER, NTFS_FILE_RECORD_OUTPUT_BUFFER
+#define FSCTL_GET_VOLUME_BITMAP CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 27, METHOD_NEITHER, FILE_ANY_ACCESS) // STARTING_LCN_INPUT_BUFFER, VOLUME_BITMAP_BUFFER
+#define FSCTL_GET_RETRIEVAL_POINTERS CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 28, METHOD_NEITHER, FILE_ANY_ACCESS) // STARTING_VCN_INPUT_BUFFER, RETRIEVAL_POINTERS_BUFFER
+#define FSCTL_MOVE_FILE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 29, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // MOVE_FILE_DATA,
+#define FSCTL_IS_VOLUME_DIRTY CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 30, METHOD_BUFFERED, FILE_ANY_ACCESS)
+// decomissioned fsctl value 31
+#define FSCTL_ALLOW_EXTENDED_DASD_IO CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 32, METHOD_NEITHER, FILE_ANY_ACCESS)
+#endif /* _WIN32_WINNT >= 0x0400 */
+
+//
+// Define the base asynchronous I/O argument types
+//
+
+typedef struct _IO_STATUS_BLOCK {
+ NTSTATUS Status;
+ ULONG Information;
+} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
+
+//
+// Define an Asynchronous Procedure Call from I/O viewpoint
+//
+
+typedef
+VOID
+(*PIO_APC_ROUTINE) (
+ IN PVOID ApcContext,
+ IN PIO_STATUS_BLOCK IoStatusBlock,
+ IN ULONG Reserved
+ );
+
+//
+// Define the file information class values
+//
+// WARNING: The order of the following values are assumed by the I/O system.
+// Any changes made here should be reflected there as well.
+//
+
+typedef enum _FILE_INFORMATION_CLASS {
+ FileDirectoryInformation = 1,
+ FileFullDirectoryInformation,
+ FileBothDirectoryInformation,
+ FileBasicInformation,
+ FileStandardInformation,
+ FileInternalInformation,
+ FileEaInformation,
+ FileAccessInformation,
+ FileNameInformation,
+ FileRenameInformation,
+ FileLinkInformation,
+ FileNamesInformation,
+ FileDispositionInformation,
+ FilePositionInformation,
+ FileFullEaInformation,
+ FileModeInformation,
+ FileAlignmentInformation,
+ FileAllInformation,
+ FileAllocationInformation,
+ FileEndOfFileInformation,
+ FileAlternateNameInformation,
+ FileStreamInformation,
+ FilePipeInformation,
+ FilePipeLocalInformation,
+ FilePipeRemoteInformation,
+ FileMailslotQueryInformation,
+ FileMailslotSetInformation,
+ FileCompressionInformation,
+ FileCopyOnWriteInformation,
+ FileCompletionInformation,
+ FileMoveClusterInformation,
+ FileOleClassIdInformation,
+ FileOleStateBitsInformation,
+ FileNetworkOpenInformation,
+ FileObjectIdInformation,
+ FileOleAllInformation,
+ FileOleDirectoryInformation,
+ FileContentIndexInformation,
+ FileInheritContentIndexInformation,
+ FileOleInformation,
+ FileMaximumInformation
+} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
+
+//
+// Define the various structures which are returned on query operations
+//
+
+typedef struct _FILE_BASIC_INFORMATION {
+ LARGE_INTEGER CreationTime;
+ LARGE_INTEGER LastAccessTime;
+ LARGE_INTEGER LastWriteTime;
+ LARGE_INTEGER ChangeTime;
+ ULONG FileAttributes;
+} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
+
+typedef struct _FILE_STANDARD_INFORMATION {
+ LARGE_INTEGER AllocationSize;
+ LARGE_INTEGER EndOfFile;
+ ULONG NumberOfLinks;
+ BOOLEAN DeletePending;
+ BOOLEAN Directory;
+} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
+
+typedef struct _FILE_POSITION_INFORMATION {
+ LARGE_INTEGER CurrentByteOffset;
+} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
+
+typedef struct _FILE_ALIGNMENT_INFORMATION {
+ ULONG AlignmentRequirement;
+} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION;
+
+typedef struct _FILE_NETWORK_OPEN_INFORMATION {
+ LARGE_INTEGER CreationTime;
+ LARGE_INTEGER LastAccessTime;
+ LARGE_INTEGER LastWriteTime;
+ LARGE_INTEGER ChangeTime;
+ LARGE_INTEGER AllocationSize;
+ LARGE_INTEGER EndOfFile;
+ ULONG FileAttributes;
+} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;
+
+typedef struct _FILE_DISPOSITION_INFORMATION {
+ BOOLEAN DeleteFile;
+} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;
+
+typedef struct _FILE_END_OF_FILE_INFORMATION {
+ LARGE_INTEGER EndOfFile;
+} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;
+
+
+typedef struct _FILE_FULL_EA_INFORMATION {
+ ULONG NextEntryOffset;
+ UCHAR Flags;
+ UCHAR EaNameLength;
+ USHORT EaValueLength;
+ CHAR EaName[1];
+} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
+
+//
+// Define the file system information class values
+//
+// WARNING: The order of the following values are assumed by the I/O system.
+// Any changes made here should be reflected there as well.
+
+typedef enum _FSINFOCLASS {
+ FileFsVolumeInformation = 1,
+ FileFsLabelInformation,
+ FileFsSizeInformation,
+ FileFsDeviceInformation,
+ FileFsAttributeInformation,
+ FileFsControlInformation,
+ FileFsQuotaQueryInformation, // temporary
+ FileFsQuotaSetInformation, // temporary
+ FileFsMaximumInformation
+} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
+
+typedef struct _FILE_FS_DEVICE_INFORMATION {
+ DEVICE_TYPE DeviceType;
+ ULONG Characteristics;
+} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
+
+//
+// Registry Specific Access Rights.
+//
+
+#define KEY_QUERY_VALUE (0x0001)
+#define KEY_SET_VALUE (0x0002)
+#define KEY_CREATE_SUB_KEY (0x0004)
+#define KEY_ENUMERATE_SUB_KEYS (0x0008)
+#define KEY_NOTIFY (0x0010)
+#define KEY_CREATE_LINK (0x0020)
+
+#define KEY_READ ((STANDARD_RIGHTS_READ |\
+ KEY_QUERY_VALUE |\
+ KEY_ENUMERATE_SUB_KEYS |\
+ KEY_NOTIFY) \
+ & \
+ (~SYNCHRONIZE))
+
+
+#define KEY_WRITE ((STANDARD_RIGHTS_WRITE |\
+ KEY_SET_VALUE |\
+ KEY_CREATE_SUB_KEY) \
+ & \
+ (~SYNCHRONIZE))
+
+#define KEY_EXECUTE ((KEY_READ) \
+ & \
+ (~SYNCHRONIZE))
+
+#define KEY_ALL_ACCESS ((STANDARD_RIGHTS_ALL |\
+ KEY_QUERY_VALUE |\
+ KEY_SET_VALUE |\
+ KEY_CREATE_SUB_KEY |\
+ KEY_ENUMERATE_SUB_KEYS |\
+ KEY_NOTIFY |\
+ KEY_CREATE_LINK) \
+ & \
+ (~SYNCHRONIZE))
+
+//
+// Open/Create Options
+//
+
+#define REG_OPTION_RESERVED (0x00000000L) // Parameter is reserved
+
+#define REG_OPTION_NON_VOLATILE (0x00000000L) // Key is preserved
+ // when system is rebooted
+
+#define REG_OPTION_VOLATILE (0x00000001L) // Key is not preserved
+ // when system is rebooted
+
+#define REG_OPTION_CREATE_LINK (0x00000002L) // Created key is a
+ // symbolic link
+
+#define REG_OPTION_BACKUP_RESTORE (0x00000004L) // open for backup or restore
+ // special access rules
+ // privilege required
+
+#define REG_OPTION_OPEN_LINK (0x00000008L) // Open symbolic link
+
+#define REG_LEGAL_OPTION \
+ (REG_OPTION_RESERVED |\
+ REG_OPTION_NON_VOLATILE |\
+ REG_OPTION_VOLATILE |\
+ REG_OPTION_CREATE_LINK |\
+ REG_OPTION_BACKUP_RESTORE |\
+ REG_OPTION_OPEN_LINK)
+
+//
+// Key creation/open disposition
+//
+
+#define REG_CREATED_NEW_KEY (0x00000001L) // New Registry Key created
+#define REG_OPENED_EXISTING_KEY (0x00000002L) // Existing Key opened
+
+//
+// Key restore flags
+//
+
+#define REG_WHOLE_HIVE_VOLATILE (0x00000001L) // Restore whole hive volatile
+#define REG_REFRESH_HIVE (0x00000002L) // Unwind changes to last flush
+#define REG_NO_LAZY_FLUSH (0x00000004L) // Never lazy flush this hive
+
+//
+// Key query structures
+//
+
+typedef struct _KEY_BASIC_INFORMATION {
+ LARGE_INTEGER LastWriteTime;
+ ULONG TitleIndex;
+ ULONG NameLength;
+ WCHAR Name[1]; // Variable length string
+} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;
+
+typedef struct _KEY_NODE_INFORMATION {
+ LARGE_INTEGER LastWriteTime;
+ ULONG TitleIndex;
+ ULONG ClassOffset;
+ ULONG ClassLength;
+ ULONG NameLength;
+ WCHAR Name[1]; // Variable length string
+// Class[1]; // Variable length string not declared
+} KEY_NODE_INFORMATION, *PKEY_NODE_INFORMATION;
+
+typedef struct _KEY_FULL_INFORMATION {
+ LARGE_INTEGER LastWriteTime;
+ ULONG TitleIndex;
+ ULONG ClassOffset;
+ ULONG ClassLength;
+ ULONG SubKeys;
+ ULONG MaxNameLen;
+ ULONG MaxClassLen;
+ ULONG Values;
+ ULONG MaxValueNameLen;
+ ULONG MaxValueDataLen;
+ WCHAR Class[1]; // Variable length
+} KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION;
+
+typedef enum _KEY_INFORMATION_CLASS {
+ KeyBasicInformation,
+ KeyNodeInformation,
+ KeyFullInformation
+} KEY_INFORMATION_CLASS;
+
+typedef struct _KEY_WRITE_TIME_INFORMATION {
+ LARGE_INTEGER LastWriteTime;
+} KEY_WRITE_TIME_INFORMATION, *PKEY_WRITE_TIME_INFORMATION;
+
+typedef enum _KEY_SET_INFORMATION_CLASS {
+ KeyWriteTimeInformation
+} KEY_SET_INFORMATION_CLASS;
+
+//
+// Value entry query structures
+//
+
+typedef struct _KEY_VALUE_BASIC_INFORMATION {
+ ULONG TitleIndex;
+ ULONG Type;
+ ULONG NameLength;
+ WCHAR Name[1]; // Variable size
+} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;
+
+typedef struct _KEY_VALUE_FULL_INFORMATION {
+ ULONG TitleIndex;
+ ULONG Type;
+ ULONG DataOffset;
+ ULONG DataLength;
+ ULONG NameLength;
+ WCHAR Name[1]; // Variable size
+// Data[1]; // Variable size data not declared
+} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;
+
+typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
+ ULONG TitleIndex;
+ ULONG Type;
+ ULONG DataLength;
+ UCHAR Data[1]; // Variable size
+} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
+
+typedef struct _KEY_VALUE_ENTRY {
+ PUNICODE_STRING ValueName;
+ ULONG DataLength;
+ ULONG DataOffset;
+ ULONG Type;
+} KEY_VALUE_ENTRY, *PKEY_VALUE_ENTRY;
+
+typedef enum _KEY_VALUE_INFORMATION_CLASS {
+ KeyValueBasicInformation,
+ KeyValueFullInformation,
+ KeyValuePartialInformation
+} KEY_VALUE_INFORMATION_CLASS;
+
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+NtEnumerateKey(
+ IN HANDLE KeyHandle,
+ IN ULONG Index,
+ IN KEY_INFORMATION_CLASS KeyInformationClass,
+ IN PVOID KeyInformation,
+ IN ULONG Length,
+ IN PULONG ResultLength
+ );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+NtOpenKey(
+ OUT PHANDLE KeyHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes
+ );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+NtQueryValueKey(
+ IN HANDLE KeyHandle,
+ IN PUNICODE_STRING ValueName,
+ IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
+ IN PVOID KeyValueInformation,
+ IN ULONG Length,
+ IN PULONG ResultLength
+ );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+NtSetValueKey(
+ IN HANDLE KeyHandle,
+ IN PUNICODE_STRING ValueName,
+ IN ULONG TitleIndex OPTIONAL,
+ IN ULONG Type,
+ IN PVOID Data,
+ IN ULONG DataSize
+ );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+NtDeleteValueKey(
+ IN HANDLE KeyHandle,
+ IN PUNICODE_STRING ValueName
+ );
+
+
+#define OBJ_NAME_PATH_SEPARATOR ((WCHAR)L'\\')
+
+//
+// Object Manager Object Type Specific Access Rights.
+//
+
+#define OBJECT_TYPE_CREATE (0x0001)
+
+#define OBJECT_TYPE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)
+
+//
+// Object Manager Directory Specific Access Rights.
+//
+
+#define DIRECTORY_QUERY (0x0001)
+#define DIRECTORY_TRAVERSE (0x0002)
+#define DIRECTORY_CREATE_OBJECT (0x0004)
+#define DIRECTORY_CREATE_SUBDIRECTORY (0x0008)
+
+#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)
+
+//
+// Object Manager Symbolic Link Specific Access Rights.
+//
+
+#define SYMBOLIC_LINK_QUERY (0x0001)
+
+#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)
+
+typedef struct _OBJECT_NAME_INFORMATION {
+ UNICODE_STRING Name;
+} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
+
+//
+// Section Information Structures.
+//
+
+typedef enum _SECTION_INHERIT {
+ ViewShare = 1,
+ ViewUnmap = 2
+} SECTION_INHERIT;
+
+//
+// Section Access Rights.
+//
+
+// begin_winnt
+#define SECTION_QUERY 0x0001
+#define SECTION_MAP_WRITE 0x0002
+#define SECTION_MAP_READ 0x0004
+#define SECTION_MAP_EXECUTE 0x0008
+#define SECTION_EXTEND_SIZE 0x0010
+
+#define SECTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SECTION_QUERY|\
+ SECTION_MAP_WRITE | \
+ SECTION_MAP_READ | \
+ SECTION_MAP_EXECUTE | \
+ SECTION_EXTEND_SIZE)
+// end_winnt
+
+#define SEGMENT_ALL_ACCESS SECTION_ALL_ACCESS
+
+#define PAGE_NOACCESS 0x01 // winnt
+#define PAGE_READONLY 0x02 // winnt
+#define PAGE_READWRITE 0x04 // winnt
+#define PAGE_WRITECOPY 0x08 // winnt
+#define PAGE_EXECUTE 0x10 // winnt
+#define PAGE_EXECUTE_READ 0x20 // winnt
+#define PAGE_EXECUTE_READWRITE 0x40 // winnt
+#define PAGE_EXECUTE_WRITECOPY 0x80 // winnt
+#define PAGE_GUARD 0x100 // winnt
+#define PAGE_NOCACHE 0x200 // winnt
+
+#define MEM_COMMIT 0x1000
+#define MEM_RESERVE 0x2000
+#define MEM_DECOMMIT 0x4000
+#define MEM_RELEASE 0x8000
+#define MEM_FREE 0x10000
+#define MEM_PRIVATE 0x20000
+#define MEM_MAPPED 0x40000
+#define MEM_RESET 0x80000
+#define MEM_TOP_DOWN 0x100000
+#define MEM_LARGE_PAGES 0x20000000
+#define SEC_RESERVE 0x4000000
+#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
+ 0xFFF)
+
+
+#define MAXIMUM_PROCESSORS 32
+
+// end_winnt
+
+//
+// Thread Specific Access Rights
+//
+
+#define THREAD_TERMINATE (0x0001) // winnt
+#define THREAD_SET_INFORMATION (0x0020) // winnt
+
+#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
+ 0x3FF)
+
+//
+// ClientId
+//
+
+typedef struct _CLIENT_ID {
+ HANDLE UniqueProcess;
+ HANDLE UniqueThread;
+} CLIENT_ID;
+typedef CLIENT_ID *PCLIENT_ID;
+
+//
+// Define the size of the 80387 save area, which is in the context frame.
+//
+
+#define SIZE_OF_80387_REGISTERS 80
+
+//
+// The following flags control the contents of the CONTEXT structure.
+//
+
+#if !defined(RC_INVOKED)
+
+#define CONTEXT_i386 0x00010000 // this assumes that i386 and
+#define CONTEXT_i486 0x00010000 // i486 have identical context records
+
+// end_wx86
+
+#define CONTEXT_CONTROL (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP
+#define CONTEXT_INTEGER (CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI
+#define CONTEXT_SEGMENTS (CONTEXT_i386 | 0x00000004L) // DS, ES, FS, GS
+#define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 0x00000008L) // 387 state
+#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x00000010L) // DB 0-3,6,7
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER |\
+ CONTEXT_SEGMENTS)
+
+// begin_wx86
+
+#endif
+
+typedef struct _FLOATING_SAVE_AREA {
+ ULONG ControlWord;
+ ULONG StatusWord;
+ ULONG TagWord;
+ ULONG ErrorOffset;
+ ULONG ErrorSelector;
+ ULONG DataOffset;
+ ULONG DataSelector;
+ UCHAR RegisterArea[SIZE_OF_80387_REGISTERS];
+ ULONG Cr0NpxState;
+} FLOATING_SAVE_AREA;
+
+typedef FLOATING_SAVE_AREA *PFLOATING_SAVE_AREA;
+
+//
+// Context Frame
+//
+// This frame has a several purposes: 1) it is used as an argument to
+// NtContinue, 2) is is used to constuct a call frame for APC delivery,
+// and 3) it is used in the user level thread creation routines.
+//
+// The layout of the record conforms to a standard call frame.
+//
+
+typedef struct _CONTEXT {
+
+ //
+ // The flags values within this flag control the contents of
+ // a CONTEXT record.
+ //
+ // If the context record is used as an&nbs