ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

create.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.