// // LPC.H Local Remote Procedure Call // // History: // 2/27/94 JosephJ Created. // //#define NEW_LPC #ifdef NEW_LPC enum { eSRVR_UNREG=0, eSRVR_IDLE, eSRVR_BUSY } SERVER_STATE; enum { eCALL_NONE=0, eCALL_REQUESTED, eCALL_PROCESSING, eCALL_ABANDONED, eCALL_DONE, eCALL_DONE_ACK } CALL_STATE; #define dwSIG_SHARED 0x567D56DBL #define dwSIG_SERVER 0x50704B2BL #define dwSIG_CLIENT 0xBF9B1A63L typedef struct { DWORD dwSig; // Must be dwSIG_SHARED above DWORD dwClientIDs; // Bitmap of currently bound client IDs; DWORD dwSrvrID; // ID of current server. DWORD dwSrvrState; // SERVER_STATE enum DWORD dwCallState; // CALL_STATE enum DWORD dwCallClientID; // ID of client that placed current call. DWORD dwDataSize; // Size of following data BYTE rgbData[]; } SHARED_DATA, FAR * LPSHARED_DATA; #endif // NEW_LPC typedef struct { // Service name char rgchService[MAX_PATHNAME_SIZE+1]; // Shared Memory HANDLE hMap; // hMap of shared data. HANDLE hMtx; // Controls access to the shared data. // Created by anyone (thread that // created it is responsible for initializing the // shared memory it guards). // Only the server can grab it for extended periods // of time -- precisely when it is processing a call. BOOL fGrabbed; // True if mutex grabbed by this process. // Events; HANDLE hevSrvrFree;// Used to signal to clients that the server is idle. // AUTO reset, created non-signalled by anyone. HANDLE hevCallAvail;// Used to signal to the server that a call is avilable // Manual reset. Created non-signalled by anyone. HANDLE hevCallDone; // If Server: event of client that placed current // call. Used to signal to the client that it's // call is done. It is also used determine if the // client is still around by trying to open this // named event. // If Client: it's event, signalled by server. Created // when calling ClientBind. // Manual reset. ONE per client. Created nonsignalled // by client when doing a ClientBind. HANDLE hevCallDoneAck; // Used to signal to the server that the call-done // has been picked up by the client. // Manual reset. Created non-signalled by anyone. #ifdef NEW_LPC LPSHARED_DATA lpSharedData; // Pointer to shared data. DWORD dwSrvrID; // Server: My ID; Client: Server I last dealt with. DWORD dwClientID; // Server: Client I last dealt with. Server: My ID. #else // !NEW_LPC DWORD dwSharedDataSize; LPVOID lpvSharedData; // Events HANDLE hevSrvcReg; enum {eSS_UNDEF=0, eSS_REG, eSS_UNREG} eState; #endif // !NEW_LPC } SHARED_STATE, FAR * LPSHARED_STATE; typedef struct { #ifdef NEW_LPC DWORD dwSig; // MUST be dwSIG_SERVER above. #else // !NEW_LPC DWORD dwInstanceID; enum {eS_UNINIT=0, eS_INIT} eState; #endif // !NEW_LPC HANDLE hDummyEvent; SHARED_STATE SState; } SERVER_LOCAL_STATE, FAR * LPSERVER_LOCAL_STATE; typedef struct { #ifdef NEW_LPC DWORD dwSig; // MUST be dwSIG_CLIENT above. #else NEW_LPC DWORD dwInstanceID; DWORD dwServerInstanceID; #endif //!NEW_LPC SHARED_STATE SState; } CLIENT_LOCAL_STATE, FAR * LPCLIENT_LOCAL_STATE; typedef void (FAR *LPFNCALLHANDLER)(DWORD dwID, DWORD dwDataSize, LPBYTE lpbData); // Server call handling function. BOOL ServerRegister(LPSTR lpszService, LPSERVER_LOCAL_STATE); // Registers a server. Only one server can be registered for // a particular service name. // Initializes server_local_state. Returns TRUE on success. BOOL ServerUnRegister(LPSERVER_LOCAL_STATE); // Unregisters the service. Invalidates data in server_local_state. // Returns true on success. #ifdef NEW_LPC BOOL ClientCheckIfServerPresent(LPSTR lpszService); // Returns true iff a server for this service exists. May be called // at any time (even before ClientBind). It may be used for the client // to determine whether to launch the server. // This is not foolproof: for example, the server may exit just after // this call returns true, or the server may exist, but be hung. #endif // NEW_LPC BOOL ClientBind(LPSTR lpszService, DWORD dwTimeout, LPCLIENT_LOCAL_STATE); // Binds to the specified service, initializes client_local_state. // Returns TRUE on success. BOOL ClientUnBind(LPCLIENT_LOCAL_STATE lpClient); // Binds from the specified service. // Returns TRUE on success. BOOL ClientMakeCall(LPCLIENT_LOCAL_STATE, DWORD dwTimeout, DWORD dwID, DWORD dwSize, LPBYTE lpbData); // Returns only when complete... // Copies all data to shared mem, and copies back when // done. Never times out. Returns FALSE if there was // some problem with the rpc system, or if bad parameters. BOOL ClientMakeCallEx(LPSTR lpszService, DWORD dwID, DWORD dwSize, LPBYTE lpbData); // Immediate binding version of ClientMakeCall. // Returns only when complete... // Copies all data to shared mem, and copies back when // done. Never times out. Returns FALSE if there was // some problem with the rpc system, or if bad parameters. BOOL ServerListen(LPSERVER_LOCAL_STATE, LPFNCALLHANDLER, HANDLE hev2, DWORD dwTimeout); // Blocks until call received, then // calls lpfnCallHandler(id,size,data) once and returns when call is // handled. Returns FALSE iff listen timed out. The intension here // is for the server to repeatedly call ServerListen. Each time // either one call is handled or the function times out. // Following functions are for calling only by LibEntry, on process // Creation and termination.... When the LPC functionality is moved // into a separate DLL, this will migrate into an internal header file. void LPCInternalInit(void); void LPCInternalDeInit(void);