Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencreate.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/lpc/create.c 00005 * PURPOSE: Local Procedure Call: Port/Queue/Message Creation 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* PRIVATE FUNCTIONS *********************************************************/ 00016 00017 NTSTATUS 00018 NTAPI 00019 LpcpInitializePortQueue(IN PLPCP_PORT_OBJECT Port) 00020 { 00021 PLPCP_NONPAGED_PORT_QUEUE MessageQueue; 00022 PAGED_CODE(); 00023 00024 /* Allocate the queue */ 00025 MessageQueue = ExAllocatePoolWithTag(NonPagedPool, 00026 sizeof(LPCP_NONPAGED_PORT_QUEUE), 00027 'troP'); 00028 if (!MessageQueue) return STATUS_INSUFFICIENT_RESOURCES; 00029 00030 /* Set it up */ 00031 KeInitializeSemaphore(&MessageQueue->Semaphore, 0, MAXLONG); 00032 MessageQueue->BackPointer = Port; 00033 00034 /* And link it with the Paged Pool part */ 00035 Port->MsgQueue.Semaphore = &MessageQueue->Semaphore; 00036 InitializeListHead(&Port->MsgQueue.ReceiveHead); 00037 return STATUS_SUCCESS; 00038 } 00039 00040 NTSTATUS 00041 NTAPI 00042 LpcpCreatePort(OUT PHANDLE PortHandle, 00043 IN POBJECT_ATTRIBUTES ObjectAttributes, 00044 IN ULONG MaxConnectionInfoLength, 00045 IN ULONG MaxMessageLength, 00046 IN ULONG MaxPoolUsage, 00047 IN BOOLEAN Waitable) 00048 { 00049 KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); 00050 NTSTATUS Status; 00051 PLPCP_PORT_OBJECT Port; 00052 PAGED_CODE(); 00053 LPCTRACE(LPC_CREATE_DEBUG, "Name: %wZ\n", ObjectAttributes->ObjectName); 00054 00055 /* Create the Object */ 00056 Status = ObCreateObject(PreviousMode, 00057 LpcPortObjectType, 00058 ObjectAttributes, 00059 PreviousMode, 00060 NULL, 00061 sizeof(LPCP_PORT_OBJECT), 00062 0, 00063 0, 00064 (PVOID*)&Port); 00065 if (!NT_SUCCESS(Status)) return Status; 00066 00067 /* Set up the Object */ 00068 RtlZeroMemory(Port, sizeof(LPCP_PORT_OBJECT)); 00069 Port->ConnectionPort = Port; 00070 Port->Creator = PsGetCurrentThread()->Cid; 00071 InitializeListHead(&Port->LpcDataInfoChainHead); 00072 InitializeListHead(&Port->LpcReplyChainHead); 00073 00074 /* Check if we don't have a name */ 00075 if (!ObjectAttributes->ObjectName->Buffer) 00076 { 00077 /* Set up for an unconnected port */ 00078 Port->Flags = LPCP_UNCONNECTED_PORT; 00079 Port->ConnectedPort = Port; 00080 Port->ServerProcess = NULL; 00081 } 00082 else 00083 { 00084 /* Set up for a named connection port */ 00085 Port->Flags = LPCP_CONNECTION_PORT; 00086 Port->ServerProcess = PsGetCurrentProcess(); 00087 00088 /* Don't let the process die on us */ 00089 ObReferenceObject(Port->ServerProcess); 00090 } 00091 00092 /* Check if this is a waitable port */ 00093 if (Waitable) Port->Flags |= LPCP_WAITABLE_PORT; 00094 00095 /* Setup the port queue */ 00096 Status = LpcpInitializePortQueue(Port); 00097 if (!NT_SUCCESS(Status)) 00098 { 00099 /* Fail */ 00100 ObDereferenceObject(Port); 00101 return Status; 00102 } 00103 00104 /* Check if this is a waitable port */ 00105 if (Port->Flags & LPCP_WAITABLE_PORT) 00106 { 00107 /* Setup the wait event */ 00108 KeInitializeEvent(&Port->WaitEvent, NotificationEvent, FALSE); 00109 } 00110 00111 /* Set the maximum message size allowed */ 00112 Port->MaxMessageLength = LpcpMaxMessageSize - 00113 FIELD_OFFSET(LPCP_MESSAGE, Request); 00114 00115 /* Now subtract the actual message structures and get the data size */ 00116 Port->MaxConnectionInfoLength = Port->MaxMessageLength - 00117 sizeof(PORT_MESSAGE) - 00118 sizeof(LPCP_CONNECTION_MESSAGE); 00119 00120 /* Validate the sizes */ 00121 if (Port->MaxConnectionInfoLength < MaxConnectionInfoLength) 00122 { 00123 /* Not enough space for your request */ 00124 ObDereferenceObject(Port); 00125 return STATUS_INVALID_PARAMETER_3; 00126 } 00127 else if (Port->MaxMessageLength < MaxMessageLength) 00128 { 00129 /* Not enough space for your request */ 00130 ObDereferenceObject(Port); 00131 return STATUS_INVALID_PARAMETER_4; 00132 } 00133 00134 /* Now set the custom setting */ 00135 Port->MaxMessageLength = MaxMessageLength; 00136 00137 /* Insert it now */ 00138 Status = ObInsertObject((PVOID)Port, 00139 NULL, 00140 PORT_ALL_ACCESS, 00141 0, 00142 NULL, 00143 PortHandle); 00144 00145 /* Return success or the error */ 00146 LPCTRACE(LPC_CREATE_DEBUG, "Port: %p. Handle: %lx\n", Port, *PortHandle); 00147 return Status; 00148 } 00149 00150 /* PUBLIC FUNCTIONS **********************************************************/ 00151 00152 /* 00153 * @implemented 00154 */ 00155 NTSTATUS 00156 NTAPI 00157 NtCreatePort(OUT PHANDLE PortHandle, 00158 IN POBJECT_ATTRIBUTES ObjectAttributes, 00159 IN ULONG MaxConnectInfoLength, 00160 IN ULONG MaxDataLength, 00161 IN ULONG MaxPoolUsage) 00162 { 00163 PAGED_CODE(); 00164 00165 /* Call the internal API */ 00166 return LpcpCreatePort(PortHandle, 00167 ObjectAttributes, 00168 MaxConnectInfoLength, 00169 MaxDataLength, 00170 MaxPoolUsage, 00171 FALSE); 00172 } 00173 00174 /* 00175 * @implemented 00176 */ 00177 NTSTATUS 00178 NTAPI 00179 NtCreateWaitablePort(OUT PHANDLE PortHandle, 00180 IN POBJECT_ATTRIBUTES ObjectAttributes, 00181 IN ULONG MaxConnectInfoLength, 00182 IN ULONG MaxDataLength, 00183 IN ULONG MaxPoolUsage) 00184 { 00185 PAGED_CODE(); 00186 00187 /* Call the internal API */ 00188 return LpcpCreatePort(PortHandle, 00189 ObjectAttributes, 00190 MaxConnectInfoLength, 00191 MaxDataLength, 00192 MaxPoolUsage, 00193 TRUE); 00194 } 00195 00196 /* EOF */ Generated on Sun May 27 2012 04:16:59 for ReactOS by
1.7.6.1
|