You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
672 lines
20 KiB
672 lines
20 KiB
|
|
/* object.c -
|
|
*
|
|
* Handles display of object attributes
|
|
*/
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "winfile.h"
|
|
#include "object.h"
|
|
|
|
INT_PTR APIENTRY ObjectAttributesDlgProc(HWND, UINT, WPARAM, LPARAM);
|
|
BOOL ObjectInformationDlgInit(HWND, LPSTR);
|
|
HANDLE OpenObject(HWND, LPSTR);
|
|
BOOL GetObjectInfo(HWND, HANDLE);
|
|
VOID CloseObject(HANDLE);
|
|
|
|
VOID StripObjectPath(LPSTR lpszPath);
|
|
VOID StripObjectSpec(LPSTR lpszPath);
|
|
|
|
|
|
// Define known object type names
|
|
|
|
#define DIRECTORYTYPE L"Directory"
|
|
#define SYMLINKTYPE L"SymbolicLink"
|
|
#define ADAPTERTYPE L"Adapter"
|
|
#define CONTROLLERTYPE L"Controller"
|
|
#define DEVICETYPE L"Device"
|
|
#define DRIVERTYPE L"Driver"
|
|
#define EVENTTYPE L"Event"
|
|
#define EVENTPAIRTYPE L"EventPair"
|
|
#define FILETYPE L"File"
|
|
#define MUTANTTYPE L"Mutant"
|
|
#define PORTTYPE L"Port"
|
|
#define PROFILETYPE L"Profile"
|
|
#define SECTIONTYPE L"Section"
|
|
#define SEMAPHORETYPE L"Semaphore"
|
|
#define TIMERTYPE L"Timer"
|
|
#define TYPETYPE L"Type"
|
|
#define PROCESSTYPE L"Process"
|
|
|
|
|
|
|
|
VOID
|
|
DisplayObjectInformation(
|
|
HWND hwndParent,
|
|
LPSTR lpstrObject
|
|
)
|
|
{
|
|
WNDPROC lpProc;
|
|
HANDLE hInst = hAppInstance;
|
|
|
|
DialogBoxParam(hInst,(LPSTR)IDD_OBJATTRS, hwndParent, ObjectAttributesDlgProc, (LPARAM)lpstrObject);
|
|
}
|
|
|
|
|
|
INT_PTR
|
|
APIENTRY
|
|
ObjectAttributesDlgProc(
|
|
HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
switch (message) {
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
if (!ObjectInformationDlgInit(hDlg, (HANDLE)lParam)) {
|
|
// Failed to initialize dialog, get out
|
|
EndDialog(hDlg, FALSE);
|
|
}
|
|
|
|
return (TRUE);
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam)) {
|
|
case IDOK:
|
|
// we're done, drop through to quit dialog....
|
|
|
|
case IDCANCEL:
|
|
|
|
//MainDlgEnd(hDlg, LOWORD(wParam) == IDOK);
|
|
|
|
EndDialog(hDlg, TRUE);
|
|
return TRUE;
|
|
break;
|
|
|
|
default:
|
|
// We didn't process this message
|
|
return FALSE;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
// We didn't process this message
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
// We processed the message
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
ObjectInformationDlgInit(
|
|
HWND hwnd,
|
|
LPSTR lpstrObject
|
|
)
|
|
{
|
|
HANDLE ObjectHandle;
|
|
BOOL Result;
|
|
|
|
ObjectHandle = OpenObject(hwnd, lpstrObject);
|
|
if (ObjectHandle == NULL) {
|
|
return(FALSE);
|
|
}
|
|
|
|
Result = GetObjectInfo(hwnd, ObjectHandle);
|
|
|
|
CloseObject(ObjectHandle);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
|
|
/* Open the object given only its name.
|
|
* First find the object type by enumerating the directory entries.
|
|
* Then call the type-specific open routine to get a handle
|
|
*/
|
|
HANDLE
|
|
OpenObject(
|
|
HWND hwnd,
|
|
LPSTR lpstrObject
|
|
)
|
|
{
|
|
#define BUFFER_SIZE 1024
|
|
|
|
NTSTATUS Status;
|
|
HANDLE DirectoryHandle;
|
|
ULONG Context = 0;
|
|
ULONG ReturnedLength;
|
|
CHAR Buffer[BUFFER_SIZE];
|
|
ANSI_STRING AnsiString;
|
|
POBJECT_DIRECTORY_INFORMATION DirInfo;
|
|
WCHAR ObjectNameBuf[MAX_PATH];
|
|
UNICODE_STRING ObjectName;
|
|
WCHAR ObjectTypeBuf[MAX_PATH];
|
|
UNICODE_STRING ObjectType;
|
|
HANDLE ObjectHandle;
|
|
OBJECT_ATTRIBUTES Attributes;
|
|
UNICODE_STRING DirectoryName;
|
|
IO_STATUS_BLOCK IOStatusBlock;
|
|
|
|
//DbgPrint("Open object: raw full name = <%s>\n", lpstrObject);
|
|
|
|
// Remove drive letter
|
|
while ((*lpstrObject != 0) && (*lpstrObject != '\\')) {
|
|
lpstrObject ++;
|
|
}
|
|
|
|
//DbgPrint("Open object: full name = <%s>\n", lpstrObject);
|
|
|
|
// Initialize the object type buffer
|
|
ObjectType.Buffer = ObjectTypeBuf;
|
|
ObjectType.MaximumLength = sizeof(ObjectTypeBuf);
|
|
|
|
// Initialize the object name string
|
|
strcpy(Buffer, lpstrObject);
|
|
StripObjectPath(Buffer);
|
|
RtlInitAnsiString(&AnsiString, Buffer);
|
|
|
|
ObjectName.Buffer = ObjectNameBuf;
|
|
ObjectName.MaximumLength = sizeof(ObjectNameBuf);
|
|
|
|
Status = RtlAnsiStringToUnicodeString(&ObjectName, &AnsiString, FALSE);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
//DbgPrint("Open object: name only = <%wZ>\n", &ObjectName);
|
|
|
|
//
|
|
// Open the directory for list directory access
|
|
//
|
|
|
|
strcpy(Buffer, lpstrObject);
|
|
StripObjectSpec(Buffer);
|
|
|
|
RtlInitAnsiString(&AnsiString, Buffer);
|
|
Status = RtlAnsiStringToUnicodeString( &DirectoryName, &AnsiString, TRUE);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
InitializeObjectAttributes( &Attributes,
|
|
&DirectoryName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL );
|
|
|
|
//DbgPrint("Open object: dir only = <%wZ>\n", &DirectoryName);
|
|
|
|
if (!NT_SUCCESS( Status = NtOpenDirectoryObject( &DirectoryHandle,
|
|
STANDARD_RIGHTS_READ |
|
|
DIRECTORY_QUERY |
|
|
DIRECTORY_TRAVERSE,
|
|
&Attributes ) )) {
|
|
|
|
if (Status == STATUS_OBJECT_TYPE_MISMATCH) {
|
|
DbgPrint( "%wZ is not a valid Object Directory Object name\n",
|
|
&DirectoryName );
|
|
} else {
|
|
DbgPrint("OpenObject: failed to open directory, status = 0x%lx\n\r", Status);
|
|
}
|
|
|
|
RtlFreeUnicodeString(&DirectoryName);
|
|
|
|
MessageBox(hwnd, "Unable to open object", NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
|
|
return NULL;
|
|
}
|
|
|
|
RtlFreeUnicodeString(&DirectoryName);
|
|
|
|
|
|
//
|
|
// Query the entire directory in one sweep
|
|
//
|
|
ObjectType.Length = 0;
|
|
|
|
for (Status = NtQueryDirectoryObject( DirectoryHandle,
|
|
Buffer,
|
|
sizeof(Buffer),
|
|
// LATER FALSE,
|
|
TRUE, // one entry at a time for now
|
|
TRUE,
|
|
&Context,
|
|
&ReturnedLength );
|
|
ObjectType.Length == 0;
|
|
Status = NtQueryDirectoryObject( DirectoryHandle,
|
|
Buffer,
|
|
sizeof(Buffer),
|
|
// LATER FALSE,
|
|
TRUE, // one entry at a time for now
|
|
FALSE,
|
|
&Context,
|
|
&ReturnedLength ) ) {
|
|
//
|
|
// Check the status of the operation.
|
|
//
|
|
|
|
if (!NT_SUCCESS( Status )) {
|
|
if (Status != STATUS_NO_MORE_ENTRIES) {
|
|
DbgPrint("OpenObject: failed to query directory object, status = 0x%lx\n\r", Status);
|
|
}
|
|
break;
|
|
}
|
|
|
|
//
|
|
// For every record in the buffer compare name with the one we're
|
|
// looking for
|
|
//
|
|
|
|
//
|
|
// Point to the first record in the buffer, we are guaranteed to have
|
|
// one otherwise Status would have been No More Files
|
|
//
|
|
|
|
DirInfo = (POBJECT_DIRECTORY_INFORMATION)Buffer;
|
|
|
|
while (DirInfo->Name.Length != 0) {
|
|
|
|
//
|
|
// Compare with object we're searching for
|
|
//
|
|
|
|
//DbgPrint("Found object <%wZ>\n", &(DirInfo->Name));
|
|
|
|
if (RtlEqualString((PSTRING)&ObjectName, (PSTRING)&(DirInfo->Name), TRUE)) {
|
|
RtlCopyString((PSTRING)&ObjectType, (PSTRING)&DirInfo->TypeName);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Advance DirInfo to the next entry
|
|
//
|
|
|
|
DirInfo ++;
|
|
}
|
|
}
|
|
|
|
if (ObjectType.Length == 0) {
|
|
DbgPrint("Object not found in directory\n\r");
|
|
MessageBox(hwnd, "Unable to open object", NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
|
|
return(NULL);
|
|
}
|
|
|
|
// We now have the type of the object in ObjectType
|
|
// We still have the full object name in lpstrObject
|
|
// Use the appropriate open routine to get a handle
|
|
|
|
ObjectHandle = NULL;
|
|
|
|
RtlInitString(&AnsiString, lpstrObject);
|
|
Status = RtlAnsiStringToUnicodeString(&ObjectName, &AnsiString, TRUE);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
InitializeObjectAttributes(&Attributes,
|
|
&ObjectName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
switch (CalcAttributes(&ObjectType)) {
|
|
|
|
case ATTR_SYMLINK:
|
|
Status = NtOpenSymbolicLinkObject(&ObjectHandle,
|
|
READ_CONTROL | SYMBOLIC_LINK_QUERY,
|
|
&Attributes);
|
|
break;
|
|
|
|
case ATTR_EVENT:
|
|
Status = NtOpenEvent(&ObjectHandle,
|
|
READ_CONTROL,
|
|
&Attributes);
|
|
break;
|
|
|
|
case ATTR_EVENTPAIR:
|
|
Status = NtOpenEventPair(&ObjectHandle,
|
|
READ_CONTROL,
|
|
&Attributes);
|
|
break;
|
|
|
|
case ATTR_FILE:
|
|
Status = NtOpenFile(&ObjectHandle,
|
|
READ_CONTROL,
|
|
&Attributes,
|
|
&IOStatusBlock,
|
|
FILE_SHARE_VALID_FLAGS,
|
|
0);
|
|
break;
|
|
|
|
case ATTR_MUTANT:
|
|
Status = NtOpenMutant(&ObjectHandle,
|
|
READ_CONTROL,
|
|
&Attributes);
|
|
break;
|
|
|
|
case ATTR_SECTION:
|
|
Status = NtOpenSection(&ObjectHandle,
|
|
READ_CONTROL,
|
|
&Attributes);
|
|
break;
|
|
|
|
case ATTR_SEMAPHORE:
|
|
Status = NtOpenSemaphore(&ObjectHandle,
|
|
READ_CONTROL,
|
|
&Attributes);
|
|
break;
|
|
|
|
case ATTR_TIMER:
|
|
Status = NtOpenTimer(&ObjectHandle,
|
|
READ_CONTROL,
|
|
&Attributes);
|
|
break;
|
|
|
|
case ATTR_PROCESS:
|
|
Status = NtOpenProcess(&ObjectHandle,
|
|
READ_CONTROL,
|
|
&Attributes,
|
|
NULL);
|
|
break;
|
|
|
|
default:
|
|
DbgPrint("No open routine for this object type\n\r");
|
|
MessageBox(hwnd, "I don't know how to open an object of this type", NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
|
|
Status = 0;
|
|
break;
|
|
}
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
DbgPrint("Type specific open failed, status = 0x%lx\n\r", Status);
|
|
MessageBox(hwnd, "Object open failed", NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
|
|
ObjectHandle = NULL;
|
|
}
|
|
|
|
RtlFreeUnicodeString(&ObjectName);
|
|
|
|
return(ObjectHandle);
|
|
}
|
|
|
|
|
|
VOID
|
|
CloseObject(
|
|
HANDLE ObjectHandle
|
|
)
|
|
{
|
|
NtClose(ObjectHandle);
|
|
}
|
|
|
|
|
|
BOOL
|
|
GetObjectInfo(
|
|
HWND hwnd,
|
|
HANDLE ObjectHandle
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
OBJECT_BASIC_INFORMATION BasicInfo;
|
|
OBJECT_TYPE_INFORMATION TypeInfo;
|
|
WCHAR TypeName[ 64 ];
|
|
#define BUFFER_SIZE 1024
|
|
CHAR Buffer[BUFFER_SIZE];
|
|
STRING String;
|
|
TIME_FIELDS TimeFields;
|
|
WCHAR UnicodeBuffer[BUFFER_SIZE];
|
|
UNICODE_STRING UnicodeString;
|
|
|
|
//
|
|
// Name
|
|
//
|
|
|
|
Status = NtQueryObject(ObjectHandle, ObjectNameInformation,
|
|
(PVOID)Buffer, sizeof(Buffer), NULL);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
DbgPrint("GetObjectInfo: Failed to get name info, status = 0x%lx\n\r", Status);
|
|
return(FALSE);
|
|
}
|
|
|
|
Status = RtlUnicodeStringToAnsiString(&String, &(((POBJECT_NAME_INFORMATION)Buffer)->Name), TRUE);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
SetDlgItemText(hwnd, IDS_NAME, String.Buffer);
|
|
|
|
RtlFreeAnsiString(&String);
|
|
|
|
|
|
//
|
|
// Type
|
|
//
|
|
|
|
Status = NtQueryObject(ObjectHandle, ObjectTypeInformation,
|
|
(PVOID)Buffer, sizeof(Buffer), NULL);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
DbgPrint("GetObjectInfo: Failed to get type info, status = 0x%lx\n\r", Status);
|
|
return(FALSE);
|
|
}
|
|
|
|
Status = RtlUnicodeStringToAnsiString(&String, &(((POBJECT_TYPE_INFORMATION)Buffer)->TypeName), TRUE);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
SetDlgItemText(hwnd, IDS_TYPE, String.Buffer);
|
|
|
|
RtlFreeAnsiString(&String);
|
|
|
|
|
|
//
|
|
// Symbolic link target if this is a symlink
|
|
//
|
|
|
|
RtlInitUnicodeString(&UnicodeString, SYMLINKTYPE);
|
|
|
|
if (RtlEqualString((PSTRING)&UnicodeString,
|
|
(PSTRING)&(((POBJECT_TYPE_INFORMATION)Buffer)->TypeName), TRUE)) {
|
|
|
|
ShowWindow(GetDlgItem(hwnd, IDS_OTHERLABEL), SW_SHOWNOACTIVATE);
|
|
ShowWindow(GetDlgItem(hwnd, IDS_OTHERTEXT), SW_SHOWNOACTIVATE);
|
|
|
|
UnicodeString.Buffer = UnicodeBuffer;
|
|
UnicodeString.MaximumLength = sizeof(UnicodeBuffer);
|
|
|
|
Status = NtQuerySymbolicLinkObject(ObjectHandle, &UnicodeString, NULL);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
DbgPrint("GetObjectInfo: Failed to query symbolic link target, status = 0x%lx\n\r", Status);
|
|
return(FALSE);
|
|
}
|
|
|
|
RtlUnicodeStringToAnsiString(&String, &UnicodeString, TRUE);
|
|
|
|
SetDlgItemText(hwnd, IDS_OTHERTEXT, String.Buffer);
|
|
|
|
RtlFreeAnsiString(&String);
|
|
}
|
|
|
|
|
|
//
|
|
// Basic info
|
|
//
|
|
|
|
Status = NtQueryObject(ObjectHandle, ObjectBasicInformation,
|
|
(PVOID)&BasicInfo, sizeof(BasicInfo), NULL);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
DbgPrint("GetObjectInfo: Failed to get basic info, status = 0x%lx\n\r", Status);
|
|
return(FALSE);
|
|
}
|
|
|
|
TypeInfo.TypeName.Buffer = TypeName;
|
|
TypeInfo.TypeName.MaximumLength = sizeof( TypeName );
|
|
Status = NtQueryObject(ObjectHandle, ObjectTypeInformation,
|
|
(PVOID)&TypeInfo, sizeof(TypeInfo) + TypeInfo.TypeName.MaximumLength, NULL);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
DbgPrint("GetObjectInfo: Failed to get type info, status = 0x%lx\n\r", Status);
|
|
return(FALSE);
|
|
}
|
|
|
|
CheckDlgButton(hwnd, IDCB_INHERIT, (BasicInfo.Attributes & OBJ_INHERIT) != 0);
|
|
CheckDlgButton(hwnd, IDCB_PERMANENT, (BasicInfo.Attributes & OBJ_PERMANENT) != 0);
|
|
CheckDlgButton(hwnd, IDCB_EXCLUSIVE, (BasicInfo.Attributes & OBJ_EXCLUSIVE) != 0);
|
|
|
|
SetDlgItemInt(hwnd, IDS_PAGEDCHARGE, BasicInfo.PagedPoolCharge, FALSE);
|
|
SetDlgItemInt(hwnd, IDS_NONPAGEDCHARGE, BasicInfo.NonPagedPoolCharge, FALSE);
|
|
SetDlgItemInt(hwnd, IDS_HANDLES, BasicInfo.HandleCount, FALSE);
|
|
SetDlgItemInt(hwnd, IDS_TOTALHANDLES, TypeInfo.TotalNumberOfHandles, FALSE);
|
|
SetDlgItemInt(hwnd, IDS_POINTERS, BasicInfo.PointerCount, FALSE);
|
|
SetDlgItemInt(hwnd, IDS_TOTALPOINTERS, 0, FALSE);
|
|
SetDlgItemInt(hwnd, IDS_COUNT, TypeInfo.TotalNumberOfObjects, FALSE);
|
|
|
|
RtlTimeToTimeFields(&BasicInfo.CreationTime, &TimeFields);
|
|
|
|
sprintf(Buffer, "%hd/%hd/%hd @ %02hd:%02hd:%02hd",
|
|
TimeFields.Year, TimeFields.Month, TimeFields.Day,
|
|
TimeFields.Hour, TimeFields.Minute, TimeFields.Second);
|
|
|
|
SetDlgItemText(hwnd, IDS_CREATIONTIME, Buffer);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/* Converts the type-name into an attribute value */
|
|
|
|
LONG
|
|
CalcAttributes(
|
|
PUNICODE_STRING Type
|
|
)
|
|
{
|
|
UNICODE_STRING TypeName;
|
|
|
|
RtlInitUnicodeString(&TypeName, DIRECTORYTYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_DIR;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, SYMLINKTYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_SYMLINK;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, ADAPTERTYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_ADAPTER;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, CONTROLLERTYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_CONTROLLER;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, DEVICETYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_DEVICE;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, DRIVERTYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_DRIVER;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, EVENTTYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_EVENT;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, EVENTPAIRTYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_EVENTPAIR;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, FILETYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_FILE;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, MUTANTTYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_MUTANT;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, PORTTYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_PORT;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, PROFILETYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_PROFILE;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, SECTIONTYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_SECTION;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, SEMAPHORETYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_SEMAPHORE;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, TIMERTYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_TIMER;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, TYPETYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_TYPE;
|
|
}
|
|
RtlInitUnicodeString(&TypeName, PROCESSTYPE);
|
|
if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
|
|
return ATTR_PROCESS;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* */
|
|
/* StripObjectSpec() - */
|
|
/* */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* Remove the filespec portion from a path (including the backslash). */
|
|
|
|
VOID
|
|
StripObjectSpec(
|
|
LPSTR lpszPath
|
|
)
|
|
{
|
|
LPSTR p;
|
|
|
|
p = lpszPath + lstrlen(lpszPath);
|
|
while ((*p != '\\') && (p != lpszPath))
|
|
p = AnsiPrev(lpszPath, p);
|
|
|
|
/* Don't strip backslash from root directory entry. */
|
|
if ((p == lpszPath) && (*p == '\\')) {
|
|
p++;
|
|
}
|
|
|
|
*p = '\000';
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* */
|
|
/* StripObjectPath() - */
|
|
/* */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* Extract only the filespec portion from a path. */
|
|
|
|
VOID
|
|
StripObjectPath(
|
|
LPSTR lpszPath
|
|
)
|
|
{
|
|
LPSTR p;
|
|
|
|
p = lpszPath + lstrlen(lpszPath);
|
|
while ((*p != '\\') && (p != lpszPath))
|
|
p = AnsiPrev(lpszPath, p);
|
|
|
|
if (*p == '\\')
|
|
p++;
|
|
|
|
if (p != lpszPath)
|
|
lstrcpy(lpszPath, p);
|
|
}
|