[STORPORT] Fix x64 build
[reactos.git] / ntoskrnl / lpc / create.c
index b4fb885..aaa5ed7 100644 (file)
@@ -19,11 +19,12 @@ NTAPI
 LpcpInitializePortQueue(IN PLPCP_PORT_OBJECT Port)
 {
     PLPCP_NONPAGED_PORT_QUEUE MessageQueue;
+
     PAGED_CODE();
 
     /* Allocate the queue */
     MessageQueue = ExAllocatePoolWithTag(NonPagedPool,
-                                         sizeof(LPCP_NONPAGED_PORT_QUEUE),
+                                         sizeof(*MessageQueue),
                                          'troP');
     if (!MessageQueue) return STATUS_INSUFFICIENT_RESOURCES;
 
@@ -46,12 +47,51 @@ LpcpCreatePort(OUT PHANDLE PortHandle,
                IN ULONG MaxPoolUsage,
                IN BOOLEAN Waitable)
 {
-    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
     NTSTATUS Status;
+    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
+    UNICODE_STRING CapturedObjectName, *ObjectName;
     PLPCP_PORT_OBJECT Port;
+    HANDLE Handle;
+
     PAGED_CODE();
     LPCTRACE(LPC_CREATE_DEBUG, "Name: %wZ\n", ObjectAttributes->ObjectName);
 
+    RtlInitEmptyUnicodeString(&CapturedObjectName, NULL, 0);
+
+    /* Check if the call comes from user mode */
+    if (PreviousMode != KernelMode)
+    {
+        _SEH2_TRY
+        {
+            /* Probe the PortHandle */
+            ProbeForWriteHandle(PortHandle);
+
+            /* Probe the ObjectAttributes and its object name (not the buffer) */
+            ProbeForRead(ObjectAttributes, sizeof(*ObjectAttributes), sizeof(ULONG));
+            ObjectName = ((volatile OBJECT_ATTRIBUTES*)ObjectAttributes)->ObjectName;
+            if (ObjectName)
+            {
+                ProbeForRead(ObjectName, sizeof(*ObjectName), 1);
+                CapturedObjectName = *(volatile UNICODE_STRING*)ObjectName;
+            }
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
+        }
+        _SEH2_END;
+    }
+    else
+    {
+        if (ObjectAttributes->ObjectName)
+            CapturedObjectName = *(ObjectAttributes->ObjectName);
+    }
+
+    /* Normalize the buffer pointer in case we don't have a name */
+    if (CapturedObjectName.Length == 0)
+        CapturedObjectName.Buffer = NULL;
+
     /* Create the Object */
     Status = ObCreateObject(PreviousMode,
                             LpcPortObjectType,
@@ -72,7 +112,7 @@ LpcpCreatePort(OUT PHANDLE PortHandle,
     InitializeListHead(&Port->LpcReplyChainHead);
 
     /* Check if we don't have a name */
-    if (!ObjectAttributes->ObjectName->Buffer)
+    if (CapturedObjectName.Buffer == NULL)
     {
         /* Set up for an unconnected port */
         Port->Flags = LPCP_UNCONNECTED_PORT;
@@ -135,15 +175,30 @@ LpcpCreatePort(OUT PHANDLE PortHandle,
     Port->MaxMessageLength = MaxMessageLength;
 
     /* Insert it now */
-    Status = ObInsertObject((PVOID)Port,
+    Status = ObInsertObject(Port,
                             NULL,
                             PORT_ALL_ACCESS,
                             0,
                             NULL,
-                            PortHandle);
+                            &Handle);
+    if (NT_SUCCESS(Status))
+    {
+        _SEH2_TRY
+        {
+            /* Write back the handle, pointer was already probed */
+            *PortHandle = Handle;
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* An exception happened, close the opened handle */
+            ObCloseHandle(Handle, PreviousMode);
+            Status = _SEH2_GetExceptionCode();
+        }
+        _SEH2_END;
+    }
 
     /* Return success or the error */
-    LPCTRACE(LPC_CREATE_DEBUG, "Port: %p. Handle: %p\n", Port, *PortHandle);
+    LPCTRACE(LPC_CREATE_DEBUG, "Port: %p. Handle: %p\n", Port, Handle);
     return Status;
 }