diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/unimodem/new/slot | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/unimodem/new/slot')
-rw-r--r-- | private/unimodem/new/slot/client.c | 47 | ||||
-rw-r--r-- | private/unimodem/new/slot/main.c | 514 | ||||
-rw-r--r-- | private/unimodem/new/slot/makefile | 6 | ||||
-rw-r--r-- | private/unimodem/new/slot/sec.c | 169 | ||||
-rw-r--r-- | private/unimodem/new/slot/sec.h | 24 | ||||
-rw-r--r-- | private/unimodem/new/slot/slot.c | 486 | ||||
-rw-r--r-- | private/unimodem/new/slot/slot.h | 32 | ||||
-rw-r--r-- | private/unimodem/new/slot/sources | 27 |
8 files changed, 1305 insertions, 0 deletions
diff --git a/private/unimodem/new/slot/client.c b/private/unimodem/new/slot/client.c new file mode 100644 index 000000000..c77d385ee --- /dev/null +++ b/private/unimodem/new/slot/client.c @@ -0,0 +1,47 @@ +//**************************************************************************** +// +// Module: UNIMDM +// File: SLOT.C +// +// Copyright (c) 1992-1996, Microsoft Corporation, all rights reserved +// +// Revision History +// +// +// 3/25/96 JosephJ Created +// +// +// Description: Implements the unimodem TSP notification mechanism: +// The higher level API: UnimodemNotifyTSP() +// +//**************************************************************************** +#define UNICODE +#include <windows.h> +#include "slot.h" +#include "..\..\inc\tspnotif.h" + + +BOOL WINAPI UnimodemNotifyTSP(PNOTIFICATION_FRAME pnf) +{ + BOOL fRet=FALSE; + HNOTIFICATION hN=0; + + if (pnf->dwSig!=dwNFRAME_SIG || pnf->dwSize<sizeof(*pnf) || + pnf->dwSize>MAX_NOTIFICATION_FRAME_SIZE) + { + SetLastError(ERROR_INVALID_PARAMETER); + goto end; + } + + hN = notifCreate(FALSE, SLOTNAME_UNIMODEM_NOTIFY_TSP, 0, 0); + + if (hN) + { + fRet = notifWriteMsg(hN, (LPBYTE) pnf, pnf->dwSize); + notifFree(hN); hN=0; + } + +end: + + return fRet; +} diff --git a/private/unimodem/new/slot/main.c b/private/unimodem/new/slot/main.c new file mode 100644 index 000000000..b60d85f5a --- /dev/null +++ b/private/unimodem/new/slot/main.c @@ -0,0 +1,514 @@ +//**************************************************************************** +// +// Module: UNIMDM +// File: MAIN.C +// +// Copyright (c) 1992-1996, Microsoft Corporation, all rights reserved +// +// Revision History +// +// +// 3/25/96 JosephJ Created +// +// +// Description: Test the notification support. +// Tests both the higher-level api (UnimodemNotifyTSP) +// and the lower level notifXXX apis. The latter +// are tested later on in the file, and the header file +// "slot.h" is included there, not at the start of this +// file, because the higher-level tests do not need to +// include "slot.h" +// +//**************************************************************************** +#define UNICODE +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include "..\..\inc\tspnotif.h" + +#define SLOTNAME SLOTNAME_UNIMODEM_NOTIFY_TSP + +#define TSPI_NOTIF_A 101 +#define TSPI_NOTIF_B 102 +#define TSPI_NOTIF_QUIT 999 + +#define ASSERT(_c) \ + ((_c) ? 0: DPRINTF2("Assertion failed in %s:%d\n", __FILE__, __LINE__)) +#define DPRINTF(_fmt) printf(_fmt) +#define DPRINTF1(_fmt,_arg) printf(_fmt,_arg) +#define DPRINTF2(_fmt,_arg,_arg2) printf(_fmt,_arg,_arg2) +#define DPRINTF3(_fmt,_arg,_arg2,_arg3) printf(_fmt,_arg,_arg2,_arg3) + +BOOL InitGlobals(int argc, char *argv[]); +void Server(void); +void Client_LL(void); // LowLevel -- calls notif* apis +void Client_HL(void); // HighLevel -- calls UnimodemNotifyTSP +void ProcessFrame(PNOTIFICATION_FRAME pnf); +BOOL ValidateFrame(PNOTIFICATION_FRAME pnf, DWORD dwTrueSize); +BOOL ReadFrame_UI(PNOTIFICATION_FRAME pnf, DWORD dwcbMax); +BOOL ReadFrame_Auto(PNOTIFICATION_FRAME pnf, DWORD dwcbMax); + +#define READFRAME(_pnf, _max) ReadFrame_Auto(_pnf, _max) +//#define READFRAME(_pnf, _max) ReadFrame_UI(_pnf, _max) + +//#define CLIENT() Client_LL() +#define CLIENT() Client_HL() + + +BOOL InitFrame_CplReEnum(PNOTIFICATION_FRAME pnf, DWORD dwcbMax, DWORD dwCount); +BOOL InitFrame_CplChangeDCC(PNOTIFICATION_FRAME, DWORD, DWORD); +BOOL InitFrame_Simple(PNOTIFICATION_FRAME pnf, DWORD dwcbMax, DWORD dwCount); + +#define NOTIF_CPL_REENUM 1 +#define NOTIF_CPL_CHANGE_DCC 2 +#define INIT_TYPE NOTIF_CPL_CHANGE_DCC + +#if (INIT_TYPE==NOTIF_CPL_REENUM) + #define INIT_FRAME InitFrame_CplReEnum +#elif (INIT_TYPE==NOTIF_CPL_CHANGE_DCC) + #define INIT_FRAME InitFrame_CplChangeDCC +#else + #define INIT_FRAME InitFrame_Simple +#endif + +struct +{ + BOOL fQuit; + BOOL fServer; + +} gMain; + +int __cdecl main(int argc, char *argv[]) +{ + // init globals + if (!InitGlobals(argc, argv)) goto end; + + if (gMain.fServer) Server(); + else CLIENT(); + +end: + return 0; +} + +BOOL InitGlobals(int argc, char *argv[]) +{ + BOOL fRet=FALSE; + char *pc; + + if (argc!=2) goto end; + + pc=argv[1]; + if (*pc!='-' && *pc!='/') goto end; + *pc++; + switch(*pc++) + { + case 's': + gMain.fServer=TRUE; + break; + case 'c': + break; + default: + goto end; + } + + DPRINTF1("Ha!%d\n", gMain.fServer); + fRet=TRUE; + +end: + return fRet; +} + + +void ProcessFrame(PNOTIFICATION_FRAME pnf) +{ + if (pnf->dwSig!=dwNFRAME_SIG) + { + ASSERT(FALSE); + return; + } + + switch(pnf->dwType) + { + case TSPI_NOTIF_A: + DPRINTF("Got NOTIF_A\n"); + break; + case TSPI_NOTIF_B: + DPRINTF("Got NOTIF_B\n"); + break; + case TSPI_NOTIF_QUIT: + DPRINTF("Got NOTIF_QUIT, Quitting...\n"); + gMain.fQuit=TRUE; + break; + default: + DPRINTF1("Got unknown notif type 0x%lu. Quitting\n", pnf->dwType); + gMain.fQuit=TRUE; + break; + } +} + + +void Client_HL(void) +{ + struct { + DWORD dw0; + DWORD dw1; + BYTE rgb[256]; + } EmptyFr; + PNOTIFICATION_FRAME pnf = (PNOTIFICATION_FRAME) &EmptyFr; + DWORD dwcbMax=sizeof(EmptyFr); + DWORD dwcbServerMax=0; + + // Get input from user, submit request + pnf->dwSig=pnf->dwSize=0; + while(READFRAME(pnf, dwcbMax)) + { + ASSERT(pnf->dwSig==dwNFRAME_SIG); + if (!UnimodemNotifyTSP(pnf)) + { + DPRINTF1("UnimodemNotifyTSP(-) failed. GetLastError=0x%lx. Exiting.\n", + (unsigned long) GetLastError()); + // break; + } + pnf->dwSig=pnf->dwSize=0; + } + + return; +} + +BOOL ReadFrame_UI(PNOTIFICATION_FRAME pnf, DWORD dwcbMax) +{ + BOOL fRet=FALSE; + char rgchTmp[128]; + DWORD dwType=0; + BOOL fInputError=FALSE; + + if (dwcbMax<sizeof(*pnf)) + { + DPRINTF1("ReadFrame: input frame too small (%lu)\n", + dwcbMax); + goto end; + } + + fInputError=TRUE; + + if (scanf("%s", rgchTmp)==1) + { + if (lstrlenA(rgchTmp)==1) + { + fInputError=FALSE; + switch(*rgchTmp) + { + case 'a': + DPRINTF("sending NOTIF_A\n"); + dwType = TSPI_NOTIF_A; + break; + case 'b': + DPRINTF("sending NOTIF_B\n"); + dwType = TSPI_NOTIF_B; + break; + case 'q': + DPRINTF("sending NOTIF_QUIT\n"); + dwType = TSPI_NOTIF_QUIT; + break; + case 'x': + DPRINTF("Exiting\n"); + break; + default: + fInputError=TRUE; + break; + } + } + } + + if (dwType) + { + pnf->dwSig=dwNFRAME_SIG; + pnf->dwSize=sizeof(*pnf); + pnf->dwType=dwType; + fRet=TRUE; + } + + if (fInputError) + { + DPRINTF("Bad/no input. Quitting...\n"); + } + +end: + return fRet; +} + +BOOL ReadFrame_Auto(PNOTIFICATION_FRAME pnf, DWORD dwcbMax) +{ + static dwCount=0; + DWORD dwSleepAmount; + BOOL fRet=FALSE; + + if (!dwCount++) + { + srand((ULONG) GetTickCount()); + } + +# define MAXSLEEP 10000 + dwSleepAmount = ((DWORD) rand()) % MAXSLEEP; + + Sleep(dwSleepAmount); + + // Quit after 100 -- currently disabled. + //if (dwCount>100) goto end; + + fRet = INIT_FRAME(pnf, dwcbMax, dwCount); + +// end: + return fRet; +} + +BOOL ValidateFrame(PNOTIFICATION_FRAME pnf, DWORD dwTrueSize) +{ + return (pnf && pnf->dwSig==dwNFRAME_SIG && pnf->dwSize>=sizeof(*pnf) && + pnf->dwSize==dwTrueSize && + pnf->dwSize<=MAX_NOTIFICATION_FRAME_SIZE); +} + +// ----------------------------- TEST INTERNAL STUFF -------------------- +#include "slot.h" +void ProcessNotification(HNOTIFICATION hN); + +// Server Thread +void Server(void) +{ + HNOTIFICATION hN=0; + DWORD dwLastErr=0; + HANDLE hObj=NULL; + + // Create slot + hN = notifCreate(TRUE, SLOTNAME, MAX_NOTIFICATION_FRAME_SIZE, 100); + if (!hN) + { + DPRINTF3("notifServerCreate(\"%s\", %lu) failed. GetLastError=0x%lx.\n", + (LPCSTR) SLOTNAME, + (unsigned long) MAX_NOTIFICATION_FRAME_SIZE, + (unsigned long) GetLastError()); + goto end; + } + if (!(hObj=notifGetObj(hN))) + { + DPRINTF("notifGetObj failed\n"); + goto end; + } + + // Wait and process messages + while(!gMain.fQuit) + { + UINT u=WaitForSingleObject(hObj, 5000); + if (u==WAIT_OBJECT_0) + { + ProcessNotification(hN); + //Sleep(1000); + } + } + +end: + if (hN) + { + notifFree(hN); hN=0; + } + ; +} + + + +void ProcessNotification(HNOTIFICATION hN) +{ + BOOL fRet; + struct { + DWORD dw0; + DWORD dw1; + BYTE rgb[256]; + } EmptyFr; + DWORD dwcbMax=sizeof(EmptyFr); + DWORD dwcbRead=0; + + PNOTIFICATION_FRAME pnf = (PNOTIFICATION_FRAME) &EmptyFr; + + pnf->dwSig=pnf->dwSize=0; + + fRet=notifReadMsg(hN, (LPBYTE) pnf, dwcbMax, &dwcbRead); + if (!fRet) + { + DPRINTF1("notifReadFrame(...) failed. GetLastError=0x%lx.\n", + (unsigned long) GetLastError()); + goto end; + } + + // Verify validity of msg... + if (!ValidateFrame(pnf, dwcbRead)) + { + DPRINTF("Invalid frame\n"); + goto end; + } + ASSERT(pnf->dwSig==dwNFRAME_SIG); + ASSERT(pnf->dwSize<=dwcbMax); + ASSERT(pnf->dwSize<=MAX_NOTIFICATION_FRAME_SIZE); + + ProcessFrame(pnf); + +end: + return; +} + +void Client_LL(void) +{ + HNOTIFICATION hN=0; + DWORD dwLastErr=0; + struct { + DWORD dw0; + DWORD dw1; + BYTE rgb[256]; + } EmptyFr; + PNOTIFICATION_FRAME pnf = (PNOTIFICATION_FRAME) &EmptyFr; + DWORD dwcbMax=sizeof(EmptyFr); + DWORD dwcbServerMax=0; + + // Open slot + hN = notifCreate(FALSE, SLOTNAME, 0, 0); + if (!hN) + { + DPRINTF2("notifClientOpen(\"%s\", -) failed. GetLastError=0x%lx.\n", + (LPCSTR) SLOTNAME, + (unsigned long) GetLastError()); + goto end; + } + dwcbServerMax=notifGetMaxSize(hN); + + if (dwcbServerMax<dwcbMax) + { + DPRINTF2("Warning -- server max size = %lu; Our max=%lu\n", + dwcbServerMax, + dwcbMax); + } + + // Get input from user, submit request + pnf->dwSig=pnf->dwSize=0; + while(READFRAME(pnf, dwcbMax)) + { + ASSERT(pnf->dwSig==dwNFRAME_SIG); + if (!notifWriteMsg(hN, (LPBYTE)pnf, pnf->dwSize)) + { + DPRINTF1("notifWriteFrame(-) failed. GetLastError=0x%lx. Exiting.\n", + (unsigned long) GetLastError()); + break; + } + pnf->dwSig=pnf->dwSize=0; + } + +end: + if (hN) + { + notifFree(hN); hN=0; + } +} + +BOOL InitFrame_Simple(PNOTIFICATION_FRAME pnf, DWORD dwcbMax, DWORD dwCount) +{ + BOOL fRet=FALSE; + DWORD dwType=0; + DWORD dwFlags=0; + + if (dwcbMax<sizeof(*pnf)) + { + DPRINTF1("ReadFrame: input frame too small (%lu)\n", + dwcbMax); + goto end; + } + + if (dwCount&0x1) + { + DPRINTF("sending NOTIF_A\n"); + dwType = TSPI_NOTIF_A; + } + else + { + DPRINTF("sending NOTIF_B\n"); + dwType = TSPI_NOTIF_B; + } + + pnf->dwSig=dwNFRAME_SIG; + pnf->dwSize=sizeof(*pnf); + pnf->dwType=dwType; + pnf->dwFlags=dwFlags; + fRet=TRUE; + +end: + return fRet; +} + +BOOL InitFrame_CplReEnum(PNOTIFICATION_FRAME pnf, DWORD dwcbMax, DWORD dwCount) +{ + BOOL fRet=FALSE; + DWORD dwType=0; + DWORD dwFlags=0; + + if (dwcbMax<sizeof(*pnf)) + { + DPRINTF1("ReadFrame: input frame too small (%lu)\n", + dwcbMax); + goto end; + } + + dwType = TSPNOTIF_TYPE_CPL; + dwFlags = fTSPNOTIF_FLAG_CPL_REENUM; + + pnf->dwSig=dwNFRAME_SIG; + pnf->dwSize=sizeof(*pnf); + pnf->dwType=dwType; + pnf->dwFlags=dwFlags; + fRet=TRUE; + +end: + return fRet; +} + +BOOL InitFrame_CplChangeDCC +( + PNOTIFICATION_FRAME pnf, + DWORD dwcbMax, + DWORD dwCount +) +{ + BOOL fRet=FALSE; + DWORD dwType=0; + DWORD dwFlags=0; + LPCTSTR rglpctszNames[3] = + { + TEXT("Zoom Fax Modem V.34X Model 470"), + TEXT("Zoom Fax Modem V.34X Model 470 #2"), + TEXT("blah") + }; + LPCTSTR lpctszFriendlyName = rglpctszNames[dwCount%3]; + UINT u = lstrlen(lpctszFriendlyName); + + if (dwcbMax< (sizeof(*pnf)+(u+1)*sizeof(TCHAR))) + { + DPRINTF1("ReadFrame: input frame too small (%lu)\n", + dwcbMax); + goto end; + } + + pnf->dwSig = dwNFRAME_SIG; + pnf->dwSize = dwcbMax; + pnf->dwType = TSPNOTIF_TYPE_CPL; + pnf->dwFlags = fTSPNOTIF_FLAG_CPL_DEFAULT_COMMCONFIG_CHANGE; + + #ifdef UNICODE + pnf->dwFlags |= fTSPNOTIF_FLAG_UNICODE; + #endif // UNICODE + + lstrcpy((TCHAR *)pnf->rgb, lpctszFriendlyName); + + printf("Sending ChangeDCC[%s]\n", lpctszFriendlyName); + + fRet=TRUE; + +end: + return fRet; +} diff --git a/private/unimodem/new/slot/makefile b/private/unimodem/new/slot/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/unimodem/new/slot/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/unimodem/new/slot/sec.c b/private/unimodem/new/slot/sec.c new file mode 100644 index 000000000..786e2b5ed --- /dev/null +++ b/private/unimodem/new/slot/sec.c @@ -0,0 +1,169 @@ +//**************************************************************************** +// +// Module: UNIMDM +// File: SEC.C +// +// Copyright (c) 1992-1996, Microsoft Corporation, all rights reserved +// +// Revision History +// +// +// 3/27/96 JosephJ Created +// +// +// Description: Security-related helper functions +// +//**************************************************************************** +#define UNICODE +#include <windows.h> +#include <stdio.h> +#include "sec.h" + +#define DPRINTF2(_format, _a1, _a2) printf(_format, _a1, _a2) + +#define ASSERT(_c) \ + ((_c) ? 0: DPRINTF2("Assertion failed in %s:%d\n", __FILE__, __LINE__)) + +//**************************************************************************** +// Description: This procedure will allocate and initialize a security +// descriptor with the specificed attributes. +// +// Returns: pointer to an allocated and initialized security descriptor. +// If NULL, GetLastError() will return the appropriate error code. +// +// History: +// 3/27/96 JosephJ Created +//****************************************************************************/ +// +PSECURITY_DESCRIPTOR AllocateSecurityDescriptor ( + PSID_IDENTIFIER_AUTHORITY pSIA, + DWORD dwRID, + DWORD dwRights, + PSID pSidOwner, + PSID pSidGroup + ) +{ + PSID pObjSid = NULL; + PACL pDacl = NULL; + PSECURITY_DESCRIPTOR pSD = NULL; + + pSD = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH+256); + + if (!pSD) goto end_fail; + + // Set up the SID for the admins that will be allowed to have + // access. This SID will have 1 sub-authority + if (!AllocateAndInitializeSid( + pSIA, + 1, + dwRID, 0, 0, 0, 0, 0, 0, 0, + &pObjSid + )) + { + goto end_fail; + } + + // Set up the DACL that will allow all processes with the above SID + // access specified in dwRights. It should be large enough to hold all ACEs. + // + { + DWORD cbDaclSize = sizeof(ACCESS_ALLOWED_ACE) + + GetLengthSid(pObjSid) + + sizeof(ACL); + + pDacl = (PACL)LocalAlloc( LPTR, cbDaclSize ); + if (!pDacl) + { + goto end_fail; + } + + if ( !InitializeAcl( pDacl, cbDaclSize, ACL_REVISION2 ) ) + { + goto end_fail; + } + } + + // Add the ACE to the DACL + // + if ( !AddAccessAllowedAce( pDacl, ACL_REVISION2, dwRights, pObjSid)) + { + goto end_fail; + } + + // Create the security descriptor and put the DACL in it. + // + if ( !InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION )) + { + goto end_fail; + } + + if ( !SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE ) ) + { + goto end_fail; + } + + // Set owner for the descriptor + // + if ( !SetSecurityDescriptorOwner( pSD, pSidOwner, FALSE) ) + { + goto end_fail; + } + + // Set group for the descriptor + // + if ( !SetSecurityDescriptorGroup( pSD, pSidGroup, FALSE) ) + { + goto end_fail; + } + + FreeSid(pObjSid); + return pSD; + + +end_fail: + { + DWORD dwRetCode = GetLastError(); + + if (pDacl) { LocalFree(pDacl); pDacl=0;} + + if (pObjSid) { FreeSid(pObjSid); pObjSid=0;} + + if (pSD) { LocalFree(pSD); pSD=0;} + + SetLastError(dwRetCode); + } + return NULL; +} + + +//**************************************************************************** +// Description: Frees a security descriptor previously allocated by +// AllocateSecurityDescriptor. +// +// History: +// 3/27/96 JosephJ Created +//****************************************************************************/ +void FreeSecurityDescriptor(PSECURITY_DESCRIPTOR pSD) +{ + PSID pObjSid = NULL; + PACL pDacl = NULL; + BOOL fGotAcl=FALSE, fByDefault=FALSE; + + + // Free Dacl, if user had allocated it. + if (GetSecurityDescriptorDacl(pSD, &fGotAcl, &pDacl, &fByDefault )) + { + if (fGotAcl && !fByDefault && pDacl) + { + LocalFree(pDacl); + } + } + else + { + ASSERT(FALSE); // We should not be calling this function with such + // an pSD. + } + + LocalFree(pSD); + +} diff --git a/private/unimodem/new/slot/sec.h b/private/unimodem/new/slot/sec.h new file mode 100644 index 000000000..9ec615f7e --- /dev/null +++ b/private/unimodem/new/slot/sec.h @@ -0,0 +1,24 @@ +//**************************************************************************** +// +// Module: UNIMDM +// File: SEC.H +// +// Copyright (c) 1992-1996, Microsoft Corporation, all rights reserved +// +// Revision History +// +// +// 3/27/96 JosephJ Created +// +// +// Description: Security-related helper functions +// +//**************************************************************************** +PSECURITY_DESCRIPTOR AllocateSecurityDescriptor ( + PSID_IDENTIFIER_AUTHORITY pSIA, + DWORD dwRID, + DWORD dwRights, + PSID pSidOwner, + PSID pSidGroup + ); +void FreeSecurityDescriptor(PSECURITY_DESCRIPTOR pSD); diff --git a/private/unimodem/new/slot/slot.c b/private/unimodem/new/slot/slot.c new file mode 100644 index 000000000..35236c439 --- /dev/null +++ b/private/unimodem/new/slot/slot.c @@ -0,0 +1,486 @@ +//**************************************************************************** +// +// Module: UNIMDM +// File: SLOT.C +// +// Copyright (c) 1992-1996, Microsoft Corporation, all rights reserved +// +// Revision History +// +// +// 3/25/96 JosephJ Created +// +// +// Description: Implements the unimodem TSP notification mechanism: +// The lower level (notifXXXX) APIs +// +//**************************************************************************** + +#define UNICODE +#include <windows.h> +#include <stdio.h> +#include "slot.h" +#include "sec.h" + +#define T(_str) TEXT(_str) + +#define ASSERT(_c) \ + ((_c) ? 0: DPRINTF2("Assertion failed in %s:%d\n", __FILE__, __LINE__)) +#define DPRINTF(_fmt) printf(_fmt) +#define DPRINTF1(_fmt,_arg) printf(_fmt,_arg) +#define DPRINTF2(_fmt,_arg,_arg2) printf(_fmt,_arg,_arg2) +#define DPRINTF3(_fmt,_arg,_arg2,_arg3) printf(_fmt,_arg,_arg2,_arg3) + +#define fNOTIF_STATE_DEINIT 0 +#define fNOTIF_STATE_INIT_SERVER 1 +#define fNOTIF_STATE_INIT_CLIENT 2 + +#define IS_SERVER(_pns) ((_pns)->dwState==fNOTIF_STATE_INIT_SERVER) +#define IS_CLIENT(_pns) ((_pns)->dwState==fNOTIF_STATE_INIT_CLIENT) + + +// The following help define the fully-qualified mailslot and semaphore names. +#define dwNOTIFSTATE_SIG (0x53CB31A0L) +#define FULLNAME_TEMPLATE T("--.-mailslot-%08lx-%s") + +// Keeps the state of a notification (either client or server). +// It is cast to a DWORD to form the handle returned by notifCreate() +typedef struct +{ + DWORD dwSig; // should be dwNOTIFSTATE_SIG when inited + HANDLE hSem; + HANDLE hSlot; + DWORD dwState; + DWORD dwcbMax; + +} NOTIFICATION_STATE, *PNOTIFICATION_STATE; + +DWORD inotif_server_create(PNOTIFICATION_STATE pns, LPTSTR lptsz, + DWORD dwMaxSize, + DWORD dwMaxPending); +DWORD inotif_client_open(PNOTIFICATION_STATE pns, LPTSTR lptsz); +PNOTIFICATION_STATE inotif_getstate(HNOTIFICATION hn); + + +//**************************************************************************** +// Function: Creates a notification object -- either as server or client. +// +// History: +// 3/25/96 JosephJ Created +//****************************************************************************/ +HNOTIFICATION notifCreate( + BOOL fServer, // TRUE ==> Server + LPCTSTR lptszName, // Name to associate with this object + DWORD dwMaxSize, // Max size of frames written/read + // (Ignored if (!fServer)) + DWORD dwMaxPending // Max number of notification frames allowed + // to be pending. (Ignored if (!fServer)) +) +{ + PNOTIFICATION_STATE pns=NULL; + HNOTIFICATION hn=0; + TCHAR rgtchTmp[MAX_NOTIFICATION_NAME_SIZE+23]; + UINT u = lstrlen(lptszName); + DWORD dwErr=0; + + // Format of semaphore name is --.-mailslot-sig-name + // Example: "--.-mailslot-8cb45651-unimodem" + // To create the equivalent mailslot, we run through and change + // all '-' to '\'s (if the name containts '-', they will get converted -- + // big deal.) + if ((u+23)>(sizeof(rgtchTmp)/sizeof(TCHAR))) // 13(prefix)+ 9(sig-) +1(null) + { + dwErr = ERROR_INVALID_PARAMETER; + goto end; + } + + pns=LocalAlloc(LPTR, sizeof(*pns)); + if (!pns) goto end; + + wsprintf(rgtchTmp,FULLNAME_TEMPLATE, + (unsigned long) dwNOTIFSTATE_SIG, + lptszName); + + DPRINTF1("Semaphore name = [%s]\n", rgtchTmp); + + if (fServer) dwErr = inotif_server_create(pns, rgtchTmp, + dwMaxSize, dwMaxPending); + else dwErr = inotif_client_open(pns, rgtchTmp); + + if (dwErr) goto end; + pns->dwSig=dwNOTIFSTATE_SIG; + hn = (HNOTIFICATION)pns; + +end: + if (!hn) + { + if (!dwErr) dwErr=GetLastError(); + if (pns) LocalFree(pns); + SetLastError(dwErr); + } + return hn; +} + +//**************************************************************************** +// Function: Free a notification object +// +// History: +// 3/25/96 JosephJ Created +//****************************************************************************/ +void notifFree(HNOTIFICATION hn) +{ + PNOTIFICATION_STATE pns = inotif_getstate(hn); + if (hn) + { + pns->dwSig=0; + CloseHandle(pns->hSem); pns->hSem=0; + CloseHandle(pns->hSlot); pns->hSlot=0; + LocalFree(pns); + } +} + +//**************************************************************************** +// Function: Retrieve the synchronization object handle accociated with +// the notiication object. NOTE: This handle is valid until +// the notification object is alive. It must NOT be deleted +// externally. Must be a server object. +// +// History: +// 3/25/96 JosephJ Created +//****************************************************************************/ +HANDLE notifGetObj(HNOTIFICATION hn) +{ + PNOTIFICATION_STATE pns = inotif_getstate(hn); + if (pns && IS_SERVER(pns)) + { + return pns->hSem; + } + else if (pns) + { + SetLastError(ERROR_NOT_SUPPORTED); + return NULL; + } + else + { + SetLastError(ERROR_INVALID_HANDLE); + return NULL; + } +} + +//**************************************************************************** +// Function: Retrieves the max allowable size of the frame (server only) +// +// History: +// 3/25/96 JosephJ Created +//****************************************************************************/ +DWORD notifGetMaxSize(HNOTIFICATION hn) +{ + PNOTIFICATION_STATE pns = inotif_getstate(hn); + if (pns && IS_SERVER(pns)) + { + return pns->dwcbMax; + } + else + { + if (pns) + { + SetLastError(ERROR_NOT_SUPPORTED); + } + else + { + SetLastError(ERROR_INVALID_HANDLE); + } + return 0; + } +} + + +//**************************************************************************** +// Function: (Server only) Reads a notification msg, if any. Does not block. +// A return value of FALSE and a GetLastError value of ERROR_NO_DATA +// indicates that no frame was available.. +// History: +// 3/25/96 JosephJ Created +//****************************************************************************/ +BOOL notifReadMsg(HNOTIFICATION hn, + LPBYTE lpb, + DWORD dwcbMax, + LPDWORD lpdwRead) +{ + PNOTIFICATION_STATE pns = inotif_getstate(hn); + BOOL fRet=FALSE; + *lpdwRead=0; + + if (pns) + { + DWORD dwRead=0; + + if(!IS_SERVER(pns)) + { + SetLastError(ERROR_NOT_SUPPORTED); + goto end; + } + + fRet = ReadFile(pns->hSlot, lpb, dwcbMax, lpdwRead, NULL); + + if (!fRet) + { + DPRINTF("ReadFile failed!\n"); + goto end; + } + + DPRINTF("Success!\n"); + fRet=TRUE; + } + else + { + SetLastError(ERROR_INVALID_HANDLE); + } + +end: + return fRet; +} + + +//**************************************************************************** +// Function: Returns the size of the next frame in the queue. Returns TRUE +// even if there is no data in the queue -- in this case, *lpdwcb +// is set to 0. Returns FALSE if there is some other error. +// +// History: +// 3/25/96 JosephJ Created +//****************************************************************************/ +BOOL notifGetNextMsgSize(HNOTIFICATION hn, LPDWORD lpdwcb) +{ + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; +} + + +//**************************************************************************** +// Function: (Client side). Write a notification msg. +// +// History: +// 3/25/96 JosephJ Created +//****************************************************************************/ +BOOL notifWriteMsg(HNOTIFICATION hn, LPBYTE lpb, DWORD dwcb) +{ + PNOTIFICATION_STATE pns = inotif_getstate(hn); + BOOL fRet=FALSE; + + if (pns) + { + DWORD dwWritten=0; + + if(!IS_CLIENT(pns)) + { + SetLastError(ERROR_NOT_SUPPORTED); + goto end; + } + + fRet = WriteFile(pns->hSlot, lpb, dwcb, &dwWritten, NULL); + if (fRet) + { + fRet=ReleaseSemaphore(pns->hSem,1,NULL); + if (!fRet) + { + DPRINTF("ReleaseSemaphore failed!\n"); + goto end; + } + } + if (!fRet || dwWritten!=dwcb) + { + DWORD dwErr = GetLastError(); + DPRINTF3("WriteFile failed. fRet=%lu; dwWritten=%lu; Err=%lu\n", + fRet, dwcb, dwErr); + SetLastError(dwErr); + goto end; + } + DPRINTF("notifWriteFrame: success!\n"); + fRet=TRUE; + } + else + { + SetLastError(ERROR_INVALID_HANDLE); + } + +end: + return fRet; +} + + +//**************************************************************************** +// Function: (internal) create the notif object -- server side. +// +// History: +// 3/25/96 JosephJ Created +//****************************************************************************/ +DWORD inotif_server_create(PNOTIFICATION_STATE pns, LPTSTR lptsz, DWORD dwMaxSize, + DWORD dwMaxPending) +{ + DWORD dwErr=ERROR_INVALID_PARAMETER; + TCHAR c, *pc = lptsz; + SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY; + SECURITY_ATTRIBUTES sa, *psa=NULL; + + PSECURITY_DESCRIPTOR pSD = AllocateSecurityDescriptor ( + &siaWorld, + SECURITY_WORLD_RID, + STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL + | SEMAPHORE_ALL_ACCESS + | SEMAPHORE_MODIFY_STATE + | GENERIC_READ + | GENERIC_WRITE + , + NULL, + NULL + ); + + if (!pSD) + { + DPRINTF1("WARNING:AllocateSecurityDescriptor(-) returns error 0x%lx\n", + GetLastError()); + } + else + { + DPRINTF("AllocateSecurityDescriptor(-) returns SUCCESS\n"); + sa.nLength = sizeof(sa); + sa.bInheritHandle=FALSE; + sa.lpSecurityDescriptor = pSD; + psa = &sa; + + } + + + // Create mailslot name -- make sure there are no '\'s + while(c=*pc++) {if (c=='\\') pc[-1]='-';} + DPRINTF1("Semaphore name = [%s]\n", lptsz); + + // Create Semaphore + { + pns->hSem=CreateSemaphore(psa, 0, dwMaxPending, lptsz); + if (pns->hSem && (dwErr=(GetLastError()==ERROR_ALREADY_EXISTS))) + { + DPRINTF1("Semaphore %s already exists!\n", lptsz); + CloseHandle(pns->hSem); + pns->hSem=NULL; + } + if (!pns->hSem) goto end_fail; + } + + // Create mailslot name + pc = lptsz; + while(c=*pc++) {if (c=='-') pc[-1]='\\';} + + DPRINTF1("Mailslot name = [%s]\n", lptsz); + + // CreateMailSlot -- specify size, zero-delay + pns->hSlot=CreateMailslot(lptsz, dwMaxSize, 0, psa); + if (!pns->hSlot) + { + dwErr = GetLastError(); + CloseHandle(pns->hSem); pns->hSem=0; + goto end_fail; + } + + DPRINTF("Mailslot created!\n"); + + // set state and maxsize + pns->dwState=fNOTIF_STATE_INIT_SERVER; + pns->dwcbMax=dwMaxSize; + dwErr=0; + goto end; + +end_fail: + if (!dwErr) dwErr=GetLastError(); + if (!dwErr) dwErr=ERROR_INVALID_PARAMETER; + +end: + if (pSD) {FreeSecurityDescriptor(pSD);} + return dwErr; +} + + +//**************************************************************************** +// Function: (internal) create the notif object -- client side. +// The server must be already up and running, or we will +// fail. +// +// History: +// 3/25/96 JosephJ Created +//****************************************************************************/ +DWORD inotif_client_open(PNOTIFICATION_STATE pns, LPTSTR lptsz) +{ + DWORD dwErr=ERROR_INVALID_PARAMETER; + TCHAR c, *pc = lptsz; + + // Create mailslot name -- convert '-' to '\'; + while(c=*pc++) {if (c=='-') pc[-1]='\\';} + DPRINTF1("Mailslot name = [%s]\n", lptsz); + + // Open mailslot ... + pns->hSlot=CreateFile( + lptsz, + GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + + if (!pns->hSlot) + { + DPRINTF("Couldn't open mailslot for writing\n"); + goto end_fail; + } + + // Create Semaphore name -- convert '\' to '-'; + pc=lptsz; + while(c=*pc++) {if (c=='\\') pc[-1]='-';} + DPRINTF1("Sempahore name = [%s]\n", lptsz); + + pns->hSem=OpenSemaphore(SEMAPHORE_MODIFY_STATE, FALSE, lptsz); + //pns->hSem=OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, lptsz); + if (!pns->hSem) { + DPRINTF("Could not open semaphore\n"); + dwErr=GetLastError(); + CloseHandle(pns->hSlot); pns->hSlot=0; + goto end_fail; + } + + // set state and maxsize + pns->dwState=fNOTIF_STATE_INIT_CLIENT; + pns->dwcbMax=0; // Apparently you can't get the max size of the mailslot. + dwErr=0; + goto end; + +end_fail: + if (!dwErr) dwErr=GetLastError(); + if (!dwErr) dwErr=ERROR_INVALID_PARAMETER; + +end: + return dwErr; +} + +//**************************************************************************** +// Function: (internal) validates and converts a handle to a ptr to state. +// +// History: +// 3/25/96 JosephJ Created +//****************************************************************************/ +PNOTIFICATION_STATE inotif_getstate(HNOTIFICATION hn) +{ + if (hn) + { + PNOTIFICATION_STATE pns= (PNOTIFICATION_STATE) hn; + if (pns->dwSig!=dwNOTIFSTATE_SIG) + { + DPRINTF1("Bad hotification handle 0x%lu\n", hn); + ASSERT(FALSE); + return NULL; + } + return pns; + } + return NULL; +} diff --git a/private/unimodem/new/slot/slot.h b/private/unimodem/new/slot/slot.h new file mode 100644 index 000000000..a8ea4fbe9 --- /dev/null +++ b/private/unimodem/new/slot/slot.h @@ -0,0 +1,32 @@ +//**************************************************************************** +// +// Module: UNIMDM +// File: SLOT.H +// +// Copyright (c) 1992-1996, Microsoft Corporation, all rights reserved +// +// Revision History +// +// +// 3/25/96 JosephJ Created +// +// +// Description: Interface to the unimodem TSP notification mechanism: +// The lower level (notifXXXX) APIs +// +//**************************************************************************** + +#define MAX_NOTIFICATION_NAME_SIZE 256 + + +typedef DWORD HNOTIFICATION; + +HNOTIFICATION notifCreate(BOOL fServer, LPCTSTR lptszName, DWORD dwMaxSize, + DWORD dwMaxPending); +void notifFree(HNOTIFICATION hn); + +HANDLE notifGetObj(HNOTIFICATION hn); +DWORD notifGetMaxSize(HNOTIFICATION hn); +BOOL notifReadMsg(HNOTIFICATION hn, LPBYTE lpb, DWORD dwcb, LPDWORD lpdwRead); +BOOL notifGetNextMsgSize(HNOTIFICATION hn, LPDWORD lpdwcb); +BOOL notifWriteMsg(HNOTIFICATION hn, LPBYTE lpb, DWORD dwcb); diff --git a/private/unimodem/new/slot/sources b/private/unimodem/new/slot/sources new file mode 100644 index 000000000..fb7d59080 --- /dev/null +++ b/private/unimodem/new/slot/sources @@ -0,0 +1,27 @@ +MAJORCOMP=net +MINORCOMP=unimodem + +TARGETNAME=tslot +TARGETPATH=obj +TARGETTYPE=PROGRAM +TARGETLIBS=\ + $(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\user32.lib + + +INCLUDES=$(BASEDIR)\public\sdk\inc;. + +C_DEFINES=-DWINVER=0x0400 + +USE_CRTDLL=1 + +SOURCES=slot.c \ + client.c \ + sec.c \ + main.c + +UMTYPE=console + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF |