Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534/* * COPYRIGHT: See COPYRIGHT.TXT * PROJECT: Ext2 File System Driver for WinNT/2K/XP * FILE: misc.c * PROGRAMMER: Matt Wu <mattwu@163.com> * HOMEPAGE: http://www.ext2fsd.com * UPDATE HISTORY: */
/* INCLUDES *****************************************************************/
#include "ext2fs.h"
/* GLOBALS ***************************************************************/
extern PEXT2_GLOBAL Ext2Global;
/* DEFINITIONS *************************************************************/
#ifdef ALLOC_PRAGMA#pragma alloc_text(PAGE, Ext2Sleep)#endif
ULONGExt2Log2(ULONG Value){ ULONG Order = 0;
ASSERT(Value > 0);
while (Value) { Order++; Value >>= 1; }
return (Order - 1);}
LARGE_INTEGERExt2NtTime (IN ULONG i_time){ LARGE_INTEGER SysTime;
SysTime.QuadPart = 0; RtlSecondsSince1970ToTime(i_time, &SysTime);
return SysTime;}
ULONGExt2LinuxTime (IN LARGE_INTEGER SysTime){ ULONG Ext2Time = 0;
if (!RtlTimeToSecondsSince1970(&SysTime, &Ext2Time)) { LARGE_INTEGER NtTime; KeQuerySystemTime(&NtTime); RtlTimeToSecondsSince1970(&NtTime, &Ext2Time); }
return Ext2Time;}
ULONGExt2MbsToUnicode( struct nls_table * PageTable, IN OUT PUNICODE_STRING Unicode, IN PANSI_STRING Mbs ){ ULONG Length = 0; int i, mbc = 0; WCHAR uc;
/* Count the length of the resulting Unicode. */ for (i = 0; i < Mbs->Length; i += mbc) {
mbc = PageTable->char2uni( (PUCHAR)&(Mbs->Buffer[i]), Mbs->Length - i, &uc );
if (mbc <= 0) {
/* invalid character. */ if (mbc == 0 && Length > 0) { break; } return 0; }
Length += 2; }
if (Unicode) { if (Unicode->MaximumLength < Length) {
DbgBreak(); return 0; }
Unicode->Length = 0; mbc = 0;
for (i = 0; i < Mbs->Length; i += mbc) {
mbc = PageTable->char2uni( (PUCHAR)&(Mbs->Buffer[i]), Mbs->Length - i, &uc ); Unicode->Buffer[Unicode->Length/2] = uc; Unicode->Length += 2; } }
return Length;}
ULONGExt2UnicodeToMbs ( struct nls_table * PageTable, IN OUT PANSI_STRING Mbs, IN PUNICODE_STRING Unicode){ ULONG Length = 0; UCHAR mbs[0x10]; int i, mbc;
/* Count the length of the resulting mbc-8. */ for (i = 0; i < (Unicode->Length / 2); i++) {
RtlZeroMemory(mbs, 0x10); mbc = PageTable->uni2char( Unicode->Buffer[i], mbs, 0x10 );
if (mbc <= 0) {
/* Invalid character. */ return 0; }
Length += mbc; }
if (Mbs) {
if (Mbs->MaximumLength < Length) {
DbgBreak(); return 0; }
Mbs->Length = 0;
for (i = 0; i < (Unicode->Length / 2); i++) {
mbc = PageTable->uni2char( Unicode->Buffer[i], mbs, 0x10 );
RtlCopyMemory( (PUCHAR)&(Mbs->Buffer[Mbs->Length]), &mbs[0], mbc );
Mbs->Length += (USHORT)mbc; } }
return Length;}
ULONGExt2OEMToUnicodeSize( IN PEXT2_VCB Vcb, IN PANSI_STRING Oem){ ULONG Length = 0;
if (Vcb->Codepage.PageTable) { Length = Ext2MbsToUnicode(Vcb->Codepage.PageTable, NULL, Oem); if (Length > 0) { goto errorout; } }
Length = RtlOemStringToCountedUnicodeSize(Oem);
errorout:
return Length;}
NTSTATUSExt2OEMToUnicode( IN PEXT2_VCB Vcb, IN OUT PUNICODE_STRING Unicode, IN POEM_STRING Oem){ NTSTATUS Status;
if (Vcb->Codepage.PageTable) { Status = Ext2MbsToUnicode(Vcb->Codepage.PageTable, Unicode, Oem);
if (Status >0 && Status == Unicode->Length) { Status = STATUS_SUCCESS; goto errorout; } }
Status = RtlOemStringToUnicodeString( Unicode, Oem, FALSE );
if (!NT_SUCCESS(Status)) { DbgBreak(); goto errorout; }
errorout:
return Status;}
ULONGExt2UnicodeToOEMSize( IN PEXT2_VCB Vcb, IN PUNICODE_STRING Unicode){ ULONG Length = 0;
if (Vcb->Codepage.PageTable) { Length = Ext2UnicodeToMbs(Vcb->Codepage.PageTable, NULL, Unicode); if (Length > 0) { return Length; }
DbgBreak(); }
return RtlxUnicodeStringToOemSize(Unicode);}
NTSTATUSExt2UnicodeToOEM ( IN PEXT2_VCB Vcb, IN OUT POEM_STRING Oem, IN PUNICODE_STRING Unicode){ NTSTATUS Status;
if (Vcb->Codepage.PageTable) {
Status = Ext2UnicodeToMbs(Vcb->Codepage.PageTable, Oem, Unicode); if (Status > 0 && Status == Oem->Length) { Status = STATUS_SUCCESS; } else { Status = STATUS_UNSUCCESSFUL; DbgBreak(); }
goto errorout; }
Status = RtlUnicodeStringToOemString( Oem, Unicode, FALSE );
if (!NT_SUCCESS(Status)) { DbgBreak(); goto errorout; }
errorout:
return Status;}
VOIDExt2Sleep(ULONG ms){ LARGE_INTEGER Timeout; Timeout.QuadPart = (LONGLONG)ms*1000*(-10); /* ms/1000 sec*/ KeDelayExecutionThread(KernelMode, TRUE, &Timeout);}
int Ext2LinuxError (NTSTATUS Status){ switch (Status) { case STATUS_ACCESS_DENIED: return (-EACCES);
case STATUS_ACCESS_VIOLATION: return (-EFAULT);
case STATUS_BUFFER_TOO_SMALL: return (-ETOOSMALL);
case STATUS_INVALID_PARAMETER: return (-EINVAL);
case STATUS_NOT_IMPLEMENTED: case STATUS_NOT_SUPPORTED: return (-EOPNOTSUPP);
case STATUS_INVALID_ADDRESS: case STATUS_INVALID_ADDRESS_COMPONENT: return (-EADDRNOTAVAIL);
case STATUS_NO_SUCH_DEVICE: case STATUS_NO_SUCH_FILE: case STATUS_OBJECT_NAME_NOT_FOUND: case STATUS_OBJECT_PATH_NOT_FOUND: case STATUS_NETWORK_BUSY: case STATUS_INVALID_NETWORK_RESPONSE: case STATUS_UNEXPECTED_NETWORK_ERROR: return (-ENETDOWN);
case STATUS_BAD_NETWORK_PATH: case STATUS_NETWORK_UNREACHABLE: case STATUS_PROTOCOL_UNREACHABLE: return (-ENETUNREACH);
case STATUS_LOCAL_DISCONNECT: case STATUS_TRANSACTION_ABORTED: case STATUS_CONNECTION_ABORTED: return (-ECONNABORTED);
case STATUS_REMOTE_DISCONNECT: case STATUS_LINK_FAILED: case STATUS_CONNECTION_DISCONNECTED: case STATUS_CONNECTION_RESET: case STATUS_PORT_UNREACHABLE: return (-ECONNRESET);
case STATUS_INSUFFICIENT_RESOURCES: return (-ENOMEM);
case STATUS_PAGEFILE_QUOTA: case STATUS_NO_MEMORY: case STATUS_CONFLICTING_ADDRESSES: case STATUS_QUOTA_EXCEEDED: case STATUS_TOO_MANY_PAGING_FILES: case STATUS_WORKING_SET_QUOTA: case STATUS_COMMITMENT_LIMIT: case STATUS_TOO_MANY_ADDRESSES: case STATUS_REMOTE_RESOURCES: return (-ENOBUFS);
case STATUS_INVALID_CONNECTION: return (-ENOTCONN);
case STATUS_PIPE_DISCONNECTED: return (-ESHUTDOWN);
case STATUS_TIMEOUT: case STATUS_IO_TIMEOUT: case STATUS_LINK_TIMEOUT: return (-ETIMEDOUT);
case STATUS_REMOTE_NOT_LISTENING: case STATUS_CONNECTION_REFUSED: return (-ECONNREFUSED);
case STATUS_HOST_UNREACHABLE: return (-EHOSTUNREACH);
case STATUS_CANT_WAIT: case STATUS_PENDING: return (-EAGAIN);
case STATUS_DEVICE_NOT_READY: return (-EIO);
case STATUS_CANCELLED: case STATUS_REQUEST_ABORTED: return (-EINTR);
case STATUS_BUFFER_OVERFLOW: case STATUS_INVALID_BUFFER_SIZE: return (-EMSGSIZE);
case STATUS_ADDRESS_ALREADY_EXISTS: return (-EADDRINUSE); }
if (NT_SUCCESS (Status)) return 0;
return (-EINVAL);}
NTSTATUS Ext2WinntError(int rc){ switch (rc) {
case 0: return STATUS_SUCCESS;
case -EPERM: case -EACCES: return STATUS_ACCESS_DENIED;
case -ENOENT: return STATUS_OBJECT_NAME_NOT_FOUND;
case -EFAULT: return STATUS_ACCESS_VIOLATION;
case -ETOOSMALL: return STATUS_BUFFER_TOO_SMALL;
case -EBADMSG: case -EBADF: case -EINVAL: case -EFBIG: return STATUS_INVALID_PARAMETER;
case -EBUSY: return STATUS_DEVICE_BUSY;
case -ENOSYS: return STATUS_NOT_IMPLEMENTED;
case -ENOSPC: return STATUS_DISK_FULL;
case -EOPNOTSUPP: return STATUS_NOT_SUPPORTED;
case -EDEADLK: return STATUS_POSSIBLE_DEADLOCK;
case -EEXIST: return STATUS_OBJECT_NAME_COLLISION;
case -EIO: return STATUS_UNEXPECTED_IO_ERROR;
case -ENOTDIR: return STATUS_NOT_A_DIRECTORY;
case -EISDIR: return STATUS_FILE_IS_A_DIRECTORY;
case -ENOTEMPTY: return STATUS_DIRECTORY_NOT_EMPTY;
case -ENODEV: return STATUS_NO_SUCH_DEVICE;
case -ENXIO: return STATUS_INVALID_ADDRESS;
case -EADDRNOTAVAIL: return STATUS_INVALID_ADDRESS;
case -ENETDOWN: return STATUS_UNEXPECTED_NETWORK_ERROR;
case -ENETUNREACH: return STATUS_NETWORK_UNREACHABLE;
case -ECONNABORTED: return STATUS_CONNECTION_ABORTED;
case -ECONNRESET: return STATUS_CONNECTION_RESET;
case -ENOMEM: return STATUS_INSUFFICIENT_RESOURCES;
case -ENOBUFS: return STATUS_NO_MEMORY;
case -ENOTCONN: return STATUS_INVALID_CONNECTION;
case -ESHUTDOWN: return STATUS_CONNECTION_DISCONNECTED;
case -ETIMEDOUT: return STATUS_TIMEOUT;
case -ECONNREFUSED: return STATUS_CONNECTION_REFUSED;
case -EHOSTUNREACH: return STATUS_HOST_UNREACHABLE;
case -EAGAIN: return STATUS_CANT_WAIT;
case -EINTR: return STATUS_CANCELLED;
case -EMSGSIZE: return STATUS_INVALID_BUFFER_SIZE;
case -EADDRINUSE: return STATUS_ADDRESS_ALREADY_EXISTS; }
return STATUS_UNSUCCESSFUL;}
BOOLEAN Ext2IsDot(PUNICODE_STRING name){ return (name->Length == 2 && name->Buffer[0] == L'.');}
BOOLEAN Ext2IsDotDot(PUNICODE_STRING name){ return (name->Length == 4 && name->Buffer[0] == L'.' && name->Buffer[1] == L'.');}