Fix remaning ROS bugs. A minor hack has been added to ObCreateObject because it seems that gcc doesn't dword-align the stacks?!! Thanks to w3seek for some of the ex patches.

svn path=/trunk/; revision=13206
This commit is contained in:
Alex Ionescu 2005-01-22 03:54:23 +00:00
parent c6bd59c308
commit 07ea0d9fa0
10 changed files with 673 additions and 324 deletions

View file

@ -88,9 +88,9 @@ TARGET_BASE_LIB_VERSION =0x77a90000
TARGET_BASE_LIB_ADVAPI32 =0x77dc0000 TARGET_BASE_LIB_ADVAPI32 =0x77dc0000
TARGET_BASE_LIB_USER32 =0x77e60000 TARGET_BASE_LIB_USER32 =0x77e60000
TARGET_BASE_LIB_GDI32 =0x77ed0000 TARGET_BASE_LIB_GDI32 =0x77ed0000
TARGET_BASE_LIB_DNSAPI =0x78000000 TARGET_BASE_LIB_DNSAPI =0x77f00000
TARGET_BASE_LIB_MSVCRT =0x78000000 TARGET_BASE_LIB_MSVCRT =0x78000000
TARGET_BASE_LIB_MSVCRT20 =0x78000000 TARGET_BASE_LIB_MSVCRT20 =0x78500000
TARGET_BASE_LIB_EXPAT =0x79000000 TARGET_BASE_LIB_EXPAT =0x79000000
TARGET_BASE_LIB_KERNEL32 =0x7C800000 TARGET_BASE_LIB_KERNEL32 =0x7C800000
TARGET_BASE_LIB_NTDLL =0x7C900000 TARGET_BASE_LIB_NTDLL =0x7C900000

View file

@ -64,7 +64,7 @@ domaininit()
register struct domain *dp, **dpp; register struct domain *dp, **dpp;
register struct protosw *pr; register struct protosw *pr;
printf("domaininit starting\n"); //printf("domaininit starting\n");
/* /*
* NB - local domain is always present. * NB - local domain is always present.
@ -73,7 +73,7 @@ domaininit()
ADDDOMAIN(inet); ADDDOMAIN(inet);
for (dpp = (struct domain **)domain_set.ls_items; *dpp; dpp++) { for (dpp = (struct domain **)domain_set.ls_items; *dpp; dpp++) {
printf("(1) Domain %s counting\n", (**dpp).dom_name); //printf("(1) Domain %s counting\n", (**dpp).dom_name);
(**dpp).dom_next = domains; (**dpp).dom_next = domains;
domains = *dpp; domains = *dpp;
} }
@ -84,11 +84,11 @@ domaininit()
#endif #endif
*/ */
for (dp = domains; dp; dp = dp->dom_next) { for (dp = domains; dp; dp = dp->dom_next) {
printf("(1) Domain %s initializing\n", dp->dom_name); //printf("(1) Domain %s initializing\n", dp->dom_name);
if (dp->dom_init) if (dp->dom_init)
(*dp->dom_init)(); (*dp->dom_init)();
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
printf("Registering protocols for %s\n", dp->dom_name); //printf("Registering protocols for %s\n", dp->dom_name);
if (pr->pr_init) if (pr->pr_init)
(*pr->pr_init)(); (*pr->pr_init)();
} }
@ -103,7 +103,7 @@ domaininit()
timeout(pffasttimo, (void *)0, 1); timeout(pffasttimo, (void *)0, 1);
timeout(pfslowtimo, (void *)0, 1); timeout(pfslowtimo, (void *)0, 1);
printf("Domaininit done\n"); //printf("Domaininit done\n");
} }
struct protosw * struct protosw *

View file

@ -79,11 +79,11 @@ mbinit()
#else #else
#define NCL_INIT 1 #define NCL_INIT 1
#endif #endif
printf("Here1\n"); //printf("Here1\n");
s = splimp(); s = splimp();
if (m_clalloc(NCL_INIT, M_DONTWAIT) == 0) if (m_clalloc(NCL_INIT, M_DONTWAIT) == 0)
goto bad; goto bad;
printf("Here2\n"); //printf("Here2\n");
splx(s); splx(s);
return; return;
bad: bad:
@ -116,12 +116,12 @@ m_clalloc(ncl, nowait)
npg = ncl * CLSIZE; npg = ncl * CLSIZE;
printf("kmem_malloc(%d)\n", npg); //printf("kmem_malloc(%d)\n", npg);
p = (caddr_t)kmem_malloc(mb_map, ctob(npg), p = (caddr_t)kmem_malloc(mb_map, ctob(npg),
nowait ? M_NOWAIT : M_WAITOK); nowait ? M_NOWAIT : M_WAITOK);
printf("kmem_malloc done\n"); //printf("kmem_malloc done\n");
/* /*
* Either the map is now full, or this is nowait and there * Either the map is now full, or this is nowait and there
@ -133,13 +133,13 @@ m_clalloc(ncl, nowait)
ncl = ncl * CLBYTES / MCLBYTES; ncl = ncl * CLBYTES / MCLBYTES;
for (i = 0; i < ncl; i++) { for (i = 0; i < ncl; i++) {
((union mcluster *)p)->mcl_next = mclfree; ((union mcluster *)p)->mcl_next = mclfree;
printf( "Freeing %x onto the free list\n", p); //printf( "Freeing %x onto the free list\n", p);
mclfree = (union mcluster *)p; mclfree = (union mcluster *)p;
p += MCLBYTES; p += MCLBYTES;
mbstat.m_clfree++; mbstat.m_clfree++;
} }
mbstat.m_clusters += ncl; mbstat.m_clusters += ncl;
printf( "done with m_clalloc\n"); //printf( "done with m_clalloc\n");
return (1); return (1);
} }
#endif /* !OSKIT */ #endif /* !OSKIT */

View file

@ -694,7 +694,7 @@ GetFileAttributesExW(LPCWSTR lpFileName,
NTSTATUS Status; NTSTATUS Status;
WIN32_FILE_ATTRIBUTE_DATA* FileAttributeData; WIN32_FILE_ATTRIBUTE_DATA* FileAttributeData;
DPRINT ("GetFileAttributesExW(%S) called\n", lpFileName); DPRINT("GetFileAttributesExW(%S) called\n", lpFileName);
if (fInfoLevelId != GetFileExInfoStandard || lpFileInformation == NULL) if (fInfoLevelId != GetFileExInfoStandard || lpFileInformation == NULL)
@ -709,7 +709,7 @@ GetFileAttributesExW(LPCWSTR lpFileName,
NULL, NULL,
NULL)) NULL))
{ {
DPRINT ("Invalid path\n"); DPRINT1 ("Invalid path\n");
SetLastError (ERROR_BAD_PATHNAME); SetLastError (ERROR_BAD_PATHNAME);
return FALSE; return FALSE;
} }
@ -731,7 +731,7 @@ GetFileAttributesExW(LPCWSTR lpFileName,
RtlFreeUnicodeString (&FileName); RtlFreeUnicodeString (&FileName);
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
{ {
DPRINT ("NtOpenFile() failed (Status %lx)\n", Status); DPRINT1 ("NtOpenFile() failed %x (Status %lx)\n", &ObjectAttributes, Status);
SetLastErrorByStatus (Status); SetLastErrorByStatus (Status);
return FALSE; return FALSE;
} }
@ -746,7 +746,7 @@ GetFileAttributesExW(LPCWSTR lpFileName,
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
{ {
DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status); DPRINT1 ("NtQueryInformationFile() failed (Status %lx)\n", Status);
SetLastErrorByStatus (Status); SetLastErrorByStatus (Status);
return FALSE; return FALSE;
} }

View file

@ -41,6 +41,10 @@ static GENERIC_MAPPING ExpEventMapping = {
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | EVENT_QUERY_STATE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | EVENT_QUERY_STATE,
EVENT_ALL_ACCESS}; EVENT_ALL_ACCESS};
static const INFORMATION_CLASS_INFO ExEventInfoClass[] =
{
ICI_SQ_SAME( sizeof(EVENT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* EventBasicInformation */
};
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -92,6 +96,9 @@ ExpInitializeEventImplementation(VOID)
} }
/*
* @implemented
*/
NTSTATUS STDCALL NTSTATUS STDCALL
NtClearEvent(IN HANDLE EventHandle) NtClearEvent(IN HANDLE EventHandle)
{ {
@ -101,16 +108,16 @@ NtClearEvent(IN HANDLE EventHandle)
Status = ObReferenceObjectByHandle(EventHandle, Status = ObReferenceObjectByHandle(EventHandle,
EVENT_MODIFY_STATE, EVENT_MODIFY_STATE,
ExEventObjectType, ExEventObjectType,
UserMode, ExGetPreviousMode(),
(PVOID*)&Event, (PVOID*)&Event,
NULL); NULL);
if (!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{ {
return(Status); KeClearEvent(Event);
} ObDereferenceObject(Event);
KeClearEvent(Event); }
ObDereferenceObject(Event);
return(STATUS_SUCCESS); return Status;
} }
@ -188,68 +195,119 @@ NtCreateEvent(OUT PHANDLE EventHandle,
} }
/*
* @implemented
*/
NTSTATUS STDCALL NTSTATUS STDCALL
NtOpenEvent(OUT PHANDLE EventHandle, NtOpenEvent(OUT PHANDLE EventHandle,
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes) IN POBJECT_ATTRIBUTES ObjectAttributes)
{ {
NTSTATUS Status;
HANDLE hEvent; HANDLE hEvent;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtOpenEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, DesiredAccess, ObjectAttributes);
DPRINT("ObjectName '%wZ'\n", ObjectAttributes->ObjectName); PreviousMode = ExGetPreviousMode();
if(PreviousMode == UserMode)
{
_SEH_TRY
{
ProbeForWrite(EventHandle,
sizeof(HANDLE),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
return Status;
}
}
Status = ObOpenObjectByName(ObjectAttributes, Status = ObOpenObjectByName(ObjectAttributes,
ExEventObjectType, ExEventObjectType,
NULL, NULL,
UserMode, PreviousMode,
DesiredAccess, DesiredAccess,
NULL, NULL,
&hEvent); &hEvent);
if (!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{ {
return(Status); _SEH_TRY
}
Status = MmCopyToCaller(EventHandle, &hEvent, sizeof(HANDLE));
if (!NT_SUCCESS(Status))
{ {
ZwClose(EventHandle); *EventHandle = hEvent;
return(Status);
} }
_SEH_HANDLE
return(Status); {
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
return Status;
} }
/*
* @implemented
*/
NTSTATUS STDCALL NTSTATUS STDCALL
NtPulseEvent(IN HANDLE EventHandle, NtPulseEvent(IN HANDLE EventHandle,
OUT PLONG PreviousState OPTIONAL) OUT PLONG PreviousState OPTIONAL)
{ {
PKEVENT Event; PKEVENT Event;
NTSTATUS Status; KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtPulseEvent(EventHandle %x PreviousState %x)\n", DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
EventHandle, PreviousState); EventHandle, PreviousState);
PreviousMode = ExGetPreviousMode();
if(PreviousState != NULL && PreviousMode == UserMode)
{
_SEH_TRY
{
ProbeForWrite(PreviousState,
sizeof(LONG),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
Status = ObReferenceObjectByHandle(EventHandle, Status = ObReferenceObjectByHandle(EventHandle,
EVENT_MODIFY_STATE, EVENT_MODIFY_STATE,
ExEventObjectType, ExEventObjectType,
UserMode, PreviousMode,
(PVOID*)&Event, (PVOID*)&Event,
NULL); NULL);
if (!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{ {
return(Status); KePulseEvent(Event, EVENT_INCREMENT, FALSE);
} ObDereferenceObject(Event);
/* FIXME - Return the previous state! */
}
KePulseEvent(Event, EVENT_INCREMENT, FALSE); return Status;
ObDereferenceObject(Event);
return(STATUS_SUCCESS);
} }
/*
* @implemented
*/
NTSTATUS STDCALL NTSTATUS STDCALL
NtQueryEvent(IN HANDLE EventHandle, NtQueryEvent(IN HANDLE EventHandle,
IN EVENT_INFORMATION_CLASS EventInformationClass, IN EVENT_INFORMATION_CLASS EventInformationClass,
@ -257,78 +315,129 @@ NtQueryEvent(IN HANDLE EventHandle,
IN ULONG EventInformationLength, IN ULONG EventInformationLength,
OUT PULONG ReturnLength OPTIONAL) OUT PULONG ReturnLength OPTIONAL)
{ {
EVENT_BASIC_INFORMATION Info;
PKEVENT Event; PKEVENT Event;
NTSTATUS Status; KPROCESSOR_MODE PreviousMode;
ULONG RetLen; NTSTATUS Status = STATUS_SUCCESS;
if (EventInformationClass > EventBasicInformation) PreviousMode = ExGetPreviousMode();
return STATUS_INVALID_INFO_CLASS;
DefaultQueryInfoBufferCheck(EventInformationClass,
if (EventInformationLength < sizeof(EVENT_BASIC_INFORMATION)) ExEventInfoClass,
return STATUS_INFO_LENGTH_MISMATCH; EventInformation,
EventInformationLength,
ReturnLength,
PreviousMode,
&Status);
if(!NT_SUCCESS(Status))
{
DPRINT1("NtQueryEvent() failed, Status: 0x%x\n", Status);
return Status;
}
Status = ObReferenceObjectByHandle(EventHandle, Status = ObReferenceObjectByHandle(EventHandle,
EVENT_QUERY_STATE, EVENT_QUERY_STATE,
ExEventObjectType, ExEventObjectType,
UserMode, PreviousMode,
(PVOID*)&Event, (PVOID*)&Event,
NULL); NULL);
if (!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
return Status; {
switch(EventInformationClass)
if (Event->Header.Type == InternalNotificationEvent)
Info.EventType = NotificationEvent;
else
Info.EventType = SynchronizationEvent;
Info.EventState = KeReadStateEvent(Event);
Status = MmCopyToCaller(EventInformation, &Event,
sizeof(EVENT_BASIC_INFORMATION));
if (!NT_SUCCESS(Status))
{ {
ObDereferenceObject(Event); case EventBasicInformation:
return(Status); {
} PEVENT_BASIC_INFORMATION BasicInfo = (PEVENT_BASIC_INFORMATION)EventInformation;
if (ReturnLength != NULL) _SEH_TRY
{
RetLen = sizeof(EVENT_BASIC_INFORMATION);
Status = MmCopyToCaller(ReturnLength, &RetLen, sizeof(ULONG));
if (!NT_SUCCESS(Status))
{ {
ObDereferenceObject(Event); if (Event->Header.Type == InternalNotificationEvent)
return(Status); BasicInfo->EventType = NotificationEvent;
else
BasicInfo->EventType = SynchronizationEvent;
BasicInfo->EventState = KeReadStateEvent(Event);
if(ReturnLength != NULL)
{
*ReturnLength = sizeof(EVENT_BASIC_INFORMATION);
}
} }
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
break;
}
default:
Status = STATUS_NOT_IMPLEMENTED;
break;
} }
ObDereferenceObject(Event); ObDereferenceObject(Event);
return(STATUS_SUCCESS); }
return Status;
} }
/*
* @implemented
*/
NTSTATUS STDCALL NTSTATUS STDCALL
NtResetEvent(IN HANDLE EventHandle, NtResetEvent(IN HANDLE EventHandle,
OUT PLONG PreviousState OPTIONAL) OUT PLONG PreviousState OPTIONAL)
{ {
PKEVENT Event; PKEVENT Event;
NTSTATUS Status; KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtResetEvent(EventHandle %x)\n", EventHandle);
DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
EventHandle, PreviousState);
PreviousMode = ExGetPreviousMode();
if(PreviousState != NULL && PreviousMode == UserMode)
{
_SEH_TRY
{
ProbeForWrite(PreviousState,
sizeof(LONG),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
Status = ObReferenceObjectByHandle(EventHandle, Status = ObReferenceObjectByHandle(EventHandle,
EVENT_MODIFY_STATE, EVENT_MODIFY_STATE,
ExEventObjectType, ExEventObjectType,
UserMode, PreviousMode,
(PVOID*)&Event, (PVOID*)&Event,
NULL); NULL);
if (!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{
LONG Prev = KeResetEvent(Event);
ObDereferenceObject(Event);
if(PreviousState != NULL)
{ {
return(Status); _SEH_TRY
{
*PreviousState = Prev;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
} }
KeResetEvent(Event); }
ObDereferenceObject(Event);
return(STATUS_SUCCESS); return Status;
} }
@ -340,25 +449,58 @@ NtSetEvent(IN HANDLE EventHandle,
OUT PLONG PreviousState OPTIONAL) OUT PLONG PreviousState OPTIONAL)
{ {
PKEVENT Event; PKEVENT Event;
NTSTATUS Status; KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtSetEvent(EventHandle %x)\n", EventHandle);
DPRINT("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
EventHandle, PreviousState);
PreviousMode = ExGetPreviousMode();
if(PreviousState != NULL && PreviousMode == UserMode)
{
_SEH_TRY
{
ProbeForWrite(PreviousState,
sizeof(LONG),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
Status = ObReferenceObjectByHandle(EventHandle, Status = ObReferenceObjectByHandle(EventHandle,
EVENT_MODIFY_STATE, EVENT_MODIFY_STATE,
ExEventObjectType, ExEventObjectType,
UserMode, PreviousMode,
(PVOID*)&Event, (PVOID*)&Event,
NULL); NULL);
if (!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{
LONG Prev = KeSetEvent(Event, EVENT_INCREMENT, FALSE);
ObDereferenceObject(Event);
if(PreviousState != NULL)
{ {
return(Status); _SEH_TRY
{
*PreviousState = Prev;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
} }
KeSetEvent(Event,EVENT_INCREMENT,FALSE); }
ObDereferenceObject(Event);
return(STATUS_SUCCESS); return Status;
} }
/* /*
* @unimplemented * @unimplemented
*/ */

View file

@ -95,39 +95,66 @@ NtCreateEventPair(OUT PHANDLE EventPairHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes) IN POBJECT_ATTRIBUTES ObjectAttributes)
{ {
PKEVENT_PAIR EventPair; PKEVENT_PAIR EventPair;
NTSTATUS Status; HANDLE hEventPair;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
PreviousMode = ExGetPreviousMode();
if(PreviousMode == UserMode)
{
_SEH_TRY
{
ProbeForWrite(EventPairHandle,
sizeof(HANDLE),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
DPRINT("NtCreateEventPair()\n");
Status = ObCreateObject(ExGetPreviousMode(), Status = ObCreateObject(ExGetPreviousMode(),
ExEventPairObjectType, ExEventPairObjectType,
ObjectAttributes, ObjectAttributes,
ExGetPreviousMode(), PreviousMode,
NULL, NULL,
sizeof(KEVENT_PAIR), sizeof(KEVENT_PAIR),
0, 0,
0, 0,
(PVOID*)&EventPair); (PVOID*)&EventPair);
if (!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{
KeInitializeEvent(&EventPair->LowEvent,
SynchronizationEvent,
FALSE);
KeInitializeEvent(&EventPair->HighEvent,
SynchronizationEvent,
FALSE);
Status = ObInsertObject ((PVOID)EventPair,
NULL,
DesiredAccess,
0,
NULL,
&hEventPair);
ObDereferenceObject(EventPair);
if(NT_SUCCESS(Status))
{ {
return(Status); _SEH_TRY
{
*EventPairHandle = hEventPair;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
} }
}
KeInitializeEvent(&EventPair->LowEvent,
SynchronizationEvent,
FALSE);
KeInitializeEvent(&EventPair->HighEvent,
SynchronizationEvent,
FALSE);
Status = ObInsertObject ((PVOID)EventPair,
NULL,
DesiredAccess,
0,
NULL,
EventPairHandle);
ObDereferenceObject(EventPair);
return Status; return Status;
} }
@ -137,18 +164,47 @@ NtOpenEventPair(OUT PHANDLE EventPairHandle,
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes) IN POBJECT_ATTRIBUTES ObjectAttributes)
{ {
NTSTATUS Status; HANDLE hEventPair;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtOpenEventPair()\n"); PreviousMode = ExGetPreviousMode();
if(PreviousMode == UserMode)
{
_SEH_TRY
{
ProbeForWrite(EventPairHandle,
sizeof(HANDLE),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
Status = ObOpenObjectByName(ObjectAttributes, Status = ObOpenObjectByName(ObjectAttributes,
ExEventPairObjectType, ExEventPairObjectType,
NULL, NULL,
UserMode, PreviousMode,
DesiredAccess, DesiredAccess,
NULL, NULL,
EventPairHandle); &hEventPair);
if(NT_SUCCESS(Status))
{
_SEH_TRY
{
*EventPairHandle = hEventPair;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
return Status; return Status;
} }
@ -157,26 +213,30 @@ NTSTATUS STDCALL
NtSetHighEventPair(IN HANDLE EventPairHandle) NtSetHighEventPair(IN HANDLE EventPairHandle)
{ {
PKEVENT_PAIR EventPair; PKEVENT_PAIR EventPair;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status; NTSTATUS Status;
DPRINT("NtSetHighEventPair(EventPairHandle %x)\n", DPRINT("NtSetHighEventPair(EventPairHandle %x)\n",
EventPairHandle); EventPairHandle);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(EventPairHandle, Status = ObReferenceObjectByHandle(EventPairHandle,
EVENT_PAIR_ALL_ACCESS, SYNCHRONIZE,
ExEventPairObjectType, ExEventPairObjectType,
UserMode, PreviousMode,
(PVOID*)&EventPair, (PVOID*)&EventPair,
NULL); NULL);
if (!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
return(Status); {
KeSetEvent(&EventPair->HighEvent,
EVENT_INCREMENT,
FALSE);
KeSetEvent(&EventPair->HighEvent, ObDereferenceObject(EventPair);
EVENT_INCREMENT, }
FALSE);
return Status;
ObDereferenceObject(EventPair);
return(STATUS_SUCCESS);
} }
@ -184,32 +244,36 @@ NTSTATUS STDCALL
NtSetHighWaitLowEventPair(IN HANDLE EventPairHandle) NtSetHighWaitLowEventPair(IN HANDLE EventPairHandle)
{ {
PKEVENT_PAIR EventPair; PKEVENT_PAIR EventPair;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status; NTSTATUS Status;
DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n",
EventPairHandle); EventPairHandle);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(EventPairHandle, Status = ObReferenceObjectByHandle(EventPairHandle,
EVENT_PAIR_ALL_ACCESS, SYNCHRONIZE,
ExEventPairObjectType, ExEventPairObjectType,
UserMode, PreviousMode,
(PVOID*)&EventPair, (PVOID*)&EventPair,
NULL); NULL);
if (!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
return(Status); {
KeSetEvent(&EventPair->HighEvent,
EVENT_INCREMENT,
TRUE);
KeSetEvent(&EventPair->HighEvent, KeWaitForSingleObject(&EventPair->LowEvent,
EVENT_INCREMENT, WrEventPair,
TRUE); PreviousMode,
FALSE,
NULL);
KeWaitForSingleObject(&EventPair->LowEvent, ObDereferenceObject(EventPair);
WrEventPair, }
UserMode,
FALSE, return Status;
NULL);
ObDereferenceObject(EventPair);
return(STATUS_SUCCESS);
} }
@ -217,26 +281,30 @@ NTSTATUS STDCALL
NtSetLowEventPair(IN HANDLE EventPairHandle) NtSetLowEventPair(IN HANDLE EventPairHandle)
{ {
PKEVENT_PAIR EventPair; PKEVENT_PAIR EventPair;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status; NTSTATUS Status;
DPRINT("NtSetLowEventPair(EventPairHandle %x)\n", DPRINT("NtSetLowEventPair(EventPairHandle %x)\n",
EventPairHandle); EventPairHandle);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(EventPairHandle, Status = ObReferenceObjectByHandle(EventPairHandle,
EVENT_PAIR_ALL_ACCESS, SYNCHRONIZE,
ExEventPairObjectType, ExEventPairObjectType,
UserMode, PreviousMode,
(PVOID*)&EventPair, (PVOID*)&EventPair,
NULL); NULL);
if (!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
return(Status); {
KeSetEvent(&EventPair->LowEvent,
EVENT_INCREMENT,
FALSE);
KeSetEvent(&EventPair->LowEvent, ObDereferenceObject(EventPair);
EVENT_INCREMENT, }
FALSE);
return Status;
ObDereferenceObject(EventPair);
return(STATUS_SUCCESS);
} }
@ -244,32 +312,36 @@ NTSTATUS STDCALL
NtSetLowWaitHighEventPair(IN HANDLE EventPairHandle) NtSetLowWaitHighEventPair(IN HANDLE EventPairHandle)
{ {
PKEVENT_PAIR EventPair; PKEVENT_PAIR EventPair;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status; NTSTATUS Status;
DPRINT("NtSetLowWaitHighEventPair(EventPairHandle %x)\n", DPRINT("NtSetLowWaitHighEventPair(EventPairHandle %x)\n",
EventPairHandle); EventPairHandle);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(EventPairHandle, Status = ObReferenceObjectByHandle(EventPairHandle,
EVENT_PAIR_ALL_ACCESS, SYNCHRONIZE,
ExEventPairObjectType, ExEventPairObjectType,
UserMode, PreviousMode,
(PVOID*)&EventPair, (PVOID*)&EventPair,
NULL); NULL);
if (!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
return(Status); {
KeSetEvent(&EventPair->LowEvent,
EVENT_INCREMENT,
TRUE);
KeSetEvent(&EventPair->LowEvent, KeWaitForSingleObject(&EventPair->HighEvent,
EVENT_INCREMENT, WrEventPair,
TRUE); PreviousMode,
FALSE,
NULL);
KeWaitForSingleObject(&EventPair->HighEvent, ObDereferenceObject(EventPair);
WrEventPair, }
UserMode,
FALSE, return Status;
NULL);
ObDereferenceObject(EventPair);
return(STATUS_SUCCESS);
} }
@ -277,28 +349,32 @@ NTSTATUS STDCALL
NtWaitLowEventPair(IN HANDLE EventPairHandle) NtWaitLowEventPair(IN HANDLE EventPairHandle)
{ {
PKEVENT_PAIR EventPair; PKEVENT_PAIR EventPair;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status; NTSTATUS Status;
DPRINT("NtWaitLowEventPair(EventPairHandle %x)\n", DPRINT("NtWaitLowEventPair(EventPairHandle %x)\n",
EventPairHandle); EventPairHandle);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(EventPairHandle, Status = ObReferenceObjectByHandle(EventPairHandle,
EVENT_PAIR_ALL_ACCESS, SYNCHRONIZE,
ExEventPairObjectType, ExEventPairObjectType,
UserMode, PreviousMode,
(PVOID*)&EventPair, (PVOID*)&EventPair,
NULL); NULL);
if (!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
return(Status); {
KeWaitForSingleObject(&EventPair->LowEvent,
WrEventPair,
PreviousMode,
FALSE,
NULL);
KeWaitForSingleObject(&EventPair->LowEvent, ObDereferenceObject(EventPair);
WrEventPair, }
UserMode,
FALSE, return Status;
NULL);
ObDereferenceObject(EventPair);
return(STATUS_SUCCESS);
} }
@ -306,28 +382,32 @@ NTSTATUS STDCALL
NtWaitHighEventPair(IN HANDLE EventPairHandle) NtWaitHighEventPair(IN HANDLE EventPairHandle)
{ {
PKEVENT_PAIR EventPair; PKEVENT_PAIR EventPair;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status; NTSTATUS Status;
DPRINT("NtWaitHighEventPair(EventPairHandle %x)\n", DPRINT("NtWaitHighEventPair(EventPairHandle %x)\n",
EventPairHandle); EventPairHandle);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(EventPairHandle, Status = ObReferenceObjectByHandle(EventPairHandle,
EVENT_PAIR_ALL_ACCESS, SYNCHRONIZE,
ExEventPairObjectType, ExEventPairObjectType,
UserMode, PreviousMode,
(PVOID*)&EventPair, (PVOID*)&EventPair,
NULL); NULL);
if (!NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
return(Status); {
KeWaitForSingleObject(&EventPair->HighEvent,
WrEventPair,
PreviousMode,
FALSE,
NULL);
KeWaitForSingleObject(&EventPair->HighEvent, ObDereferenceObject(EventPair);
WrEventPair, }
UserMode,
FALSE,
NULL);
ObDereferenceObject(EventPair); return Status;
return(STATUS_SUCCESS);
} }
#ifdef _ENABLE_THRDEVTPAIR #ifdef _ENABLE_THRDEVTPAIR
@ -349,8 +429,8 @@ NtSetLowWaitHighThread(
PKEVENT_PAIR EventPair; PKEVENT_PAIR EventPair;
NTSTATUS Status; NTSTATUS Status;
KIRQL Irql; KIRQL Irql;
Thread = PsGetCurrentThread(); PreviousMode = ExGetPreviousMode();
if(!Thread->EventPair) if(!Thread->EventPair)
return STATUS_NO_EVENT_PAIR; return STATUS_NO_EVENT_PAIR;

View file

@ -40,6 +40,11 @@ static GENERIC_MAPPING ExpMutantMapping = {
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | MUTANT_QUERY_STATE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | MUTANT_QUERY_STATE,
MUTANT_ALL_ACCESS}; MUTANT_ALL_ACCESS};
static const INFORMATION_CLASS_INFO ExMutantInfoClass[] =
{
ICI_SQ_SAME( sizeof(MUTANT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* MutantBasicInformation */
};
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -103,105 +108,70 @@ ExpInitializeMutantImplementation(VOID)
} }
/*
* @implemented
*/
NTSTATUS STDCALL NTSTATUS STDCALL
NtCreateMutant(OUT PHANDLE MutantHandle, NtCreateMutant(OUT PHANDLE MutantHandle,
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN BOOLEAN InitialOwner) IN BOOLEAN InitialOwner)
{ {
KPROCESSOR_MODE PreviousMode;
HANDLE hMutant;
PKMUTEX Mutant; PKMUTEX Mutant;
NTSTATUS Status; NTSTATUS Status = STATUS_SUCCESS;
PreviousMode = ExGetPreviousMode();
Status = ObCreateObject(ExGetPreviousMode(), if(PreviousMode == UserMode)
{
_SEH_TRY
{
ProbeForWrite(MutantHandle,
sizeof(HANDLE),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
Status = ObCreateObject(PreviousMode,
ExMutantObjectType, ExMutantObjectType,
ObjectAttributes, ObjectAttributes,
ExGetPreviousMode(), PreviousMode,
NULL, NULL,
sizeof(KMUTANT), sizeof(KMUTANT),
0, 0,
0, 0,
(PVOID*)&Mutant); (PVOID*)&Mutant);
if (!NT_SUCCESS(Status))
{
return(Status);
}
KeInitializeMutant(Mutant,
InitialOwner);
Status = ObInsertObject ((PVOID)Mutant,
NULL,
DesiredAccess,
0,
NULL,
MutantHandle);
ObDereferenceObject(Mutant);
return Status;
}
NTSTATUS STDCALL
NtOpenMutant(OUT PHANDLE MutantHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes)
{
return(ObOpenObjectByName(ObjectAttributes,
ExMutantObjectType,
NULL,
ExGetPreviousMode(),
DesiredAccess,
NULL,
MutantHandle));
}
NTSTATUS STDCALL
NtQueryMutant(IN HANDLE MutantHandle,
IN MUTANT_INFORMATION_CLASS MutantInformationClass,
OUT PVOID MutantInformation,
IN ULONG MutantInformationLength,
OUT PULONG ResultLength OPTIONAL)
{
MUTANT_BASIC_INFORMATION SafeMutantInformation;
PKMUTANT Mutant;
NTSTATUS Status;
if (MutantInformationClass > MutantBasicInformation)
return(STATUS_INVALID_INFO_CLASS);
if (MutantInformationLength < sizeof(MUTANT_BASIC_INFORMATION))
return(STATUS_INFO_LENGTH_MISMATCH);
Status = ObReferenceObjectByHandle(MutantHandle,
MUTANT_QUERY_STATE,
ExMutantObjectType,
ExGetPreviousMode(),
(PVOID*)&Mutant,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
SafeMutantInformation.Count = KeReadStateMutant(Mutant);
SafeMutantInformation.Owned = (Mutant->OwnerThread != NULL);
SafeMutantInformation.Abandoned = Mutant->Abandoned;
ObDereferenceObject(Mutant);
Status = MmCopyToCaller(MutantInformation, &SafeMutantInformation, sizeof(MUTANT_BASIC_INFORMATION));
if(NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{ {
if(ResultLength != NULL) KeInitializeMutant(Mutant,
InitialOwner);
Status = ObInsertObject((PVOID)Mutant,
NULL,
DesiredAccess,
0,
NULL,
&hMutant);
ObDereferenceObject(Mutant);
if(NT_SUCCESS(Status))
{ {
ULONG RetLen = sizeof(MUTANT_BASIC_INFORMATION); _SEH_TRY
Status = MmCopyToCaller(ResultLength, &RetLen, sizeof(ULONG)); {
} *MutantHandle = hMutant;
else }
{ _SEH_HANDLE
Status = STATUS_SUCCESS; {
Status = _SEH_GetExceptionCode();
}
_SEH_END;
} }
} }
@ -209,41 +179,198 @@ NtQueryMutant(IN HANDLE MutantHandle,
} }
/*
* @implemented
*/
NTSTATUS STDCALL NTSTATUS STDCALL
NtReleaseMutant(IN HANDLE MutantHandle, NtOpenMutant(OUT PHANDLE MutantHandle,
IN PLONG PreviousCount OPTIONAL) IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes)
{ {
PKMUTANT Mutant; HANDLE hMutant;
NTSTATUS Status; KPROCESSOR_MODE PreviousMode;
LONG Count; NTSTATUS Status = STATUS_SUCCESS;
Status = ObReferenceObjectByHandle(MutantHandle, DPRINT1("NtOpenMutant(0x%x, 0x%x, 0x%x)\n", MutantHandle, DesiredAccess, ObjectAttributes);
MUTANT_ALL_ACCESS,
ExMutantObjectType,
ExGetPreviousMode(),
(PVOID*)&Mutant,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Count = KeReleaseMutant(Mutant, PreviousMode = ExGetPreviousMode();
MUTANT_INCREMENT,
0,
FALSE);
ObDereferenceObject(Mutant);
if (PreviousCount != NULL) if(PreviousMode == UserMode)
{
_SEH_TRY
{ {
Status = MmCopyToCaller(PreviousCount, &Count, sizeof(LONG)); ProbeForWrite(MutantHandle,
sizeof(HANDLE),
sizeof(ULONG));
} }
else _SEH_HANDLE
{ {
Status = STATUS_SUCCESS; Status = _SEH_GetExceptionCode();
} }
_SEH_END;
if(!NT_SUCCESS(Status))
{
return Status;
}
}
Status = ObOpenObjectByName(ObjectAttributes,
ExMutantObjectType,
NULL,
PreviousMode,
DesiredAccess,
NULL,
&hMutant);
if(NT_SUCCESS(Status))
{
_SEH_TRY
{
*MutantHandle = hMutant;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
return Status; return Status;
} }
/*
* @implemented
*/
NTSTATUS STDCALL
NtQueryMutant(IN HANDLE MutantHandle,
IN MUTANT_INFORMATION_CLASS MutantInformationClass,
OUT PVOID MutantInformation,
IN ULONG MutantInformationLength,
OUT PULONG ResultLength OPTIONAL)
{
PKMUTANT Mutant;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
PreviousMode = ExGetPreviousMode();
DefaultQueryInfoBufferCheck(MutantInformationClass,
ExMutantInfoClass,
MutantInformation,
MutantInformationLength,
ResultLength,
PreviousMode,
&Status);
if(!NT_SUCCESS(Status))
{
DPRINT1("NtQueryMutant() failed, Status: 0x%x\n", Status);
return Status;
}
Status = ObReferenceObjectByHandle(MutantHandle,
MUTANT_QUERY_STATE,
ExMutantObjectType,
PreviousMode,
(PVOID*)&Mutant,
NULL);
if(NT_SUCCESS(Status))
{
switch(MutantInformationClass)
{
case MutantBasicInformation:
{
PMUTANT_BASIC_INFORMATION BasicInfo = (PMUTANT_BASIC_INFORMATION)MutantInformation;
_SEH_TRY
{
BasicInfo->Count = KeReadStateMutant(Mutant);
BasicInfo->Owned = (Mutant->OwnerThread != NULL);
BasicInfo->Abandoned = Mutant->Abandoned;
if(ResultLength != NULL)
{
*ResultLength = sizeof(MUTANT_BASIC_INFORMATION);
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
break;
}
default:
Status = STATUS_NOT_IMPLEMENTED;
break;
}
ObDereferenceObject(Mutant);
}
return Status;
}
/*
* @implemented
*/
NTSTATUS STDCALL
NtReleaseMutant(IN HANDLE MutantHandle,
IN PLONG PreviousCount OPTIONAL)
{
PKMUTANT Mutant;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtReleaseMutant(MutantHandle 0%x PreviousCount 0%x)\n",
MutantHandle, PreviousCount);
PreviousMode = ExGetPreviousMode();
if(PreviousCount != NULL && PreviousMode == UserMode)
{
_SEH_TRY
{
ProbeForWrite(PreviousCount,
sizeof(LONG),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
Status = ObReferenceObjectByHandle(MutantHandle,
MUTANT_QUERY_STATE,
ExMutantObjectType,
PreviousMode,
(PVOID*)&Mutant,
NULL);
if(NT_SUCCESS(Status))
{
LONG Prev = KeReleaseMutant(Mutant, MUTANT_INCREMENT, 0, FALSE);
ObDereferenceObject(Mutant);
if(PreviousCount != NULL)
{
_SEH_TRY
{
*PreviousCount = Prev;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
}
return Status;
}
/* EOF */ /* EOF */

View file

@ -538,7 +538,7 @@ NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
NTSTATUS Status; NTSTATUS Status;
/* Open the file */ /* Open the file */
Status = NtOpenFile (&FileHandle, Status = ZwOpenFile (&FileHandle,
SYNCHRONIZE | FILE_READ_ATTRIBUTES, SYNCHRONIZE | FILE_READ_ATTRIBUTES,
ObjectAttributes, ObjectAttributes,
&IoStatusBlock, &IoStatusBlock,
@ -546,20 +546,20 @@ NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
FILE_SYNCHRONOUS_IO_NONALERT); FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
{ {
DPRINT ("NtOpenFile() failed (Status %lx)\n", Status); DPRINT ("ZwOpenFile() failed (Status %lx)\n", Status);
return Status; return Status;
} }
/* Get file attributes */ /* Get file attributes */
Status = NtQueryInformationFile (FileHandle, Status = ZwQueryInformationFile (FileHandle,
&IoStatusBlock, &IoStatusBlock,
FileInformation, FileInformation,
sizeof(FILE_BASIC_INFORMATION), sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation); FileBasicInformation);
NtClose (FileHandle); ZwClose (FileHandle);
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
{ {
DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status); DPRINT ("ZwQueryInformationFile() failed (Status %lx)\n", Status);
} }
return Status; return Status;
@ -575,7 +575,7 @@ NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
NTSTATUS Status; NTSTATUS Status;
/* Open the file */ /* Open the file */
Status = NtOpenFile (&FileHandle, Status = ZwOpenFile (&FileHandle,
SYNCHRONIZE | FILE_READ_ATTRIBUTES, SYNCHRONIZE | FILE_READ_ATTRIBUTES,
ObjectAttributes, ObjectAttributes,
&IoStatusBlock, &IoStatusBlock,
@ -583,20 +583,20 @@ NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
FILE_SYNCHRONOUS_IO_NONALERT); FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
{ {
DPRINT ("NtOpenFile() failed (Status %lx)\n", Status); DPRINT ("ZwOpenFile() failed (Status %lx)\n", Status);
return Status; return Status;
} }
/* Get file attributes */ /* Get file attributes */
Status = NtQueryInformationFile (FileHandle, Status = ZwQueryInformationFile (FileHandle,
&IoStatusBlock, &IoStatusBlock,
FileInformation, FileInformation,
sizeof(FILE_NETWORK_OPEN_INFORMATION), sizeof(FILE_NETWORK_OPEN_INFORMATION),
FileNetworkOpenInformation); FileNetworkOpenInformation);
NtClose (FileHandle); ZwClose (FileHandle);
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
{ {
DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status); DPRINT ("ZwQueryInformationFile() failed (Status %lx)\n", Status);
} }
return Status; return Status;

View file

@ -608,7 +608,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
{ {
ProbeForRead(ObjectAttributes, ProbeForRead(ObjectAttributes,
sizeof(OBJECT_ATTRIBUTES), sizeof(OBJECT_ATTRIBUTES),
sizeof(ULONG)); sizeof(USHORT)); /*FIXME: HACK! kernel32/file/file.c:~734 is having a weird stack */
} }
_SEH_HANDLE _SEH_HANDLE
{ {

View file

@ -52,10 +52,10 @@
VOID CALLBACK VOID CALLBACK
ServiceMain(DWORD argc, LPTSTR *argv) ServiceMain(DWORD argc, LPTSTR *argv)
{ {
DPRINT1("ServiceMain() called\n"); DPRINT("ServiceMain() called\n");
DPRINT1("ServiceMain() done\n"); DPRINT("ServiceMain() done\n");
} }