HWINSTA APIENTRY NtUserOpenWindowStation( POBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK dwDesiredAccess) { HWINSTA hwinsta; NTSTATUS Status; Status = ObOpenObjectByName(ObjectAttributes, ExWindowStationObjectType, UserMode, NULL, dwDesiredAccess, NULL, (PVOID*)&hwinsta); if (!NT_SUCCESS(Status)) { ERR("NtUserOpenWindowStation failed\n"); SetLastNtError(Status); return 0; } TRACE("Opened window station %wZ with handle %p\n", ObjectAttributes->ObjectName, hwinsta); return hwinsta; }
NTSTATUS GetObjectByName(PUNICODE_STRING ObjName, POBJECT_TYPE ObjectType, PVOID *pObject) { PVOID Object; NTSTATUS Status; OBJECT_ATTRIBUTES ObjAttrs; HANDLE ObjectHandle; InitializeObjectAttributes(&ObjAttrs, ObjName, OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, NULL, NULL); Status = ObOpenObjectByName(&ObjAttrs, ObjectType, KernelMode, NULL, 0, NULL, &ObjectHandle); if (!NT_SUCCESS(Status)) { KLErr("Can't open object by name Status 0x%x", Status); return Status; } Status = ObReferenceObjectByHandle(ObjectHandle, 0, ObjectType, KernelMode, &Object, NULL); if (!NT_SUCCESS(Status)) { KLErr("Can't reference object by handle %p Status 0x%x", ObjectHandle, Status); ZwClose(ObjectHandle); return Status; } ZwClose(ObjectHandle); *pObject = Object; return STATUS_SUCCESS; }
static POBJECT_TYPE GetObjectType( IN PCWSTR TypeName) { NTSTATUS Status; UNICODE_STRING Name; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE Handle; PVOID ObjectType = NULL; RtlInitUnicodeString(&Name, TypeName); InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ObOpenObjectByName(&ObjectAttributes, NULL, KernelMode, NULL, 0, NULL, &Handle); ok_eq_hex(Status, STATUS_SUCCESS); ok(Handle != NULL, "ObjectTypeHandle = NULL\n"); if (!skip(Status == STATUS_SUCCESS && Handle, "No handle\n")) { Status = ObReferenceObjectByHandle(Handle, 0, NULL, KernelMode, &ObjectType, NULL); ok_eq_hex(Status, STATUS_SUCCESS); ok(ObjectType != NULL, "ObjectType = NULL\n"); Status = ZwClose(Handle); ok_eq_hex(Status, STATUS_SUCCESS); } return ObjectType; }
NTSTATUS IopCreateFileXp2003( __out PHANDLE FileHandle, __in ACCESS_MASK DesiredAccess, __in POBJECT_ATTRIBUTES ObjectAttributes, __out PIO_STATUS_BLOCK IoStatusBlock, __in PLARGE_INTEGER AllocationSize OPTIONAL, __in ULONG FileAttributes, __in ULONG ShareAccess, __in ULONG Disposition, __in ULONG CreateOptions, __in PVOID EaBuffer OPTIONAL, __in ULONG EaLength, __in CREATE_FILE_TYPE CreateFileType, __in PVOID ExtraCreateParameters OPTIONAL, __in ULONG Options, __in ULONG InternalFlags, __in PVOID DeviceObject ) { KPROCESSOR_MODE kRrequestorMode = KernelMode; NTSTATUS nsStatus = STATUS_UNSUCCESSFUL; HANDLE hHandle = NULL; POPEN_PACKET pOpenPacket = NULL; PVOID pFileObjRetFunc = NULL; PVOID pDeviceObjRetFunc = NULL; BOOLEAN bSuccessfulIoParse = FALSE; BOOLEAN bSetObjFunc = FALSE; ULONG ulFileOrDevice = 0; LARGE_INTEGER liInitialAllocationSize = {0x00}; do { kRrequestorMode = KernelMode; if (Options & IO_NO_PARAMETER_CHECKING) { kRrequestorMode = KernelMode; } if (AllocationSize != NULL) { liInitialAllocationSize.QuadPart = AllocationSize->QuadPart; } else { liInitialAllocationSize.QuadPart = 0; } BDKitAllocateNonpagePool(pOpenPacket, sizeof(*pOpenPacket)); BDKit_If_Not_Break(pOpenPacket != NULL); if (EaBuffer != NULL && EaLength != 0) { ULONG errorOffset = 0; BDKitAllocatePagePool(pOpenPacket->EaBuffer, EaLength); BDKit_If_Not_Break(pOpenPacket->EaBuffer != NULL); pOpenPacket->EaLength = EaLength; __try { RtlCopyMemory(pOpenPacket->EaBuffer, EaBuffer, EaLength); } __except(EXCEPTION_EXECUTE_HANDLER) { nsStatus= STATUS_INVALID_PARAMETER; BDKit_If_Not_Break(FALSE); } nsStatus = IoCheckEaBufferValidity((PFILE_FULL_EA_INFORMATION)pOpenPacket->EaBuffer, EaLength, &errorOffset); if (!NT_SUCCESS(nsStatus)) { IoStatusBlock->Status = nsStatus; IoStatusBlock->Information = errorOffset; BDKit_If_Not_Break(FALSE); } } else { pOpenPacket->EaBuffer = (PVOID)NULL; pOpenPacket->EaLength = 0L; } pOpenPacket->Type = IO_TYPE_OPEN_PACKET; pOpenPacket->Size = sizeof(*pOpenPacket); pOpenPacket->ParseCheck = 0L; pOpenPacket->AllocationSize = liInitialAllocationSize; pOpenPacket->CreateOptions = CreateOptions; pOpenPacket->FileAttributes = (USHORT) FileAttributes; pOpenPacket->ShareAccess = (USHORT) ShareAccess; pOpenPacket->Disposition = Disposition; pOpenPacket->Override = FALSE; pOpenPacket->QueryOnly = FALSE; pOpenPacket->DeleteOnly = FALSE; pOpenPacket->Options = Options; pOpenPacket->RelatedFileObject = (PFILE_OBJECT)NULL; pOpenPacket->CreateFileType = CreateFileType; pOpenPacket->ExtraCreateParameters = ExtraCreateParameters; pOpenPacket->InternalFlags = InternalFlags; pOpenPacket->TraversedMountPoint = FALSE; pOpenPacket->TopDeviceObjectHint = (PDEVICE_OBJECT)DeviceObject; pOpenPacket->FinalStatus = STATUS_SUCCESS; pOpenPacket->FileObject = (PFILE_OBJECT)NULL; { //恢复Object CallBack bSetObjFunc = KeFileSetObjectFunction(*IoFileObjectType, g_emObjFileFunction, emObjParseOper, &pFileObjRetFunc, TRUE); if (bSetObjFunc && pFileObjRetFunc != NULL) { ulFileOrDevice |= RESET_FILE_OBJECT_CALLBACK; } bSetObjFunc = KeFileSetObjectFunction(g_pDevObjectTypePointer, g_emObjDeviceFunction, emObjParseOper, &pDeviceObjRetFunc, TRUE); if (bSetObjFunc && pDeviceObjRetFunc != NULL) { ulFileOrDevice |= RESET_DEVICE_OBJECT_CALLBACK; } nsStatus = ObOpenObjectByName( ObjectAttributes, NULL, kRrequestorMode, NULL, DesiredAccess, pOpenPacket, &hHandle ); //恢复设置 if (ulFileOrDevice & RESET_FILE_OBJECT_CALLBACK) { KeFileSetObjectFunction(*IoFileObjectType, g_emObjFileFunction, emObjParseOper, &pFileObjRetFunc, FALSE); ulFileOrDevice &= ~RESET_FILE_OBJECT_CALLBACK; } if (ulFileOrDevice & RESET_DEVICE_OBJECT_CALLBACK) { KeFileSetObjectFunction(g_pDevObjectTypePointer, g_emObjDeviceFunction, emObjParseOper, &pDeviceObjRetFunc, FALSE); ulFileOrDevice &= ~RESET_DEVICE_OBJECT_CALLBACK; } } BDKitFreePool(pOpenPacket->EaBuffer); pOpenPacket->EaLength = 0; bSuccessfulIoParse = (BOOLEAN)(pOpenPacket->ParseCheck == OPEN_PACKET_PATTERN); if ( !NT_SUCCESS(nsStatus) || bSuccessfulIoParse == FALSE ) { if (NT_SUCCESS(nsStatus)) { BDKitCloseHandle(hHandle); nsStatus = STATUS_OBJECT_TYPE_MISMATCH; } if ( !NT_SUCCESS(pOpenPacket->FinalStatus) ) { nsStatus = pOpenPacket->FinalStatus; if ( NT_WARNING(nsStatus) ) { __try { IoStatusBlock->Status = pOpenPacket->FinalStatus; IoStatusBlock->Information = pOpenPacket->Information; } __except(EXCEPTION_EXECUTE_HANDLER) { nsStatus = GetExceptionCode(); } } } else if ( pOpenPacket->FileObject != NULL && !bSuccessfulIoParse )
BOOLEAN obtest( void ) { ULONG i; HANDLE Handles[ 2 ]; NTSTATUS Status; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectTypeAName, "ObjectTypeA" ); RtlInitString( &ObjectTypeBName, "ObjectTypeB" ); RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) ); ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer ); ObjectTypeInitializer.ValidAccessMask = -1; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.MaintainHandleCount = TRUE; ObjectTypeInitializer.DumpProcedure = DumpAProc; ObjectTypeInitializer.OpenProcedure = OpenAProc; ObjectTypeInitializer.CloseProcedure = CloseAProc; ObjectTypeInitializer.DeleteProcedure = DeleteAProc; ObjectTypeInitializer.ParseProcedure = ParseAProc; ObCreateObjectType( &ObjectTypeAName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ObjectTypeA ); ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.MaintainHandleCount = FALSE; ObjectTypeInitializer.GenericMapping = MyGenericMapping; ObjectTypeInitializer.DumpProcedure = DumpBProc; ObjectTypeInitializer.OpenProcedure = NULL; ObjectTypeInitializer.CloseProcedure = NULL; ObjectTypeInitializer.DeleteProcedure = DeleteBProc; ObjectTypeInitializer.ParseProcedure = NULL; ObCreateObjectType( &ObjectTypeBName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ObjectTypeB ); ObpDumpTypes( NULL ); RtlInitString( &DirectoryName, "\\MyObjects" ); InitializeObjectAttributes( &DirectoryObjA, &DirectoryName, OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, NULL, NULL ); NtCreateDirectoryObject( &DirectoryHandle, 0, &DirectoryObjA ); NtClose( DirectoryHandle ); RtlInitString( &ObjectAName, "\\myobjects\\ObjectA" ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAName, OBJ_CASE_INSENSITIVE, NULL, NULL ); RtlInitString( &ObjectBName, "\\myobjects\\ObjectB" ); InitializeObjectAttributes( &ObjectBObjA, &ObjectBName, OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = ObCreateObject( KernelMode, ObjectTypeA, &ObjectAObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEA ), 0L, 0L, (PVOID *)&ObjectBodyA ); ObjectA = (POBJECTTYPEA)ObjectBodyA; ObjectA->TypeALength = sizeof( *ObjectA ); for (i=0; i<4; i++) { ObjectA->Stuff[i] = i+1; } KeInitializeEvent( &ObjectA->Event, NotificationEvent, TRUE ); Status = ObCreateObject( KernelMode, ObjectTypeB, &ObjectBObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEB ), 0L, 0L, (PVOID *)&ObjectBodyB ); ObjectB = (POBJECTTYPEB)ObjectBodyB; ObjectB->TypeBLength = sizeof( *ObjectB ); for (i=0; i<16; i++) { ObjectB->Stuff[i] = i+1; } KeInitializeSemaphore ( &ObjectB->Semaphore, 2L, 2L ); Status = ObInsertObject( ObjectBodyA, SYNCHRONIZE | 0x3, NULL, 1, &ObjectBodyA, &ObjectHandleA1 ); DbgPrint( "Status: %lx ObjectBodyA: %lx ObjectHandleA1: %lx\n", Status, ObjectBodyA, ObjectHandleA1 ); Status = ObInsertObject( ObjectBodyB, SYNCHRONIZE | 0x1, NULL, 1, &ObjectBodyB, &ObjectHandleB1 ); DbgPrint( "Status: %lx ObjectBodyB: %lx ObjectHandleB1: %lx\n", Status, ObjectBodyB, ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectAName, "\\MyObjects\\ObjectA" ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAName, OBJ_OPENIF, NULL, NULL ); Status = ObCreateObject( KernelMode, ObjectTypeA, &ObjectAObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEA ), 0L, 0L, (PVOID *)&ObjectBodyA1 ); Status = ObInsertObject( ObjectBodyA1, SYNCHRONIZE | 0x3, NULL, 1, &ObjectBodyA2, &ObjectHandleA2 ); DbgPrint( "Status: %lx ObjectBodyA1: %lx ObjectBodyA2: %lx ObjectHandleA2: %lx\n", Status, ObjectBodyA1, ObjectBodyA2, ObjectHandleA2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); NtClose( ObjectHandleA2 ); ObDereferenceObject( ObjectBodyA2 ); // ObInsertObject,ObjectPointerBias NtWaitForSingleObject( ObjectHandleB1, TRUE, NULL ); Handles[ 0 ] = ObjectHandleA1; Handles[ 1 ] = ObjectHandleB1; NtWaitForMultipleObjects( 2, Handles, WaitAny, TRUE, NULL ); ObReferenceObjectByHandle( ObjectHandleA1, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB1, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByPointer( ObjectBodyA, 0L, ObjectTypeA, KernelMode ); ObReferenceObjectByPointer( ObjectBodyB, 0L, ObjectTypeB, KernelMode ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectAPathName, "\\MyObjects\\ObjectA" ); RtlInitString( &ObjectBPathName, "\\MyObjects\\ObjectB" ); ObReferenceObjectByName( &ObjectAPathName, OBJ_CASE_INSENSITIVE, 0L, ObjectTypeA, KernelMode, NULL, &ObjectBodyA ); ObReferenceObjectByName( &ObjectBPathName, OBJ_CASE_INSENSITIVE, 0L, ObjectTypeB, KernelMode, NULL, &ObjectBodyB ); DbgPrint( "Reference Name %s = %lx\n", ObjectAPathName.Buffer, ObjectBodyA ); DbgPrint( "Reference Name %s = %lx\n", ObjectBPathName.Buffer, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObDereferenceObject( ObjectBodyA ); // ObInsertObject,ObjectPointerBias ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByPointer ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByName ObDereferenceObject( ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAPathName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ObOpenObjectByName( &ObjectAObjA, 0L, NULL, ObjectTypeA, KernelMode, NULL, &ObjectHandleA2 ); InitializeObjectAttributes( &ObjectBObjA, &ObjectBPathName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ObOpenObjectByName( &ObjectBObjA, 0L, NULL, ObjectTypeB, KernelMode, NULL, &ObjectHandleB2 ); DbgPrint( "Open Object Name %s = %lx\n", ObjectAPathName.Buffer, ObjectHandleA2 ); DbgPrint( "Open Object Name %s = %lx\n", ObjectBPathName.Buffer, ObjectHandleB2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); NtClose( ObjectHandleA1 ); NtClose( ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByHandle( ObjectHandleA2, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB2, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA2, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB2, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObOpenObjectByPointer( ObjectBodyA, OBJ_CASE_INSENSITIVE, 0L, NULL, ObjectTypeA, KernelMode, &ObjectHandleA1 ); ObOpenObjectByPointer( ObjectBodyB, OBJ_CASE_INSENSITIVE, 0L, NULL, ObjectTypeB, KernelMode, &ObjectHandleB1 ); DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyA, ObjectHandleA1 ); DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyB, ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByHandle( ObjectHandleA1, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB1, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); NtClose( ObjectHandleA1 ); NtClose( ObjectHandleB1 ); NtClose( ObjectHandleA2 ); NtClose( ObjectHandleB2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); TestFunction = NULL; return( TRUE ); }
NTSTATUS NtQueryFullAttributesFile ( __in POBJECT_ATTRIBUTES ObjectAttributes, __out PFILE_NETWORK_OPEN_INFORMATION FileInformation ) /*++ Routine Description: This service queries the network attributes information for a specified file. Arguments: ObjectAttributes - Supplies the attributes to be used for file object (name, SECURITY_DESCRIPTOR, etc.) FileInformation - Supplies an output buffer to receive the returned file attributes information. Return Value: The status returned is the final completion status of the operation. --*/ { KPROCESSOR_MODE requestorMode; NTSTATUS status; OPEN_PACKET openPacket; DUMMY_FILE_OBJECT localFileObject; FILE_NETWORK_OPEN_INFORMATION networkInformation; HANDLE handle; PAGED_CODE(); // // Get the previous mode; i.e., the mode of the caller. // requestorMode = KeGetPreviousMode(); if (requestorMode != KernelMode) { try { // // The caller's mode is not kernel, so probe the output buffer. // ProbeForWriteSmallStructure( FileInformation, sizeof( FILE_NETWORK_OPEN_INFORMATION ), #if defined(_X86_) sizeof( LONG )); #else sizeof( LONGLONG )); #endif // defined(_X86_) } except(EXCEPTION_EXECUTE_HANDLER) { // // An exception was incurred while probing the caller's parameters. // Simply return an appropriate error status code. // return GetExceptionCode(); } } // // Build a parse open packet that tells the parse method to open the file, // query the file's full attributes, and close the file. // RtlZeroMemory( &openPacket, sizeof( OPEN_PACKET ) ); openPacket.Type = IO_TYPE_OPEN_PACKET; openPacket.Size = sizeof( OPEN_PACKET ); openPacket.ShareAccess = (USHORT) FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; openPacket.Disposition = FILE_OPEN; openPacket.CreateOptions = FILE_OPEN_REPARSE_POINT|FILE_OPEN_FOR_BACKUP_INTENT; openPacket.QueryOnly = TRUE; openPacket.FullAttributes = TRUE; openPacket.TraversedMountPoint = FALSE; openPacket.LocalFileObject = &localFileObject; if (requestorMode != KernelMode) { openPacket.NetworkInformation = &networkInformation; } else { openPacket.NetworkInformation = FileInformation; } // // Update the open count for this process. // IopUpdateOtherOperationCount(); // // Open the object by its name. Because of the special QueryOnly flag set // in the open packet, the parse routine will open the file, and then // realize that it is only performing a query. It will therefore perform // the query, and immediately close the file. // status = ObOpenObjectByName( ObjectAttributes, (POBJECT_TYPE) NULL, requestorMode, NULL, FILE_READ_ATTRIBUTES, &openPacket, &handle ); // // The operation is successful if the parse check field of the open packet // indicates that the parse routine was actually invoked, and the final // status field of the packet is set to success. // if (openPacket.ParseCheck != OPEN_PACKET_PATTERN) { if (NT_SUCCESS(status)) { ZwClose(handle); status = STATUS_OBJECT_TYPE_MISMATCH; } return status; } else { status = openPacket.FinalStatus; } if (NT_SUCCESS( status )) { if (requestorMode != KernelMode) { try { // // The query worked, so copy the returned information to the // caller's output buffer. // RtlCopyMemory( FileInformation, &networkInformation, sizeof( FILE_NETWORK_OPEN_INFORMATION ) ); } except(EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); } } } return status; }
NTSTATUS NtDeleteFile ( __in POBJECT_ATTRIBUTES ObjectAttributes ) /*++ Routine Description: This service deletes the specified file. Arguments: ObjectAttributes - Supplies the attributes to be used for file object (name, SECURITY_DESCRIPTOR, etc.) Return Value: The status returned is the final completion status of the operation. --*/ { KPROCESSOR_MODE requestorMode; NTSTATUS status; OPEN_PACKET openPacket; DUMMY_FILE_OBJECT localFileObject; HANDLE handle; PAGED_CODE(); // // Get the previous mode; i.e., the mode of the caller. // requestorMode = KeGetPreviousMode(); // // Build a parse open packet that tells the parse method to open the file // for open for delete access w/the delete bit set, and then close it. // RtlZeroMemory( &openPacket, sizeof( OPEN_PACKET ) ); openPacket.Type = IO_TYPE_OPEN_PACKET; openPacket.Size = sizeof( OPEN_PACKET ); openPacket.CreateOptions = FILE_DELETE_ON_CLOSE; openPacket.ShareAccess = (USHORT) FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; openPacket.Disposition = FILE_OPEN; openPacket.DeleteOnly = TRUE; openPacket.TraversedMountPoint = FALSE; openPacket.LocalFileObject = &localFileObject; // // Update the open count for this process. // IopUpdateOtherOperationCount(); // // Open the object by its name. Because of the special DeleteOnly flag // set in the open packet, the parse routine will open the file, and // then realize that it is only deleting the file, and will therefore // immediately dereference the file. This will cause the cleanup and // the close to be sent to the file system, thus causing the file to // be deleted. // status = ObOpenObjectByName( ObjectAttributes, (POBJECT_TYPE) NULL, requestorMode, NULL, DELETE, &openPacket, &handle ); // // The operation is successful if the parse check field of the open packet // indicates that the parse routine was actually invoked, and the final // status field of the packet is set to success. // if (openPacket.ParseCheck != OPEN_PACKET_PATTERN) { return status; } else { return openPacket.FinalStatus; } }
NTSTATUS NtOpenEvent ( OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes ) /*++ Routine Description: This function opens a handle to an event object with the specified desired access. Arguments: EventHandle - Supplies a pointer to a variable that will receive the event object handle. DesiredAccess - Supplies the desired types of access for the event object. ObjectAttributes - Supplies a pointer to an object attributes structure. Return Value: TBS --*/ { HANDLE Handle; KPROCESSOR_MODE PreviousMode; NTSTATUS Status; // // Establish an exception handler, probe the output handle address, and // attempt to open the event object. If the probe fails, then return the // exception code as the service status. Otherwise return the status value // returned by the object open routine. // try { // // Get previous processor mode and probe output handle address // if necessary. // PreviousMode = KeGetPreviousMode(); if (PreviousMode != KernelMode) { ProbeForWriteHandle(EventHandle); } // // Open handle to the event object with the specified desired access. // Status = ObOpenObjectByName(ObjectAttributes, ExEventObjectType, PreviousMode, NULL, DesiredAccess, NULL, &Handle); // // If the open was successful, then attempt to write the event object // handle value. If the write attempt fails, then do not report an // error. When the caller attempts to access the handle value, an // access violation will occur. // if (NT_SUCCESS(Status)) { try { *EventHandle = Handle; } except(ExSystemExceptionFilter()) { } } // // If an exception occurs during the probe of the output event handle, // then always handle the exception and return the exception code as the // status value. // } except(ExSystemExceptionFilter()) { return GetExceptionCode(); } // // Return service status. // return Status; }
NTSTATUS NtOpenIoCompletion ( __out PHANDLE IoCompletionHandle, __in ACCESS_MASK DesiredAccess, __in POBJECT_ATTRIBUTES ObjectAttributes ) /*++ Routine Description: This function opens a handle to an I/O completion object with the specified desired access. Arguments: IoCompletionHandle - Supplies a pointer to a variable that receives the completion object handle. DesiredAccess - Supplies the desired types of access for the I/O completion object. ObjectAttributes - Supplies a pointer to an object attributes structure. Return Value: STATUS_SUCCESS is returned if the function is success. Otherwise, an error status is returned. --*/ { HANDLE Handle; KPROCESSOR_MODE PreviousMode; NTSTATUS Status; // // Establish an exception handler, probe the output handle address, // and attempt to open an I/O completion object. If the probe fails, // then return the exception code as the service status. Otherwise, // return the status value returned by the object open routine. // try { // // Get previous processor mode and probe output handle address if // necessary. // PreviousMode = KeGetPreviousMode(); if (PreviousMode != KernelMode) { ProbeForWriteHandle(IoCompletionHandle); } // // Open handle to the completion object with the specified desired // access. // Status = ObOpenObjectByName(ObjectAttributes, IoCompletionObjectType, PreviousMode, NULL, DesiredAccess, NULL, &Handle); // // If the open was successful, then attempt to write the I/O // completion object handle value. If the write attempt fails, // then do not report an error. When the caller attempts to // access the handle value, an access violation will occur. // if (NT_SUCCESS(Status)) { try { *IoCompletionHandle = Handle; } except(ExSystemExceptionFilter()) { NOTHING; } } // // If an exception occurs during the probe of the output handle address, // then always handle the exception and return the exception code as the // status value. // } except(ExSystemExceptionFilter()) { Status = GetExceptionCode(); } // // Return service status. // return Status; }
HWINSTA APIENTRY NtUserCreateWindowStation( POBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK dwDesiredAccess, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, DWORD Unknown6) { UNICODE_STRING WindowStationName; PWINSTATION_OBJECT WindowStationObject; HWINSTA WindowStation; NTSTATUS Status; TRACE("NtUserCreateWindowStation called\n"); Status = ObOpenObjectByName(ObjectAttributes, ExWindowStationObjectType, UserMode, NULL, dwDesiredAccess, NULL, (PVOID*)&WindowStation); if (NT_SUCCESS(Status)) { TRACE("NtUserCreateWindowStation opened window station %wZ\n", ObjectAttributes->ObjectName); return (HWINSTA)WindowStation; } /* * No existing window station found, try to create new one */ /* Capture window station name */ _SEH2_TRY { ProbeForRead( ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), 1); Status = IntSafeCopyUnicodeStringTerminateNULL(&WindowStationName, ObjectAttributes->ObjectName); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status =_SEH2_GetExceptionCode(); } _SEH2_END if (! NT_SUCCESS(Status)) { ERR("Failed reading capturing window station name\n"); SetLastNtError(Status); return NULL; } /* Create the window station object */ Status = ObCreateObject(UserMode, ExWindowStationObjectType, ObjectAttributes, UserMode, NULL, sizeof(WINSTATION_OBJECT), 0, 0, (PVOID*)&WindowStationObject); if (!NT_SUCCESS(Status)) { ERR("ObCreateObject failed with %lx for window station %wZ\n", Status, &WindowStationName); ExFreePoolWithTag(WindowStationName.Buffer, TAG_STRING); SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); return 0; } /* Initialize the window station */ RtlZeroMemory(WindowStationObject, sizeof(WINSTATION_OBJECT)); InitializeListHead(&WindowStationObject->DesktopListHead); WindowStationObject->Name = WindowStationName; WindowStationObject->dwSessionId = NtCurrentPeb()->SessionId; Status = RtlCreateAtomTable(37, &WindowStationObject->AtomTable); if (!NT_SUCCESS(Status)) { ERR("RtlCreateAtomTable failed with %lx for window station %wZ\n", Status, &WindowStationName); ObDereferenceObject(WindowStationObject); SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); return 0; } Status = ObInsertObject((PVOID)WindowStationObject, NULL, dwDesiredAccess, 0, NULL, (PVOID*)&WindowStation); if (!NT_SUCCESS(Status)) { ERR("ObInsertObject failed with %lx for window station\n", Status); SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); return 0; } if (InputWindowStation == NULL) { ERR("Initializing input window station\n"); InputWindowStation = WindowStationObject; WindowStationObject->Flags &= ~WSS_NOIO; InitCursorImpl(); } else { WindowStationObject->Flags |= WSS_NOIO; } TRACE("NtUserCreateWindowStation created object %p with name %wZ handle %p\n", WindowStation, &WindowStationObject->Name, WindowStation); return WindowStation; }
NTSTATUS ExCreateCallback ( OUT PCALLBACK_OBJECT * CallbackObject, IN POBJECT_ATTRIBUTES ObjectAttributes, IN BOOLEAN Create, IN BOOLEAN AllowMultipleCallbacks ) /*++ Routine Description: This function opens a callback object with the specified callback object. If the callback object does not exist or it is a NULL then a callback object will be created if create is TRUE. If a callbackobject is created it will only support mulitiple registered callbacks if AllowMulitipleCallbacks is TRUE. Arguments: CallbackObject - Supplies a pointer to a variable that will receive the Callback object. CallbackName - Supplies a pointer to a object name that will receive the Create - Supplies a flag which indicates whether a callback object will be created or not . AllowMultipleCallbacks - Supplies a flag which indicates only support mulitiple registered callbacks. Return Value: Returns STATUS_SUCESS unless fali... --*/ { PCALLBACK_OBJECT cbObject; NTSTATUS Status; HANDLE Handle; PAGED_CODE(); #ifndef _PNP_POWER_ return STATUS_NOT_IMPLEMENTED; #else // // If named callback, open handle to it // if (ObjectAttributes->ObjectName) { Status = ObOpenObjectByName(ObjectAttributes, ExCallbackObjectType, KernelMode, NULL, 0, // DesiredAccess, NULL, &Handle); } else { Status = STATUS_UNSUCCESSFUL; } // // If not opened, check if callback should be created // if(!NT_SUCCESS(Status) && Create ) { Status = ObCreateObject(KernelMode, ExCallbackObjectType, ObjectAttributes, KernelMode, NULL, sizeof(CALLBACK_OBJECT), 0, 0, (PVOID *)&cbObject ); if(NT_SUCCESS(Status)){ // // Fill in structure signature // cbObject->Signature = 'llaC'; // // It will support multiple registered callbacks if // AllowMultipleCallbacks is TRUE. // cbObject->AllowMultipleCallbacks = AllowMultipleCallbacks; // // Initialize CallbackObject queue. // InitializeListHead( &cbObject->RegisteredCallbacks ); // // Initialize spinlock // KeInitializeSpinLock (&cbObject->Lock); // // Put the object in the root directory // Status = ObInsertObject ( cbObject, NULL, FILE_READ_DATA, 0, NULL, &Handle ); } } if(NT_SUCCESS(Status)){ // // Add one to callback object reference count // Status = ObReferenceObjectByHandle ( Handle, 0, // DesiredAccess ExCallbackObjectType, KernelMode, &cbObject, NULL ); ZwClose (Handle); } // // If SUCEESS , returns a referenced pointer to the CallbackObject. // if (NT_SUCCESS(Status)) { *CallbackObject = cbObject; } return Status; #endif }
/*++ * @name ExCreateCallback * @implemented * * Opens or creates a Callback Object. Creates only if Create is true. * Allows multiple Callback Functions to be registred only if * AllowMultipleCallbacks is true. * See: http://www.osronline.com/ddkx/kmarch/k102_967m.htm * http://www.osronline.com/article.cfm?id=24 * * @param CallbackObject * Pointer that will receive the Callback Object. * * @param CallbackName * Name of Callback * * @param Create * Determines if the object will be created if it doesn't exit * * @param AllowMultipleCallbacks * Determines if more then one registered callback function * can be attached to this Callback Object. * * @return STATUS_SUCESS if not failed. * * @remarks Must be called at IRQL = PASSIVE_LEVEL * *--*/ NTSTATUS NTAPI ExCreateCallback(OUT PCALLBACK_OBJECT *CallbackObject, IN POBJECT_ATTRIBUTES ObjectAttributes, IN BOOLEAN Create, IN BOOLEAN AllowMultipleCallbacks) { PCALLBACK_OBJECT Callback = NULL; NTSTATUS Status; HANDLE Handle = NULL; PAGED_CODE(); /* Open a handle to the callback if it exists */ if (ObjectAttributes->ObjectName) { /* Open the handle */ Status = ObOpenObjectByName(ObjectAttributes, ExCallbackObjectType, KernelMode, NULL, 0, NULL, &Handle); } else { /* Otherwise, fail */ Status = STATUS_UNSUCCESSFUL; } /* We weren't able to open it...should we create it? */ if (!(NT_SUCCESS(Status)) && (Create)) { /* Create the object */ Status = ObCreateObject(KernelMode, ExCallbackObjectType, ObjectAttributes, KernelMode, NULL, sizeof(CALLBACK_OBJECT), 0, 0, (PVOID *)&Callback); if (NT_SUCCESS(Status)) { /* Set it up */ Callback->Signature = 'llaC'; KeInitializeSpinLock(&Callback->Lock); InitializeListHead(&Callback->RegisteredCallbacks); Callback->AllowMultipleCallbacks = AllowMultipleCallbacks; /* Insert the object into the object namespace */ Status = ObInsertObject(Callback, NULL, FILE_READ_DATA, 0, NULL, &Handle); } } /* Check if we have success until here */ if (NT_SUCCESS(Status)) { /* Get a pointer to the new object from the handle we just got */ Status = ObReferenceObjectByHandle(Handle, 0, ExCallbackObjectType, KernelMode, (PVOID *)&Callback, NULL); /* Close the Handle, since we now have the pointer */ ZwClose(Handle); } /* Everything went fine, so return a pointer to the Object */ if (NT_SUCCESS(Status)) { *CallbackObject = Callback; } return Status; }