mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
Incorporated changed from Boudewijn
svn path=/trunk/; revision=206
This commit is contained in:
parent
d4195242ff
commit
67c37a748e
8 changed files with 796 additions and 649 deletions
|
@ -22,209 +22,6 @@ LPTOP_LEVEL_EXCEPTION_FILTER GlobalTopLevelExceptionFilter;
|
||||||
|
|
||||||
UINT GetErrorMode(void);
|
UINT GetErrorMode(void);
|
||||||
|
|
||||||
//FIXME Please remove comments in funcs.h
|
|
||||||
LPTOP_LEVEL_EXCEPTION_FILTER
|
|
||||||
STDCALL
|
|
||||||
SetUnhandledExceptionFilter(
|
|
||||||
LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// these are in various flavors
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum _EXCEPTION_DISPOSITION
|
|
||||||
{
|
|
||||||
ExceptionContinueExecution,
|
|
||||||
ExceptionContinueSearch,
|
|
||||||
ExceptionNestedException,
|
|
||||||
ExceptionCollidedUnwind
|
|
||||||
} EXCEPTION_DISPOSITION;
|
|
||||||
|
|
||||||
|
|
||||||
#define DISPOSITION_DISMISS 0
|
|
||||||
#define DISPOSITION_CONTINUE_SEARCH 1
|
|
||||||
#define DISPOSITION_NESTED_EXCEPTION 2
|
|
||||||
#define DISPOSITION_COLLIDED_UNWIND 3
|
|
||||||
|
|
||||||
// following values can be returned by exception filters
|
|
||||||
// in a try{} except() block.
|
|
||||||
|
|
||||||
//#define EXCEPTION_EXECUTE_HANDLER 1
|
|
||||||
//#define EXCEPTION_CONTINUE_SEARCH 0
|
|
||||||
//#define EXCEPTION_CONTINUE_EXECUTION -1
|
|
||||||
|
|
||||||
// OS/2 filter return codes
|
|
||||||
#define FILTER_ACCEPT 1
|
|
||||||
#define FILTER_DISMISS -1
|
|
||||||
#define FILTER_CONTINUE_SEARCH 0
|
|
||||||
|
|
||||||
|
|
||||||
#define TRYLEVEL_NONE -1
|
|
||||||
#define TRYLEVEL_INVALID -2
|
|
||||||
|
|
||||||
//callback interface codes (mimimal required set)
|
|
||||||
|
|
||||||
#define CB_GET_MAX_CODE 0
|
|
||||||
#define CB_DO_LOCAL_UNWIND 1
|
|
||||||
#define CB_GET_FRAME_EBP 2
|
|
||||||
#define CB_GET_SCOPE_INDEX 3
|
|
||||||
#define CB_GET_SCOPE_DATA 4
|
|
||||||
#define MAX_CALLBACK_CODE 4
|
|
||||||
|
|
||||||
|
|
||||||
#define EH_NONCONTINUABLE 1
|
|
||||||
#define EH_UNWINDING 2
|
|
||||||
#define EH_EXIT_UNWIND 4
|
|
||||||
#define EH_STACK_INVALID 8
|
|
||||||
#define EH_NESTED_CALL 16
|
|
||||||
|
|
||||||
//#define FACILITY_RPC_RUNTIME 2
|
|
||||||
//#define FACILITY_RPC_STUBS 3
|
|
||||||
//#define FACILITY_IO_ERROR_CODE 4
|
|
||||||
|
|
||||||
//#define SEVERITY_CODE_SUCCESS 0
|
|
||||||
//#define SEVERITY_CODE_INFORMATIONAL 1
|
|
||||||
//#define SEVERITY_CODE_WARNING 2
|
|
||||||
//#define SEVERITY_CODE_ERROR 3
|
|
||||||
|
|
||||||
|
|
||||||
#define XCPT_FATAL_EXCEPTION (0xC0000000)
|
|
||||||
#define XCPT_SEVERITY_CODE (0xC0000000)
|
|
||||||
#define XCPT_CUSTOMER_CODE (0x20000000)
|
|
||||||
#define XCPT_FACILITY_CODE (0x1FFF0000)
|
|
||||||
#define XCPT_EXCEPTION_CODE (0x0000FFFF)
|
|
||||||
|
|
||||||
|
|
||||||
// this is the definition of NTSTATUS
|
|
||||||
|
|
||||||
// definition of NTSTATUS
|
|
||||||
|
|
||||||
typedef struct _NTSTATUSDEF
|
|
||||||
{
|
|
||||||
USHORT Code;
|
|
||||||
USHORT Facility :12;
|
|
||||||
UCHAR Reserved : 1;
|
|
||||||
UCHAR CstCodeFlag : 1;
|
|
||||||
UCHAR Severity : 2;
|
|
||||||
} NTSTATUSDEF;
|
|
||||||
|
|
||||||
// Violation flags in ExceptionInfo
|
|
||||||
|
|
||||||
#define XCPT_UNKNOWN_ACCESS 0x00000000
|
|
||||||
#define XCPT_READ_ACCESS 0x00000001
|
|
||||||
#define XCPT_WRITE_ACCESS 0x00000002
|
|
||||||
#define XCPT_EXECUTE_ACCESS 0x00000004
|
|
||||||
#define XCPT_SPACE_ACCESS 0x00000008 // address space access violation
|
|
||||||
#define XCPT_LIMIT_ACCESS 0x00000010 // out of bounds
|
|
||||||
#define XCPT_DATA_UNKNOWN 0xFFFFFFFF
|
|
||||||
|
|
||||||
|
|
||||||
// some status values with corresponding ExceptionInfo values
|
|
||||||
|
|
||||||
//#define STATUS_GUARD_PAGE_VIOLATION 0x80000001
|
|
||||||
// ExceptionInfo[ 0 ] - Access Code: XCPT_READ_ACCESS | XCPT_WRITE_ACCESS
|
|
||||||
// ExceptionInfo[ 1 ] - FaultAddr
|
|
||||||
|
|
||||||
|
|
||||||
//#define STATUS_DATATYPE_MISALIGNMENT 0x80000002
|
|
||||||
// OS/2 XCPT is at 0xC000009E
|
|
||||||
// ExceptionInfo[ 0 ] - Access Code: XCPT_READ_ACCESS | XCPT_WRITE_ACCESS
|
|
||||||
// ExceptionInfo[ 1 ] - Alignment
|
|
||||||
// ExceptionInfo[ 2 ] - FaultAddr
|
|
||||||
|
|
||||||
|
|
||||||
//#define STATUS_ACCESS_VIOLATION 0xC0000005
|
|
||||||
// ExceptionInfo[ 0 ] - Access Code: XCPT_READ_ACCESS | XCPT_WRITE_ACCESS
|
|
||||||
// ExceptionInfo[ 1 ] - FaultAddr
|
|
||||||
|
|
||||||
|
|
||||||
//#define STATUS_IN_PAGE_ERROR 0xC0000006
|
|
||||||
// ExceptionInfo[ 0 ] - FaultAddr
|
|
||||||
|
|
||||||
//#define STATUS_NONCONTINUABLE_EXCEPTION 0xC0000025
|
|
||||||
//#define STATUS_INVALID_DISPOSITION 0xC0000026
|
|
||||||
|
|
||||||
|
|
||||||
// Exceptions generated by the exception handler
|
|
||||||
|
|
||||||
#define STATUS_UNWIND 0xC0000027
|
|
||||||
#define STATUS_BAD_STACK 0xC0000028
|
|
||||||
#define STATUS_INVALID_UNWIND_TARGET 0xC0000029
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _EXCEPTION_REGISTRATION;
|
|
||||||
|
|
||||||
typedef EXCEPTION_DISPOSITION
|
|
||||||
(STDCALL *ExceptionHandlerType)(
|
|
||||||
struct _EXCEPTION_RECORD *ExceptionRecord,
|
|
||||||
struct _EXCEPTION_REGISTRATION *EstablisherFrame,
|
|
||||||
struct _CONTEXT *Context,
|
|
||||||
struct _EXCEPTION_RECORD *DispatcherContext
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _SCOPE_TABLE {
|
|
||||||
DWORD prevTryLevel;
|
|
||||||
LPTOP_LEVEL_EXCEPTION_FILTER lpfnFilter;
|
|
||||||
ExceptionHandlerType lpfnHandler;
|
|
||||||
} SCOPE_TABLE , *PSCOPE_TABLE;
|
|
||||||
|
|
||||||
typedef struct _EXCEPTION_REGISTRATION {
|
|
||||||
struct _EXCEPTION_REGISTRATION *Prev;
|
|
||||||
ExceptionHandlerType Handler;
|
|
||||||
PSCOPE_TABLE ScopeTable;
|
|
||||||
unsigned int TryLevel;
|
|
||||||
unsigned int _ebp;
|
|
||||||
PEXCEPTION_POINTERS *Pointers;
|
|
||||||
} EXCEPTION_REGISTRATION, *PEXCEPTION_REGISTRATION;
|
|
||||||
|
|
||||||
#define END_OF_CHAIN ((PEXCEPTION_REGISTRATION) -1)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EXCEPTION_DISPOSITION
|
|
||||||
CDECL
|
|
||||||
ExceptionHandler(
|
|
||||||
struct _EXCEPTION_RECORD *ExceptionRecord,
|
|
||||||
struct _EXCEPTION_REGISTRATION *RegistrationFrame,
|
|
||||||
CONTEXT *Context,
|
|
||||||
struct _EXCEPTION_RECORD *DispatcherContext
|
|
||||||
);
|
|
||||||
|
|
||||||
void KiUserExceptionDispatcher(
|
|
||||||
struct _EXCEPTION_RECORD *ExceptionRecord,
|
|
||||||
CONTEXT *Context);
|
|
||||||
|
|
||||||
NTSTATUS RtlDispatchException(
|
|
||||||
struct _EXCEPTION_RECORD *ExceptionRecord,
|
|
||||||
CONTEXT *Context);
|
|
||||||
|
|
||||||
struct _EXCEPTION_REGISTRATION *RtlpGetRegistrationHead(VOID);
|
|
||||||
|
|
||||||
void RtlpCaptureContext(CONTEXT *Context);
|
|
||||||
void RtlpGetStackLimits(void *StackBase, void *StackLimit);
|
|
||||||
void RtlpUnlinkHandler(struct _EXCEPTION_REGISTRATION *__head);
|
|
||||||
void RtlpLinkHandler(struct _EXCEPTION_REGISTRATION *__head);
|
|
||||||
void RtlUnwind(struct _EXCEPTION_REGISTRATION *RegistratonFrame,
|
|
||||||
VOID *ReturnAddress, // Unused
|
|
||||||
struct _EXCEPTION_RECORD *ExceptionRecord,
|
|
||||||
DWORD _eax);
|
|
||||||
|
|
||||||
void RtlRaiseException(struct _EXCEPTION_RECORD *ExceptionRecord);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UINT GetErrorMode(void)
|
UINT GetErrorMode(void)
|
||||||
|
@ -260,91 +57,6 @@ SetUnhandledExceptionFilter(
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LONG
|
|
||||||
STDCALL
|
|
||||||
ExceptionFilter (
|
|
||||||
PEXCEPTION_POINTERS ExceptionInfo
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXCEPTION_DISPOSITION
|
|
||||||
CDECL
|
|
||||||
ExceptionHandler(
|
|
||||||
struct _EXCEPTION_RECORD *ExceptionRecord,
|
|
||||||
struct _EXCEPTION_REGISTRATION *RegistrationFrame,
|
|
||||||
CONTEXT *Context,
|
|
||||||
struct _EXCEPTION_RECORD *DispatcherContext
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int FilterRet;
|
|
||||||
unsigned int TryLevel;
|
|
||||||
EXCEPTION_POINTERS ExceptionPointers;
|
|
||||||
SCOPE_TABLE *ScopeTable;
|
|
||||||
unsigned int _ebp;
|
|
||||||
|
|
||||||
|
|
||||||
// __asm { cld };
|
|
||||||
|
|
||||||
if ( ExceptionRecord->ExceptionFlags != EH_UNWINDING &&
|
|
||||||
ExceptionRecord->ExceptionFlags != EH_EXIT_UNWIND )
|
|
||||||
{
|
|
||||||
ExceptionPointers.ExceptionRecord= ExceptionRecord;
|
|
||||||
ExceptionPointers.ContextRecord = Context;
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
TryLevel = RegistrationFrame->TryLevel;
|
|
||||||
|
|
||||||
ScopeTable = RegistrationFrame->ScopeTable;
|
|
||||||
|
|
||||||
if ( RegistrationFrame->TryLevel != TRYLEVEL_NONE )
|
|
||||||
{
|
|
||||||
if ( RegistrationFrame->ScopeTable[TryLevel].lpfnFilter != NULL)
|
|
||||||
{
|
|
||||||
_ebp = RegistrationFrame->_ebp;
|
|
||||||
//__asm { push ebp
|
|
||||||
// mov ebp, _ebp
|
|
||||||
//}
|
|
||||||
FilterRet = ScopeTable->lpfnFilter(NULL);
|
|
||||||
//__asm { pop ebp }
|
|
||||||
|
|
||||||
if ( FilterRet < 0 )
|
|
||||||
return ExceptionContinueExecution;
|
|
||||||
|
|
||||||
if ( FilterRet == EXCEPTION_EXECUTE_HANDLER )
|
|
||||||
{
|
|
||||||
ScopeTable = RegistrationFrame->ScopeTable;
|
|
||||||
RtlUnwind(RegistrationFrame,NULL,ExceptionRecord,0);
|
|
||||||
//__asm { mov ebp, _ebp }
|
|
||||||
// local unwind
|
|
||||||
// nlg
|
|
||||||
|
|
||||||
RegistrationFrame->TryLevel = ScopeTable->prevTryLevel;
|
|
||||||
RegistrationFrame->ScopeTable[TryLevel].lpfnHandler(ExceptionRecord,RegistrationFrame,Context, DispatcherContext);
|
|
||||||
NtContinue(Context,PASSIVE_LEVEL);
|
|
||||||
//return;
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ScopeTable = RegistrationFrame->ScopeTable;
|
|
||||||
TryLevel = ScopeTable->prevTryLevel;
|
|
||||||
// search for handler
|
|
||||||
return DISPOSITION_CONTINUE_SEARCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} else { // TRYLEVEL_NONE
|
|
||||||
return DISPOSITION_CONTINUE_SEARCH;
|
|
||||||
}
|
|
||||||
} else { // EXCEPTION_UNWINDING or EXCEPTION_EXIT_UNWIND
|
|
||||||
//
|
|
||||||
return DISPOSITION_CONTINUE_SEARCH;
|
|
||||||
}
|
|
||||||
return DISPOSITION_CONTINUE_SEARCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -399,226 +111,6 @@ UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord, PCONTEXT Context)
|
|
||||||
{
|
|
||||||
NTSTATUS errCode;
|
|
||||||
|
|
||||||
if ( RtlDispatchException(ExceptionRecord,Context) )
|
|
||||||
errCode = NtContinue(Context,PASSIVE_LEVEL);
|
|
||||||
else
|
|
||||||
errCode = NtRaiseException(ExceptionRecord,Context,(BOOLEAN)FALSE);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS RtlDispatchException(PEXCEPTION_RECORD ExceptionRecord, PCONTEXT Context)
|
|
||||||
{
|
|
||||||
NTSTATUS errCode;
|
|
||||||
ULONG StackBase, StackLimit;
|
|
||||||
PEXCEPTION_REGISTRATION RegistrationFrame;
|
|
||||||
EXCEPTION_RECORD DispatcherContext;
|
|
||||||
EXCEPTION_RECORD FatalExceptionRecord;
|
|
||||||
|
|
||||||
//RtlpGetStackLimits(&StackBase,&StackTop);
|
|
||||||
RegistrationFrame = RtlpGetRegistrationHead();
|
|
||||||
|
|
||||||
while( RegistrationFrame != END_OF_CHAIN ) {
|
|
||||||
|
|
||||||
//FIXME Check the stack
|
|
||||||
RtlpGetStackLimits(&StackBase, &StackLimit);
|
|
||||||
|
|
||||||
errCode = RegistrationFrame->Handler(
|
|
||||||
ExceptionRecord,
|
|
||||||
RegistrationFrame,
|
|
||||||
Context,
|
|
||||||
&DispatcherContext);
|
|
||||||
|
|
||||||
//errCode = RtlpExecuteHandlerForException(ExceptionRecord, RegistrationFrame,
|
|
||||||
// Context, &DispatcherContext);
|
|
||||||
|
|
||||||
if ( RegistrationFrame == NULL )
|
|
||||||
ExceptionRecord->ExceptionFlags &= ~EH_NESTED_CALL;
|
|
||||||
|
|
||||||
switch( errCode ) {
|
|
||||||
case DISPOSITION_DISMISS:
|
|
||||||
if ( ExceptionRecord->ExceptionFlags & EH_NONCONTINUABLE ) {
|
|
||||||
FatalExceptionRecord.ExceptionRecord = ExceptionRecord;
|
|
||||||
FatalExceptionRecord.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
|
|
||||||
FatalExceptionRecord.ExceptionFlags = EH_NONCONTINUABLE;
|
|
||||||
FatalExceptionRecord.NumberParameters = 0;
|
|
||||||
RtlRaiseException(&FatalExceptionRecord);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return DISPOSITION_CONTINUE_SEARCH;
|
|
||||||
break;
|
|
||||||
case DISPOSITION_CONTINUE_SEARCH:
|
|
||||||
break;
|
|
||||||
case DISPOSITION_NESTED_EXCEPTION:
|
|
||||||
ExceptionRecord->ExceptionFlags |= EH_EXIT_UNWIND;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
FatalExceptionRecord.ExceptionRecord = ExceptionRecord;
|
|
||||||
FatalExceptionRecord.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
|
|
||||||
FatalExceptionRecord.ExceptionFlags = EH_NONCONTINUABLE;
|
|
||||||
FatalExceptionRecord.NumberParameters = 0;
|
|
||||||
RtlRaiseException(&FatalExceptionRecord);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
RegistrationFrame = RegistrationFrame->Prev;
|
|
||||||
}
|
|
||||||
return DISPOSITION_DISMISS;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PEXCEPTION_REGISTRATION RtlpGetRegistrationHead(VOID)
|
|
||||||
{
|
|
||||||
PEXCEPTION_REGISTRATION __head;
|
|
||||||
/*
|
|
||||||
__asm {
|
|
||||||
mov eax, fs:[0]
|
|
||||||
mov __head,eax
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return __head;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame,
|
|
||||||
PVOID ReturnAddress, // Unused
|
|
||||||
PEXCEPTION_RECORD ExceptionRecord,
|
|
||||||
DWORD _eax)
|
|
||||||
{
|
|
||||||
NTSTATUS errCode, retval;
|
|
||||||
DWORD StackBase;
|
|
||||||
DWORD StackTop;
|
|
||||||
CONTEXT Context;
|
|
||||||
PEXCEPTION_REGISTRATION TraversingFrame;
|
|
||||||
EXCEPTION_RECORD TraversingRecord;
|
|
||||||
EXCEPTION_RECORD DispatcherContext;
|
|
||||||
|
|
||||||
|
|
||||||
/* build an exception record, if we do not have one */
|
|
||||||
if(ExceptionRecord != NULL)
|
|
||||||
{
|
|
||||||
ExceptionRecord->ExceptionCode = (DWORD)STATUS_UNWIND; //STATUS_INVALID_DISPOSITION;
|
|
||||||
ExceptionRecord->ExceptionFlags = 0;
|
|
||||||
ExceptionRecord->ExceptionRecord = NULL;
|
|
||||||
//ExceptionRecord->ExceptionAddress = (LPVOID)pcontext->Eip;
|
|
||||||
ExceptionRecord->NumberParameters = 0;
|
|
||||||
ExceptionRecord->ExceptionInformation[0] =0;
|
|
||||||
|
|
||||||
|
|
||||||
if ( RegistrationFrame != NULL )
|
|
||||||
ExceptionRecord->ExceptionFlags |= EH_UNWINDING;
|
|
||||||
else
|
|
||||||
ExceptionRecord->ExceptionFlags |=
|
|
||||||
(EH_UNWINDING|EH_EXIT_UNWIND);
|
|
||||||
}
|
|
||||||
Context.ContextFlags |=
|
|
||||||
(CONTEXT_i386|CONTEXT_FULL);
|
|
||||||
RtlpCaptureContext(&Context);
|
|
||||||
Context.Esp += 0x10;
|
|
||||||
Context.Eax = _eax;
|
|
||||||
|
|
||||||
TraversingFrame = RtlpGetRegistrationHead();
|
|
||||||
|
|
||||||
while( ( TraversingFrame != NULL ) && ( TraversingFrame != END_OF_CHAIN ) && ( TraversingFrame != RegistrationFrame ) )
|
|
||||||
{
|
|
||||||
|
|
||||||
errCode = TraversingFrame->Handler(
|
|
||||||
ExceptionRecord,
|
|
||||||
TraversingFrame,
|
|
||||||
&Context,
|
|
||||||
&DispatcherContext);
|
|
||||||
if ( (retval == ExceptionCollidedUnwind) && (TraversingFrame != (LPVOID)&DispatcherContext) )
|
|
||||||
TraversingFrame = (LPVOID)&DispatcherContext;
|
|
||||||
else if ((TraversingFrame != RegistrationFrame) && (TraversingFrame != TraversingFrame->Prev) ) {
|
|
||||||
RtlpUnlinkHandler(TraversingFrame);
|
|
||||||
TraversingFrame = TraversingFrame->Prev;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void RtlpUnlinkHandler(PEXCEPTION_REGISTRATION __head)
|
|
||||||
{
|
|
||||||
PEXCEPTION_REGISTRATION theHead;
|
|
||||||
PEXCEPTION_REGISTRATION theLast;
|
|
||||||
theHead = RtlpGetRegistrationHead();
|
|
||||||
|
|
||||||
/*
|
|
||||||
if ( __head == NULL )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( theHead == __head ) {
|
|
||||||
theHead = theHead->Prev;
|
|
||||||
__asm {
|
|
||||||
mov eax, theHead
|
|
||||||
mov fs:[0], eax
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
do {
|
|
||||||
theLast = theHead;
|
|
||||||
theHead = theHead->Prev;
|
|
||||||
if ( theHead == __head ) {
|
|
||||||
theLast->Prev = theHead->Prev;
|
|
||||||
}
|
|
||||||
} while ( theHead != NULL && theHead != END_OF_CHAIN );
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RtlpLinkHandler(PEXCEPTION_REGISTRATION __head)
|
|
||||||
{
|
|
||||||
PEXCEPTION_REGISTRATION theHead;
|
|
||||||
if (__head == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
theHead = RtlpGetRegistrationHead();
|
|
||||||
__head->Prev = theHead;
|
|
||||||
/*
|
|
||||||
__asm {
|
|
||||||
mov eax, __head
|
|
||||||
mov fs:[0], eax
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void RtlpCaptureContext(PCONTEXT Context)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RtlpGetStackLimits(void *StackBase, void *StackLimit)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
__asm{ mov eax, fs:[4]
|
|
||||||
mov StackBase, eax }
|
|
||||||
__asm{ mov eax, fs:[5]
|
|
||||||
mov StackLimit, eax }
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void RtlRaiseException(struct _EXCEPTION_RECORD *ExceptionRecord)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
* FILE: lib/kernel32/file/curdir.c
|
* FILE: lib/kernel32/file/curdir.c
|
||||||
* PURPOSE: Current directory functions
|
* PURPOSE: Current directory functions
|
||||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
|
||||||
* UPDATE HISTORY:
|
* UPDATE HISTORY:
|
||||||
* Created 30/09/98
|
* Created 30/09/98
|
||||||
*/
|
*/
|
||||||
|
@ -12,16 +11,35 @@
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#define NDEBUG
|
|
||||||
#include <kernel32/kernel32.h>
|
#include <kernel32/kernel32.h>
|
||||||
|
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
#define MAX_DOS_DRIVES 26
|
||||||
|
|
||||||
static WCHAR CurrentDirectoryW[MAX_PATH] = {0,};
|
WCHAR CurrentDirectoryW[MAX_PATH] = {0,};
|
||||||
static WCHAR SystemDirectoryW[MAX_PATH];
|
HANDLE hCurrentDirectory = NULL;
|
||||||
static WCHAR WindowsDirectoryW[MAX_PATH];
|
int drive= 2;
|
||||||
|
|
||||||
|
char DriveDirectoryW[MAX_DOS_DRIVES][MAX_PATH] = { {"A:\\"},{"B:\\"},{"C:\\"},{"D:\\"},
|
||||||
|
{"E:\\"},{"F:\\"},{"G:\\"},{"H:\\"},
|
||||||
|
{"I:\\"},{"J:\\"},{"K:\\"},{"L:\\"},
|
||||||
|
{"M:\\"},{"N:\\"},{"O:\\"},{"P:\\"},
|
||||||
|
{"Q:\\"},{"R:\\"},{"S:\\"},{"T:\\"},
|
||||||
|
{"U:\\"},{"V:\\"},{"W:\\"},{"X:\\"},
|
||||||
|
{"Y:\\"},{"Z:\\"} };
|
||||||
|
|
||||||
|
WCHAR SystemDirectoryW[MAX_PATH];
|
||||||
|
|
||||||
|
WCHAR WindowsDirectoryW[MAX_PATH];
|
||||||
|
|
||||||
|
|
||||||
|
WINBOOL
|
||||||
|
STDCALL
|
||||||
|
SetCurrentDirectoryW(
|
||||||
|
LPCWSTR lpPathName
|
||||||
|
);
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -30,6 +48,8 @@ DWORD STDCALL GetCurrentDirectoryA(DWORD nBufferLength, LPSTR lpBuffer)
|
||||||
UINT uSize,i;
|
UINT uSize,i;
|
||||||
if ( lpBuffer == NULL )
|
if ( lpBuffer == NULL )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
uSize = lstrlenW(CurrentDirectoryW);
|
uSize = lstrlenW(CurrentDirectoryW);
|
||||||
if ( nBufferLength > uSize ) {
|
if ( nBufferLength > uSize ) {
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -60,76 +80,115 @@ DWORD STDCALL GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer)
|
||||||
return uSize;
|
return uSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL STDCALL SetCurrentDirectoryA(LPCSTR lpPathName)
|
WINBOOL STDCALL SetCurrentDirectoryA(LPCSTR lpPathName)
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
WCHAR TempStr[MAX_PATH];
|
WCHAR PathNameW[MAX_PATH];
|
||||||
|
|
||||||
DPRINT("SetCurrentDirectoryA(lpPathName %s)\n",lpPathName);
|
|
||||||
|
|
||||||
if ( lpPathName == NULL )
|
if ( lpPathName == NULL )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( lstrlenA(lpPathName) > MAX_PATH )
|
if ( strlen(lpPathName) > MAX_PATH )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((lpPathName[i])!=0 && i < MAX_PATH)
|
while ((lpPathName[i])!=0 && i < MAX_PATH)
|
||||||
{
|
{
|
||||||
TempStr[i] = (unsigned short)lpPathName[i];
|
PathNameW[i] = (WCHAR)lpPathName[i];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
TempStr[i] = 0;
|
PathNameW[i] = 0;
|
||||||
|
|
||||||
return(SetCurrentDirectoryW(TempStr));
|
return SetCurrentDirectoryW(PathNameW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WINBOOL STDCALL SetCurrentDirectoryW(LPCWSTR lpPathName)
|
WINBOOL
|
||||||
|
STDCALL
|
||||||
|
SetCurrentDirectoryW(
|
||||||
|
LPCWSTR lpPathName
|
||||||
|
)
|
||||||
{
|
{
|
||||||
WCHAR TempDir[MAX_PATH];
|
int len;
|
||||||
HANDLE TempHandle;
|
int i,j;
|
||||||
ULONG Len;
|
HANDLE hDirOld = hCurrentDirectory;
|
||||||
|
WCHAR PathName[MAX_PATH];
|
||||||
DPRINT("SetCurrentDirectoryW(lpPathName %w)\n",lpPathName);
|
|
||||||
|
|
||||||
if ( lpPathName == NULL )
|
if ( lpPathName == NULL )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( lstrlenW(lpPathName) > MAX_PATH )
|
len = lstrlenW(lpPathName);
|
||||||
return FALSE;
|
if ( len > MAX_PATH )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ( len == 2 && isalpha(lpPathName[0]) && lpPathName[1] == ':' ) {
|
||||||
|
len = lstrlenW(CurrentDirectoryW);
|
||||||
|
for(i=0;i<len+1;i++)
|
||||||
|
DriveDirectoryW[drive][i] = CurrentDirectoryW[i];
|
||||||
|
drive = toupper((char)lpPathName[0]) - 'A';
|
||||||
|
len = lstrlenW(DriveDirectoryW[drive]);
|
||||||
|
for(i=0;i<len+1;i++)
|
||||||
|
CurrentDirectoryW[i] = DriveDirectoryW[drive][i];
|
||||||
|
if ( hDirOld != NULL )
|
||||||
|
CloseHandle(hDirOld);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if ( lpPathName[0] == '.' && lpPathName[1] == '\\') {
|
||||||
|
lstrcpyW(PathName,CurrentDirectoryW);
|
||||||
|
lstrcatW(PathName,&lpPathName[2]);
|
||||||
|
}
|
||||||
|
else if ( lpPathName[0] == '.' && lpPathName[1] == '.' ) {
|
||||||
|
lstrcpyW(PathName,CurrentDirectoryW);
|
||||||
|
lstrcatW(PathName,lpPathName);
|
||||||
|
}
|
||||||
|
else if ( lpPathName[0] != '.' && lpPathName[1] != ':' ) {
|
||||||
|
lstrcpyW(PathName,CurrentDirectoryW);
|
||||||
|
lstrcatW(PathName,lpPathName);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lstrcpyW(PathName,CurrentDirectoryW);
|
||||||
|
|
||||||
|
len = lstrlenW(PathName);
|
||||||
|
for(i=0;i<len+1;i++) {
|
||||||
|
if ( PathName[i] == '.' && PathName[i+1] == '.' )
|
||||||
|
if ( i + 2 < len && PathName[i+2] != '\\' && PathName[i+2] != 0 )
|
||||||
|
PathName[i+2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( len > 0 && PathName[len-1] == L'\\' ) {
|
||||||
|
PathName[len-1] = 0;
|
||||||
|
}
|
||||||
|
len = lstrlenW(PathName);
|
||||||
|
for(i=3;i<len-2 && PathName[i] != 0;i++) {
|
||||||
|
if ( PathName[i] == L'\\' && PathName[i+1] == L'.' && PathName[i+2] == L'.' ) {
|
||||||
|
for(j = i-1;j>=2 && PathName[j] != '\\';j-- ) {}
|
||||||
|
PathName[j+1] = 0;
|
||||||
|
if ( i+4 < len ) {
|
||||||
|
PathName[i+3] = 0;
|
||||||
|
lstrcatW(PathName,&PathName[i+4]);
|
||||||
|
}
|
||||||
|
len = lstrlenW(PathName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hCurrentDirectory = CreateFileW(PathName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS|FILE_ATTRIBUTE_DIRECTORY,NULL);
|
||||||
|
if ( hCurrentDirectory == - 1 ) {
|
||||||
|
hCurrentDirectory = hDirOld;
|
||||||
|
DPRINT("%d\n",GetLastError());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CloseHandle(hDirOld);
|
||||||
|
|
||||||
|
|
||||||
lstrcpyW(TempDir, CurrentDirectoryW);
|
lstrcpyW(CurrentDirectoryW,PathName);
|
||||||
GetFullPathNameW(lpPathName,
|
lstrcatW(CurrentDirectoryW,L"\\");
|
||||||
MAX_PATH,
|
|
||||||
TempDir,
|
return TRUE;
|
||||||
NULL);
|
|
||||||
|
|
||||||
Len = lstrlenW(TempDir);
|
|
||||||
if (TempDir[Len-1] != '\\')
|
|
||||||
{
|
|
||||||
TempDir[Len] = '\\';
|
|
||||||
TempDir[Len+1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("TempDir %w\n",TempDir);
|
|
||||||
|
|
||||||
TempHandle = CreateFileW(TempDir,
|
|
||||||
FILE_TRAVERSE,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_ATTRIBUTE_DIRECTORY,
|
|
||||||
NULL);
|
|
||||||
if (TempHandle == NULL)
|
|
||||||
{
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
CloseHandle(TempHandle);
|
|
||||||
lstrcpyW(CurrentDirectoryW, TempDir);
|
|
||||||
|
|
||||||
DPRINT("CurrentDirectoryW %w\n",CurrentDirectoryW);
|
|
||||||
|
|
||||||
return(TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DWORD STDCALL GetTempPathA(DWORD nBufferLength, LPSTR lpBuffer)
|
DWORD STDCALL GetTempPathA(DWORD nBufferLength, LPSTR lpBuffer)
|
||||||
{
|
{
|
||||||
WCHAR BufferW[MAX_PATH];
|
WCHAR BufferW[MAX_PATH];
|
||||||
|
@ -199,7 +258,12 @@ UINT STDCALL GetWindowsDirectoryA(LPSTR lpBuffer, UINT uSize)
|
||||||
return uPathSize;
|
return uPathSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT STDCALL GetSystemDirectoryW(LPWSTR lpBuffer, UINT uSize)
|
UINT
|
||||||
|
STDCALL
|
||||||
|
GetSystemDirectoryW(
|
||||||
|
LPWSTR lpBuffer,
|
||||||
|
UINT uSize
|
||||||
|
)
|
||||||
{
|
{
|
||||||
UINT uPathSize;
|
UINT uPathSize;
|
||||||
if ( lpBuffer == NULL )
|
if ( lpBuffer == NULL )
|
||||||
|
@ -212,7 +276,12 @@ UINT STDCALL GetSystemDirectoryW(LPWSTR lpBuffer, UINT uSize)
|
||||||
return uPathSize;
|
return uPathSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT STDCALL GetWindowsDirectoryW(LPWSTR lpBuffer, UINT uSize)
|
UINT
|
||||||
|
STDCALL
|
||||||
|
GetWindowsDirectoryW(
|
||||||
|
LPWSTR lpBuffer,
|
||||||
|
UINT uSize
|
||||||
|
)
|
||||||
{
|
{
|
||||||
UINT uPathSize;
|
UINT uPathSize;
|
||||||
if ( lpBuffer == NULL )
|
if ( lpBuffer == NULL )
|
||||||
|
@ -223,3 +292,5 @@ UINT STDCALL GetWindowsDirectoryW(LPWSTR lpBuffer, UINT uSize)
|
||||||
|
|
||||||
return uPathSize;
|
return uPathSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,7 @@ CopyFileExA(
|
||||||
DWORD dwCopyFlags
|
DWORD dwCopyFlags
|
||||||
);
|
);
|
||||||
|
|
||||||
DWORD
|
|
||||||
GetCurrentTime(VOID);
|
|
||||||
|
|
||||||
BOOLEAN bIsFileApiAnsi; // set the file api to ansi or oem
|
BOOLEAN bIsFileApiAnsi; // set the file api to ansi or oem
|
||||||
|
|
||||||
|
@ -91,10 +90,10 @@ WINBOOL STDCALL WriteFile(HANDLE hFile,
|
||||||
LARGE_INTEGER Offset;
|
LARGE_INTEGER Offset;
|
||||||
HANDLE hEvent = NULL;
|
HANDLE hEvent = NULL;
|
||||||
NTSTATUS errCode;
|
NTSTATUS errCode;
|
||||||
|
PIO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
IO_STATUS_BLOCK IIosb;
|
||||||
|
|
||||||
WCHAR Buffer[1000];
|
|
||||||
|
|
||||||
//printk("%.*s",nNumberOfBytesToWrite,lpBuffer);
|
|
||||||
|
|
||||||
if (lpOverLapped != NULL )
|
if (lpOverLapped != NULL )
|
||||||
{
|
{
|
||||||
|
@ -102,9 +101,15 @@ WINBOOL STDCALL WriteFile(HANDLE hFile,
|
||||||
SET_LARGE_INTEGER_HIGH_PART(Offset, lpOverLapped->OffsetHigh);
|
SET_LARGE_INTEGER_HIGH_PART(Offset, lpOverLapped->OffsetHigh);
|
||||||
lpOverLapped->Internal = STATUS_PENDING;
|
lpOverLapped->Internal = STATUS_PENDING;
|
||||||
hEvent= lpOverLapped->hEvent;
|
hEvent= lpOverLapped->hEvent;
|
||||||
|
IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IoStatusBlock = &IIosb;
|
||||||
|
Offset = NULL;
|
||||||
}
|
}
|
||||||
errCode = NtWriteFile(hFile,hEvent,NULL,NULL,
|
errCode = NtWriteFile(hFile,hEvent,NULL,NULL,
|
||||||
(PIO_STATUS_BLOCK)lpOverLapped,
|
IoStatusBlock,
|
||||||
(PVOID)lpBuffer,
|
(PVOID)lpBuffer,
|
||||||
nNumberOfBytesToWrite,
|
nNumberOfBytesToWrite,
|
||||||
&Offset,
|
&Offset,
|
||||||
|
@ -114,7 +119,8 @@ WINBOOL STDCALL WriteFile(HANDLE hFile,
|
||||||
SetLastError(RtlNtStatusToDosError(errCode));
|
SetLastError(RtlNtStatusToDosError(errCode));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
if ( !lpNumberOfBytesWritten )
|
||||||
|
*lpNumberOfBytesWritten = IoStatusBlock->Information;
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,6 +169,8 @@ WINBOOL STDCALL ReadFile(HANDLE hFile,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !lpNumberOfBytesRead )
|
||||||
|
*lpNumberOfBytesRead = IoStatusBlock->Information;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -213,6 +221,8 @@ ReadFileEx(
|
||||||
SetLastError(RtlNtStatusToDosError(errCode));
|
SetLastError(RtlNtStatusToDosError(errCode));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1265,17 +1275,7 @@ SetFileAttributesW(
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DWORD
|
|
||||||
GetCurrentTime(VOID)
|
|
||||||
{
|
|
||||||
NTSTATUS errCode;
|
|
||||||
FILETIME CurrentTime;
|
|
||||||
memset(&CurrentTime,sizeof(FILETIME),0);
|
|
||||||
// errCode = NtQuerySystemTime (
|
|
||||||
// (TIME *)&CurrentTime
|
|
||||||
// );
|
|
||||||
return CurrentTime.dwLowDateTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT
|
UINT
|
||||||
STDCALL
|
STDCALL
|
||||||
|
|
|
@ -4,9 +4,20 @@
|
||||||
* FILE: lib/kernel32/file/volume.c
|
* FILE: lib/kernel32/file/volume.c
|
||||||
* PURPOSE: File volume functions
|
* PURPOSE: File volume functions
|
||||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||||
|
Erik Bos, Alexandre Julliard :
|
||||||
|
DRIVE_IsValid, GetLogicalDriveStringsA,
|
||||||
|
GetLogicalDriveStringsW, GetLogicalDrives
|
||||||
* UPDATE HISTORY:
|
* UPDATE HISTORY:
|
||||||
* Created 01/11/98
|
* Created 01/11/98
|
||||||
*/
|
*/
|
||||||
|
//WINE copyright notice:
|
||||||
|
/*
|
||||||
|
* DOS drives handling functions
|
||||||
|
*
|
||||||
|
* Copyright 1993 Erik Bos
|
||||||
|
* Copyright 1996 Alexandre Julliard
|
||||||
|
*/
|
||||||
|
|
||||||
#undef WIN32_LEAN_AND_MEAN
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
@ -14,13 +25,29 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ddk/li.h>
|
#include <ddk/li.h>
|
||||||
|
|
||||||
DWORD
|
#define MAX_DOS_DRIVES 26
|
||||||
STDCALL
|
|
||||||
GetLogicalDrives(VOID)
|
int DRIVE_IsValid( int drive )
|
||||||
{
|
{
|
||||||
return (DWORD)-1;
|
char Drives[4];
|
||||||
|
Drives[0] = 'A';
|
||||||
|
Drives[1] = ':';
|
||||||
|
Drives[2] = '\\';
|
||||||
|
Drives[3] = 0;
|
||||||
|
|
||||||
|
Drives[0] = 'A' + drive -1;
|
||||||
|
if ((drive < 0) || (drive >= MAX_DOS_DRIVES)) return 0;
|
||||||
|
if ( CreateFileA(Drives,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS|FILE_ATTRIBUTE_DIRECTORY,NULL) == -1 ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return drive;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
STDCALL
|
STDCALL
|
||||||
GetLogicalDriveStringsA(
|
GetLogicalDriveStringsA(
|
||||||
|
@ -28,8 +55,27 @@ GetLogicalDriveStringsA(
|
||||||
LPSTR lpBuffer
|
LPSTR lpBuffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
int drive, count;
|
||||||
|
|
||||||
|
for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||||
|
if (DRIVE_IsValid(drive)) count++;
|
||||||
|
if (count * 4 * sizeof(char) <= nBufferLength)
|
||||||
|
{
|
||||||
|
LPSTR p = lpBuffer;
|
||||||
|
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||||
|
if (DRIVE_IsValid(drive))
|
||||||
|
{
|
||||||
|
*p++ = 'A' + drive;
|
||||||
|
*p++ = ':';
|
||||||
|
*p++ = '\\';
|
||||||
|
*p++ = '\0';
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
return count * 4 * sizeof(char);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
STDCALL
|
STDCALL
|
||||||
GetLogicalDriveStringsW(
|
GetLogicalDriveStringsW(
|
||||||
|
@ -37,8 +83,41 @@ GetLogicalDriveStringsW(
|
||||||
LPWSTR lpBuffer
|
LPWSTR lpBuffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
int drive, count;
|
||||||
|
|
||||||
|
for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||||
|
if (DRIVE_IsValid(drive)) count++;
|
||||||
|
if (count * 4 * sizeof(WCHAR) <= nBufferLength)
|
||||||
|
{
|
||||||
|
LPWSTR p = lpBuffer;
|
||||||
|
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||||
|
if (DRIVE_IsValid(drive))
|
||||||
|
{
|
||||||
|
*p++ = (WCHAR)('A' + drive);
|
||||||
|
*p++ = (WCHAR)':';
|
||||||
|
*p++ = (WCHAR)'\\';
|
||||||
|
*p++ = (WCHAR)'\0';
|
||||||
|
}
|
||||||
|
*p = (WCHAR)'\0';
|
||||||
|
}
|
||||||
|
return count * 4 * sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
STDCALL
|
||||||
|
GetLogicalDrives(VOID)
|
||||||
|
{
|
||||||
|
DWORD ret = 0;
|
||||||
|
int drive;
|
||||||
|
|
||||||
|
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||||
|
if (DRIVE_IsValid(drive)) ret |= (1 << drive);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WINBOOL
|
WINBOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
GetDiskFreeSpaceA(
|
GetDiskFreeSpaceA(
|
||||||
|
|
|
@ -3,7 +3,7 @@ all: kernel32.a
|
||||||
SYNCH_OBJECTS = synch/critical.o synch/event.o synch/wait.o
|
SYNCH_OBJECTS = synch/critical.o synch/event.o synch/wait.o
|
||||||
|
|
||||||
MISC_OBJECTS = misc/error.o misc/atom.o misc/handle.o misc/env.o misc/dllmain.o \
|
MISC_OBJECTS = misc/error.o misc/atom.o misc/handle.o misc/env.o misc/dllmain.o \
|
||||||
misc/console.o
|
misc/console.o misc/time.o
|
||||||
|
|
||||||
FILE_OBJECTS = file/file.o file/curdir.o file/lfile.o file/dir.o \
|
FILE_OBJECTS = file/file.o file/curdir.o file/lfile.o file/dir.o \
|
||||||
file/iocompl.o file/volume.o file/deviceio.o file/dosdev.o \
|
file/iocompl.o file/volume.o file/deviceio.o file/dosdev.o \
|
||||||
|
|
|
@ -57,22 +57,72 @@ ReadConsoleA(
|
||||||
LPVOID lpReserved
|
LPVOID lpReserved
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return ReadFile(hConsoleInput,lpBuffer,nNumberOfCharsToRead,lpNumberOfCharsRead,lpReserved);
|
KEY_EVENT_RECORD *k;
|
||||||
|
OVERLAPPED Overlapped;
|
||||||
|
OVERLAPPED * lpOverlapped;
|
||||||
|
int kSize;
|
||||||
|
int i,j;
|
||||||
|
|
||||||
|
if ( lpReserved == NULL ) {
|
||||||
|
Overlapped.Internal = 0;
|
||||||
|
Overlapped.InternalHigh = 0;
|
||||||
|
Overlapped.Offset = 0;
|
||||||
|
Overlapped.OffsetHigh = 0;
|
||||||
|
// Overlapped.hEvent = CreateEvent(NULL,FALSE,TRUE,NULL);
|
||||||
|
lpOverlapped = &Overlapped;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lpOverlapped = lpReserved;
|
||||||
|
|
||||||
|
|
||||||
|
kSize = nNumberOfCharsToRead*sizeof(kSize);
|
||||||
|
k = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,kSize);
|
||||||
|
if ( k == NULL || kSize == 0 )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
k[0].AsciiChar = 0;
|
||||||
|
while(k[0].AsciiChar == 0 )
|
||||||
|
{
|
||||||
|
ReadFile(hConsoleInput,k,kSize,lpNumberOfCharsRead,lpOverlapped);
|
||||||
|
|
||||||
|
}
|
||||||
|
j = 0;
|
||||||
|
i = 0;
|
||||||
|
//if ( k[i].bKeyDown )
|
||||||
|
{
|
||||||
|
((char *)lpBuffer)[j] = k[i].AsciiChar;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
while(j < nNumberOfCharsToRead && i < *lpNumberOfCharsRead ) {
|
||||||
|
//if ( k[i].bKeyDown )
|
||||||
|
{
|
||||||
|
((char *)lpBuffer)[j] = k[i].AsciiChar;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(),0,k);
|
||||||
|
//if ( lpReserved == NULL ) {
|
||||||
|
// CloseHandle(Overlapped.hEvent);
|
||||||
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WINBOOL
|
WINBOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
AllocConsole( VOID )
|
AllocConsole( VOID )
|
||||||
{
|
{
|
||||||
StdInput = CreateFile("\\Keyboard",
|
StdInput = CreateFile("\\Device\\Keyboard",
|
||||||
FILE_GENERIC_READ,
|
FILE_GENERIC_READ,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
0,
|
FILE_FLAG_OVERLAPPED,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
StdOutput = CreateFile("\\BlueScreen",
|
StdOutput = CreateFile("\\Device\\BlueScreen",
|
||||||
FILE_GENERIC_WRITE|FILE_GENERIC_READ,
|
FILE_GENERIC_WRITE|FILE_GENERIC_READ,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -90,6 +140,8 @@ WINBOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
FreeConsole( VOID )
|
FreeConsole( VOID )
|
||||||
{
|
{
|
||||||
|
CloseHandle(StdInput);
|
||||||
|
CloseHandle(StdOutput);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,9 +175,9 @@ SetConsoleCursorPosition(
|
||||||
|
|
||||||
if( !GetConsoleScreenBufferInfo(hConsoleOutput,&ConsoleScreenBufferInfo) )
|
if( !GetConsoleScreenBufferInfo(hConsoleOutput,&ConsoleScreenBufferInfo) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
// ConsoleScreenBufferInfo.dwCursorPosition.X = dwCursorPosition.X;
|
ConsoleScreenBufferInfo.dwCursorPosition.X = dwCursorPosition.X;
|
||||||
// ConsoleScreenBufferInfo.dwCursorPosition.Y = dwCursorPosition.Y;
|
ConsoleScreenBufferInfo.dwCursorPosition.Y = dwCursorPosition.Y;
|
||||||
return TRUE;
|
|
||||||
if( !DeviceIoControl(
|
if( !DeviceIoControl(
|
||||||
hConsoleOutput,
|
hConsoleOutput,
|
||||||
FSCTL_SET_CONSOLE_SCREEN_BUFFER_INFO,
|
FSCTL_SET_CONSOLE_SCREEN_BUFFER_INFO,
|
||||||
|
@ -164,5 +216,6 @@ FillConsoleOutputCharacterW(
|
||||||
LPDWORD lpNumberOfCharsWritten
|
LPDWORD lpNumberOfCharsWritten
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,59 +233,10 @@ GetVersionExA(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID GetSystemTime(
|
|
||||||
LPSYSTEMTIME lpSystemTime
|
|
||||||
)
|
|
||||||
{
|
|
||||||
NTSTATUS errCode;
|
|
||||||
memset(lpSystemTime,sizeof(SYSTEMTIME),0);
|
|
||||||
// errCode = NtQuerySystemTime (
|
|
||||||
// (TIME *)lpSystemTime
|
|
||||||
// );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
WINBOOL
|
|
||||||
STDCALL
|
|
||||||
SetSystemTime(
|
|
||||||
CONST SYSTEMTIME *lpSystemTime
|
|
||||||
)
|
|
||||||
{
|
|
||||||
NTSTATUS errCode;
|
|
||||||
LARGE_INTEGER NewSystemTime;
|
|
||||||
errCode = NtSetSystemTime (
|
|
||||||
(LARGE_INTEGER *)lpSystemTime,
|
|
||||||
&NewSystemTime
|
|
||||||
);
|
|
||||||
if ( !NT_SUCCESS(errCode) )
|
|
||||||
return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VOID
|
|
||||||
STDCALL
|
|
||||||
GetLocalTime(
|
|
||||||
LPSYSTEMTIME lpSystemTime
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GetSystemTime(lpSystemTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
WINBOOL
|
|
||||||
STDCALL
|
|
||||||
SetLocalTime(
|
|
||||||
CONST SYSTEMTIME *lpSystemTime
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return SetSystemTime(lpSystemTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
LPSTR
|
LPSTR
|
||||||
STDCALL
|
STDCALL
|
||||||
GetEnvironmentStringsA(
|
GetEnvironmentStringsA(
|
||||||
|
|
501
reactos/lib/kernel32/misc/time.c
Normal file
501
reactos/lib/kernel32/misc/time.c
Normal file
|
@ -0,0 +1,501 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS system libraries
|
||||||
|
* FILE: lib/kernel32/misc/time.c
|
||||||
|
* PURPOSE: Time conversion functions
|
||||||
|
* PROGRAMMER: Boudewijn ( ariadne@xs4all.nl)
|
||||||
|
DOSDATE and DOSTIME structures from Onno Hovers
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* Created 19/01/99
|
||||||
|
*/
|
||||||
|
#include <windows.h>
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
|
||||||
|
typedef struct __DOSTIME
|
||||||
|
{
|
||||||
|
WORD Second:5;
|
||||||
|
WORD Minute:6;
|
||||||
|
WORD Hour:5;
|
||||||
|
} DOSTIME, *PDOSTIME;
|
||||||
|
|
||||||
|
typedef struct __DOSDATE
|
||||||
|
{
|
||||||
|
WORD Day:5;
|
||||||
|
WORD Month:4;
|
||||||
|
WORD Year:5;
|
||||||
|
} DOSDATE, *PDOSDATE;
|
||||||
|
|
||||||
|
#define NSPERSEC 10000000
|
||||||
|
|
||||||
|
#define SECOND 1
|
||||||
|
#define MINUTE 60*SECOND
|
||||||
|
#define HOUR 60*MINUTE
|
||||||
|
#define DAY 24*HOUR
|
||||||
|
#define YEAR (365*DAY)
|
||||||
|
#define FOURYEAR (4*YEAR+DAY)
|
||||||
|
#define CENTURY (25*FOURYEAR-DAY)
|
||||||
|
#define MILLENIUM (100*CENTURY)
|
||||||
|
|
||||||
|
|
||||||
|
#define LISECOND RtlEnlargedUnsignedMultiply(SECOND,NSPERSEC)
|
||||||
|
#define LIMINUTE RtlEnlargedUnsignedMultiply(MINUTE,NSPERSEC)
|
||||||
|
#define LIHOUR RtlEnlargedUnsignedMultiply(HOUR,NSPERSEC)
|
||||||
|
#define LIDAY RtlEnlargedUnsignedMultiply(DAY,NSPERSEC)
|
||||||
|
#define LIYEAR RtlEnlargedUnsignedMultiply(YEAR,NSPERSEC)
|
||||||
|
#define LIFOURYEAR RtlEnlargedUnsignedMultiply(FOURYEAR,NSPERSEC)
|
||||||
|
#define LICENTURY RtlEnlargedUnsignedMultiply(CENTURY,NSPERSEC)
|
||||||
|
#define LIMILLENIUM RtlEnlargedUnsignedMultiply(CENTURY,10*NSPERSEC)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WINBOOL
|
||||||
|
STDCALL
|
||||||
|
FileTimeToDosDateTime(
|
||||||
|
CONST FILETIME *lpFileTime,
|
||||||
|
LPWORD lpFatDate,
|
||||||
|
LPWORD lpFatTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
PDOSTIME pdtime=(PDOSTIME) lpFatTime;
|
||||||
|
PDOSDATE pddate=(PDOSDATE) lpFatDate;
|
||||||
|
SYSTEMTIME SystemTime;
|
||||||
|
|
||||||
|
if ( lpFileTime == NULL )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ( lpFatDate == NULL )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ( lpFatTime == NULL )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
FileTimeToSystemTime(
|
||||||
|
lpFileTime,
|
||||||
|
&SystemTime
|
||||||
|
);
|
||||||
|
|
||||||
|
pdtime->Second = SystemTime.wSecond;
|
||||||
|
pdtime->Minute = SystemTime.wMinute;
|
||||||
|
pdtime->Hour = SystemTime.wHour;
|
||||||
|
|
||||||
|
|
||||||
|
pddate->Day = SystemTime.wDay;
|
||||||
|
pddate->Month = SystemTime.wMonth;
|
||||||
|
pddate->Year = SystemTime.wYear - 1980;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
WINBOOL
|
||||||
|
STDCALL
|
||||||
|
DosDateTimeToFileTime(
|
||||||
|
WORD wFatDate,
|
||||||
|
WORD wFatTime,
|
||||||
|
LPFILETIME lpFileTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
PDOSTIME pdtime = (PDOSTIME) &wFatTime;
|
||||||
|
PDOSDATE pddate = (PDOSDATE) &wFatDate;
|
||||||
|
SYSTEMTIME SystemTime;
|
||||||
|
|
||||||
|
if ( lpFileTime == NULL )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SystemTime.wMilliseconds = 0;
|
||||||
|
SystemTime.wSecond = pdtime->Second;
|
||||||
|
SystemTime.wMinute = pdtime->Minute;
|
||||||
|
SystemTime.wHour = pdtime->Hour;
|
||||||
|
|
||||||
|
|
||||||
|
SystemTime.wDay = pddate->Day;
|
||||||
|
SystemTime.wMonth = pddate->Month;
|
||||||
|
SystemTime.wYear = 1980 + pddate->Year;
|
||||||
|
|
||||||
|
SystemTimeToFileTime(&SystemTime,lpFileTime);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG
|
||||||
|
STDCALL
|
||||||
|
CompareFileTime(
|
||||||
|
CONST FILETIME *lpFileTime1,
|
||||||
|
CONST FILETIME *lpFileTime2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( lpFileTime1 == NULL )
|
||||||
|
return 0;
|
||||||
|
if ( lpFileTime2 == NULL )
|
||||||
|
return 0;
|
||||||
|
/*
|
||||||
|
if ((GET_LARGE_INTEGER_HIGH_PART(lpFileTime1)) > (GET_LARGE_INTEGER_HIGH_PART(lpFileTime2)) )
|
||||||
|
return 1;
|
||||||
|
else if ((GET_LARGE_INTEGER_HIGH_PART(lpFileTime1)) < (GET_LARGE_INTEGER_HIGH_PART(lpFileTime2)))
|
||||||
|
return -1;
|
||||||
|
else if ((GET_LARGE_INTEGER_LOW_PART(lpFileTime1)) > (GET_LARGE_INTEGER_LOW_PART(lpFileTime2)))
|
||||||
|
return 1;
|
||||||
|
else if ((GET_LARGE_INTEGER_LOW_PART(lpFileTime1)) < (GET_LARGE_INTEGER_LOW_PART(lpFileTime2)))
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
STDCALL
|
||||||
|
GetSystemTimeAsFileTime(PFILETIME lpFileTime)
|
||||||
|
{
|
||||||
|
NTSTATUS errCode;
|
||||||
|
|
||||||
|
errCode = NtQuerySystemTime (
|
||||||
|
(TIME *)lpFileTime
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WINBOOL
|
||||||
|
STDCALL
|
||||||
|
SystemTimeToFileTime(
|
||||||
|
CONST SYSTEMTIME * lpSystemTime,
|
||||||
|
LPFILETIME lpFileTime
|
||||||
|
)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
LARGE_INTEGER FileTime;
|
||||||
|
LARGE_INTEGER Year;
|
||||||
|
LARGE_INTEGER Month;
|
||||||
|
LARGE_INTEGER Day;
|
||||||
|
LARGE_INTEGER Hour;
|
||||||
|
LARGE_INTEGER Minute;
|
||||||
|
LARGE_INTEGER Second;
|
||||||
|
LARGE_INTEGER Milliseconds;
|
||||||
|
DWORD LeapDay = 0;
|
||||||
|
DWORD dwMonthDays = 0;
|
||||||
|
|
||||||
|
if ( (lpSystemTime->wYear % 4 == 0 && lpSystemTime->wYear % 100 != 0) || lpSystemTime->wYear % 400 == 0)
|
||||||
|
LeapDay = 1;
|
||||||
|
else
|
||||||
|
LeapDay = 0;
|
||||||
|
|
||||||
|
|
||||||
|
Year = RtlEnlargedIntegerMultiply(lpSystemTime->wYear - 1601,YEAR);
|
||||||
|
if ( lpSystemTime->wMonth > 1)
|
||||||
|
dwMonthDays = 31;
|
||||||
|
if ( lpSystemTime->wMonth > 2)
|
||||||
|
dwMonthDays += ( 28 + LeapDay );
|
||||||
|
if ( lpSystemTime->wMonth > 3)
|
||||||
|
dwMonthDays += 31;
|
||||||
|
if ( lpSystemTime->wMonth > 4)
|
||||||
|
dwMonthDays += 30;
|
||||||
|
if ( lpSystemTime->wMonth > 5)
|
||||||
|
dwMonthDays += 31;
|
||||||
|
if ( lpSystemTime->wMonth > 6)
|
||||||
|
dwMonthDays += 30;
|
||||||
|
if ( lpSystemTime->wMonth > 7)
|
||||||
|
dwMonthDays += 31;
|
||||||
|
if ( lpSystemTime->wMonth > 8)
|
||||||
|
dwMonthDays += 31;
|
||||||
|
if ( lpSystemTime->wMonth > 9)
|
||||||
|
dwMonthDays += 30;
|
||||||
|
if ( lpSystemTime->wMonth > 10)
|
||||||
|
dwMonthDays += 31;
|
||||||
|
if ( lpSystemTime->wMonth > 11)
|
||||||
|
dwMonthDays += 30;
|
||||||
|
|
||||||
|
Month = RtlEnlargedIntegerMultiply(dwMonthDays,DAY);
|
||||||
|
|
||||||
|
Day = RtlEnlargedIntegerMultiply(lpSystemTime->wDay,DAY);
|
||||||
|
|
||||||
|
Hour = RtlEnlargedIntegerMultiply(lpSystemTime->wHour,HOUR);
|
||||||
|
Minute = RtlEnlargedIntegerMultiply(lpSystemTime->wMinute,MINUTE);
|
||||||
|
Second = RtlEnlargedIntegerMultiply(lpSystemTime->wSecond,DAY);
|
||||||
|
|
||||||
|
Milliseconds = RtlEnlargedIntegerMultiply(lpSystemTime->wMilliseconds,10000);
|
||||||
|
|
||||||
|
FileTime += RtlLargeIntegerAdd(FileTime,Year);
|
||||||
|
FileTime += RtlLargeIntegerAdd(FileTime,Month);
|
||||||
|
FileTime += RtlLargeIntegerAdd(FileTime,Day);
|
||||||
|
FileTime += RtlLargeIntegerAdd(FileTime,Hour);
|
||||||
|
FileTime += RtlLargeIntegerAdd(FileTime,Minute);
|
||||||
|
FileTime += RtlLargeIntegerAdd(FileTime,Second);
|
||||||
|
|
||||||
|
FileTime = RtlExtendedIntegerMultiply(FileTime,NSPERSEC);
|
||||||
|
|
||||||
|
FileTime = RtlLargeIntegerAdd(FileTime,Milliseconds);
|
||||||
|
|
||||||
|
memcpy(lpFileTime,&FileTime,sizeof(FILETIME));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WINBOOL
|
||||||
|
STDCALL
|
||||||
|
FileTimeToSystemTime(
|
||||||
|
CONST FILETIME *lpFileTime,
|
||||||
|
LPSYSTEMTIME lpSystemTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
LARGE_INTEGER FileTime;
|
||||||
|
|
||||||
|
LARGE_INTEGER dwMillenium;
|
||||||
|
LARGE_INTEGER dwRemMillenium;
|
||||||
|
|
||||||
|
LARGE_INTEGER dwCentury;
|
||||||
|
LARGE_INTEGER dwRemCentury;
|
||||||
|
|
||||||
|
LARGE_INTEGER dwFourYear;
|
||||||
|
LARGE_INTEGER dwRemFourYear;
|
||||||
|
|
||||||
|
LARGE_INTEGER dwYear;
|
||||||
|
LARGE_INTEGER dwRemYear;
|
||||||
|
|
||||||
|
LARGE_INTEGER dwDay;
|
||||||
|
LARGE_INTEGER dwRemDay;
|
||||||
|
|
||||||
|
LARGE_INTEGER dwHour;
|
||||||
|
LARGE_INTEGER dwRemHour;
|
||||||
|
|
||||||
|
LARGE_INTEGER dwMinute;
|
||||||
|
LARGE_INTEGER dwRemMinute;
|
||||||
|
|
||||||
|
LARGE_INTEGER dwSecond;
|
||||||
|
LARGE_INTEGER dwRemSecond;
|
||||||
|
|
||||||
|
LARGE_INTEGER dwDayOfWeek;
|
||||||
|
|
||||||
|
|
||||||
|
DWORD LeapDay = 0;
|
||||||
|
|
||||||
|
|
||||||
|
memcpy(&FileTime,lpFileTime,sizeof(FILETIME));
|
||||||
|
|
||||||
|
|
||||||
|
dwMillenium = RtlLargeIntegerDivide(FileTime,LIMILLENIUM,&dwRemMillenium);
|
||||||
|
dwCentury = RtlLargeIntegerDivide(dwRemMillenium,LICENTURY,&dwRemCentury);
|
||||||
|
dwFourYear = RtlLargeIntegerDivide(dwRemCentury,LIFOURYEAR,&dwRemFourYear);
|
||||||
|
dwYear = RtlLargeIntegerDivide(dwRemFourYear,LIYEAR,&dwRemYear);
|
||||||
|
dwDay = RtlLargeIntegerDivide(dwRemYear,LIDAY,&dwRemDay);
|
||||||
|
dwHour = RtlLargeIntegerDivide(dwRemDay,LIHOUR,&dwRemHour);
|
||||||
|
dwMinute = RtlLargeIntegerDivide(dwRemHour,LIMINUTE,&dwRemMinute);
|
||||||
|
dwSecond = RtlLargeIntegerDivide(dwRemMinute,LISECOND,&dwRemSecond);
|
||||||
|
|
||||||
|
lpSystemTime->wHour= (WORD) GET_LARGE_INTEGER_LOW_PART(dwHour);
|
||||||
|
lpSystemTime->wMinute= (WORD)GET_LARGE_INTEGER_LOW_PART(dwMinute);
|
||||||
|
lpSystemTime->wSecond= (WORD)GET_LARGE_INTEGER_LOW_PART(dwSecond);
|
||||||
|
lpSystemTime->wMilliseconds = (WORD)(GET_LARGE_INTEGER_LOW_PART(dwRemSecond)/10000);
|
||||||
|
|
||||||
|
|
||||||
|
if ( lpSystemTime->wSecond > 60 ) {
|
||||||
|
lpSystemTime->wSecond -= 60;
|
||||||
|
lpSystemTime->wMinute ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( lpSystemTime->wMinute > 60 ) {
|
||||||
|
lpSystemTime->wMinute -= 60;
|
||||||
|
lpSystemTime->wHour ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpSystemTime->wHour > 24 ) {
|
||||||
|
lpSystemTime->wHour-= 24;
|
||||||
|
SET_LARGE_INTEGER_LOW_PART(dwDay,GET_LARGE_INTEGER_LOW_PART(dwDay)+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//FIXME since 1972 some years have a leap second [ aprox 15 out of 20 ]
|
||||||
|
|
||||||
|
// if leap year
|
||||||
|
lpSystemTime->wYear= 1601 + 1000* (LONG)GET_LARGE_INTEGER_LOW_PART(dwMillenium) + 100 * (LONG)GET_LARGE_INTEGER_LOW_PART(dwCentury) + 4*(LONG)GET_LARGE_INTEGER_LOW_PART(dwFourYear) + (LONG)GET_LARGE_INTEGER_LOW_PART(dwYear);
|
||||||
|
|
||||||
|
if ( (lpSystemTime->wYear % 4 == 0 && lpSystemTime->wYear % 100 != 0) || lpSystemTime->wYear % 400 == 0)
|
||||||
|
LeapDay = 1;
|
||||||
|
else
|
||||||
|
LeapDay = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( GET_LARGE_INTEGER_LOW_PART(dwDay) >= 0 && GET_LARGE_INTEGER_LOW_PART(dwDay) < 31 ) {
|
||||||
|
lpSystemTime->wMonth = 1;
|
||||||
|
lpSystemTime->wDay = GET_LARGE_INTEGER_LOW_PART(dwDay) + 1;
|
||||||
|
}
|
||||||
|
else if ( GET_LARGE_INTEGER_LOW_PART(dwDay) >= 31 && GET_LARGE_INTEGER_LOW_PART(dwDay) < ( 59 + LeapDay )) {
|
||||||
|
lpSystemTime->wMonth = 2;
|
||||||
|
lpSystemTime->wDay = GET_LARGE_INTEGER_LOW_PART(dwDay) + 1 - 31;
|
||||||
|
}
|
||||||
|
else if ( GET_LARGE_INTEGER_LOW_PART(dwDay) >= ( 59 + LeapDay ) && GET_LARGE_INTEGER_LOW_PART(dwDay) < ( 90 + LeapDay ) ) {
|
||||||
|
lpSystemTime->wMonth = 3;
|
||||||
|
lpSystemTime->wDay = GET_LARGE_INTEGER_LOW_PART(dwDay) + 1 - ( 59 + LeapDay);
|
||||||
|
}
|
||||||
|
else if ( GET_LARGE_INTEGER_LOW_PART(dwDay) >= 90+ LeapDay && GET_LARGE_INTEGER_LOW_PART(dwDay) < 120 + LeapDay) {
|
||||||
|
lpSystemTime->wMonth = 4;
|
||||||
|
lpSystemTime->wDay = GET_LARGE_INTEGER_LOW_PART(dwDay) + 1 - (31 + LeapDay );
|
||||||
|
}
|
||||||
|
else if ( GET_LARGE_INTEGER_LOW_PART(dwDay) >= 120 + LeapDay && GET_LARGE_INTEGER_LOW_PART(dwDay) < 151 + LeapDay ) {
|
||||||
|
lpSystemTime->wMonth = 5;
|
||||||
|
lpSystemTime->wDay = GET_LARGE_INTEGER_LOW_PART(dwDay) + 1 - (120 + LeapDay);
|
||||||
|
}
|
||||||
|
else if ( GET_LARGE_INTEGER_LOW_PART(dwDay) >= ( 151 + LeapDay) && GET_LARGE_INTEGER_LOW_PART(dwDay) < ( 181 + LeapDay ) ) {
|
||||||
|
lpSystemTime->wMonth = 6;
|
||||||
|
lpSystemTime->wDay = GET_LARGE_INTEGER_LOW_PART(dwDay) + 1 - ( 151 + LeapDay );
|
||||||
|
}
|
||||||
|
else if ( GET_LARGE_INTEGER_LOW_PART(dwDay) >= ( 181 + LeapDay ) && GET_LARGE_INTEGER_LOW_PART(dwDay) < ( 212 + LeapDay ) ) {
|
||||||
|
lpSystemTime->wMonth = 7;
|
||||||
|
lpSystemTime->wDay = GET_LARGE_INTEGER_LOW_PART(dwDay) + 1 - ( 181 + LeapDay );
|
||||||
|
}
|
||||||
|
else if ( GET_LARGE_INTEGER_LOW_PART(dwDay) >= ( 212 + LeapDay ) && GET_LARGE_INTEGER_LOW_PART(dwDay) < ( 243 + LeapDay ) ) {
|
||||||
|
lpSystemTime->wMonth = 8;
|
||||||
|
lpSystemTime->wDay = GET_LARGE_INTEGER_LOW_PART(dwDay) + 1 - (212 + LeapDay );
|
||||||
|
}
|
||||||
|
else if ( GET_LARGE_INTEGER_LOW_PART(dwDay) >= ( 243+ LeapDay ) && GET_LARGE_INTEGER_LOW_PART(dwDay) < ( 273 + LeapDay ) ) {
|
||||||
|
lpSystemTime->wMonth = 9;
|
||||||
|
lpSystemTime->wDay = GET_LARGE_INTEGER_LOW_PART(dwDay) + 1 - ( 243 + LeapDay );
|
||||||
|
}
|
||||||
|
else if ( GET_LARGE_INTEGER_LOW_PART(dwDay) >= ( 273 + LeapDay ) && GET_LARGE_INTEGER_LOW_PART(dwDay) < ( 304 + LeapDay ) ) {
|
||||||
|
lpSystemTime->wMonth = 10;
|
||||||
|
lpSystemTime->wDay = GET_LARGE_INTEGER_LOW_PART(dwDay) + 1 - ( 273 + LeapDay);
|
||||||
|
}
|
||||||
|
else if ( GET_LARGE_INTEGER_LOW_PART(dwDay) >= ( 304 + LeapDay ) && GET_LARGE_INTEGER_LOW_PART(dwDay) < ( 334 + LeapDay ) ) {
|
||||||
|
lpSystemTime->wMonth = 11;
|
||||||
|
lpSystemTime->wDay = GET_LARGE_INTEGER_LOW_PART(dwDay) + 1 - ( 304 + LeapDay );
|
||||||
|
}
|
||||||
|
else if ( GET_LARGE_INTEGER_LOW_PART(dwDay) >= ( 334 + LeapDay ) && GET_LARGE_INTEGER_LOW_PART(dwDay) < ( 365 + LeapDay )) {
|
||||||
|
lpSystemTime->wMonth = 12;
|
||||||
|
lpSystemTime->wDay = GET_LARGE_INTEGER_LOW_PART(dwDay) + 1 - ( 334 + LeapDay );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dwDayOfWeek = RtlLargeIntegerDivide(FileTime,LIDAY,&dwRemDay);
|
||||||
|
lpSystemTime->wDayOfWeek = 1 + GET_LARGE_INTEGER_LOW_PART(dwDayOfWeek) % 7;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WINBOOL
|
||||||
|
STDCALL
|
||||||
|
FileTimeToLocalFileTime(
|
||||||
|
CONST FILETIME *lpFileTime,
|
||||||
|
LPFILETIME lpLocalFileTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// memcpy(lpLocalFileTime,lpFileTime,sizeof(FILETIME));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
WINBOOL
|
||||||
|
STDCALL
|
||||||
|
LocalFileTimeToFileTime(
|
||||||
|
CONST FILETIME *lpLocalFileTime,
|
||||||
|
LPFILETIME lpFileTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
STDCALL
|
||||||
|
GetLocalTime(
|
||||||
|
LPSYSTEMTIME lpSystemTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GetSystemTime(lpSystemTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
STDCALL
|
||||||
|
GetSystemTime(
|
||||||
|
LPSYSTEMTIME lpSystemTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FILETIME FileTime;
|
||||||
|
GetSystemTimeAsFileTime(&FileTime);
|
||||||
|
FileTimeToSystemTime(&FileTime,lpSystemTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WINBOOL
|
||||||
|
STDCALL
|
||||||
|
SetLocalTime(
|
||||||
|
CONST SYSTEMTIME *lpSystemTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return SetSystemTime(lpSystemTime);
|
||||||
|
}
|
||||||
|
WINBOOL
|
||||||
|
STDCALL
|
||||||
|
SetSystemTime(
|
||||||
|
CONST SYSTEMTIME *lpSystemTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS errCode;
|
||||||
|
LARGE_INTEGER NewSystemTime;
|
||||||
|
|
||||||
|
SystemTimeToFileTime(lpSystemTime, (FILETIME *)&NewSystemTime);
|
||||||
|
errCode = NtSetSystemTime (&NewSystemTime,&NewSystemTime);
|
||||||
|
if ( !NT_SUCCESS(errCode) )
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
typedef struct _TIME_ZONE_INFORMATION { // tzi
|
||||||
|
LONG Bias;
|
||||||
|
WCHAR StandardName[ 32 ];
|
||||||
|
SYSTEMTIME StandardDate;
|
||||||
|
LONG StandardBias;
|
||||||
|
WCHAR DaylightName[ 32 ];
|
||||||
|
SYSTEMTIME DaylightDate;
|
||||||
|
LONG DaylightBias;
|
||||||
|
} TIME_ZONE_INFORMATION;
|
||||||
|
TIME_ZONE_INFORMATION TimeZoneInformation = {60,"CET",;
|
||||||
|
|
||||||
|
*/
|
||||||
|
DWORD
|
||||||
|
STDCALL
|
||||||
|
GetTimeZoneInformation(
|
||||||
|
LPTIME_ZONE_INFORMATION lpTimeZoneInformation
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// aprintf("GetTimeZoneInformation()\n");
|
||||||
|
|
||||||
|
// memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION));
|
||||||
|
|
||||||
|
return TIME_ZONE_ID_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
STDCALL
|
||||||
|
GetCurrentTime(VOID)
|
||||||
|
{
|
||||||
|
return GetTickCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
STDCALL
|
||||||
|
GetTickCount(VOID)
|
||||||
|
{
|
||||||
|
ULONG UpTime;
|
||||||
|
NtGetTickCount(&UpTime);
|
||||||
|
return UpTime;
|
||||||
|
}
|
Loading…
Reference in a new issue