home *** CD-ROM | disk | FTP | other *** search
- // ===========================================================================
- // File: S E C S V R . C P P
- //
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- // PARTICULAR PURPOSE.
- //
- // Description:
- //
- // This is the server-portion of the SECURE Network OLE sample. This
- // application implements several different server capabilities:
- // * Free-threaded server implemented as a Service. The application
- // implements a "LocalService" (CLSID_SecureObjectService) class.
- // * Free-threaded server implemented as a standard executable. The
- // application implements a "LocalServer32" (CLSID_SecureObject) class
- // and runs without user-interface.
- // * Apartment-threaded server implemented as a standard executable. The
- // application implements a "LocalServer32" (CLSID_SecureObject) class
- // and runs with a dialog-box user-interface showing the status of the
- // objects that it has handed out to clients.
- //
- // The purpose of this sample is to demonstrate the different packaging
- // options available to server writers, and to demonstrate call-security
- // capabilities.
- //
- // Instructions:
- //
- // To use this sample:
- // * build the samples using the NMAKE command. NMAKE will create SECCLNT.EXE,
- // SECSVR.EXE, and PSMYPROP.DLL. PSMYPROP.DLL is the remoting proxies and
- // stubs for the custom interface used between the client and the server.
- // * install the server on the current machine or on a remote machine
- // by running INSTALL.BAT in the same directory with SECSVR.EXE and
- // PSMYPROP.DLL. This program registers the proxy-stub DLL using the
- // REGSVR32 tool (included in the \mstools\bin directory of the SDK) and
- // runs the SECSVR.EXE program with "-AutoRegister" on the command-line,
- // which forces it to install itself.
- // * to run the apartment-threaded server, use "SECSVR -Interactive" to launch
- // the server from the command-line. the application will present UI allowing
- // you to choose how to initialize security for the server process, and
- // to view objects currently being used by clients.
- // * In Section 1, choose the security parameters to CoInitializeSecurity from
- // the two drop-down lists, and press the Initialize button.
- // * next, run SECCLNT.EXE from the same machine or from a remote machine. Follow
- // the instructions listed in SECCLNT.CPP to connect to this instance of the
- // SECSVR.EXE application.
- // * once a client has created an instance of the CLSID_SecureObject class, the
- // object will be listed in the drop-down list in Section 2 of the SECSVR.EXE
- // UI. Select the object to be viewed from this list. The current color and
- // "name" established by the client will be displayed in Section 2.
- // * use the "Lock" button to prevent the client from setting the color or "UserName"
- // of the object. the client will display an "access-denied" message if it
- // fails to set the color or "UserName". in the future this sample will include
- // the ability to establish a security-descriptor on the color and Name, and
- // will demonstrate impersonating the client and performing an AccessCheck()
- // during the PutColor and PutUserName methods.
- // * Push the "Exit" button in Section 1 to shut the server down.
- //
- // Copyright 1996 Microsoft Corporation. All Rights Reserved.
- // ===========================================================================
-
- // %%Includes: ---------------------------------------------------------------
- #define INC_OLE2
- #define STRICT
- #define UNICODE
- #include <windows.h>
- #include <initguid.h>
- #include "myprop.h"
- #include "secsvr.h"
-
- // %%Macros: -----------------------------------------------------------------
- #define ENTRY(sz, val) { sz, val }
- #define RGSIZEOF(rg) (sizeof(rg)/sizeof((rg)[0]))
-
- // %%Constants: --------------------------------------------------------------
- const TCHAR szServiceName[] = TEXT("SecSvr");
- const TCHAR szDescription[] = TEXT("Network OLE Security Sample");
- #define cAuthnLevelEntries RGSIZEOF(rgAuthnLevelEntries)
- #define cImpLevelEntries RGSIZEOF(rgImpLevelEntries)
-
- // %%Types: ------------------------------------------------------------------
- typedef struct tagENTRY{
- TCHAR *szName;
- DWORD dwVal;
- } ENTRY, *PENTRY;
-
- // %%Classes: ----------------------------------------------------------------
- class CClassFactory : public IClassFactory
- {
- // IClassFactory
- STDMETHODIMP QueryInterface(REFIID iid, void **ppv);
- STDMETHODIMP_(ULONG) AddRef(void) { return 1; }
- STDMETHODIMP_(ULONG) Release(void) { return 1; }
- STDMETHODIMP CreateInstance(LPUNKNOWN punkOuter, REFIID iid, LPVOID FAR *ppv);
- STDMETHODIMP LockServer(BOOL fLock);
- };
-
- class CSecureObject : public IMyProperties
- {
- // IUnknown
- STDMETHODIMP QueryInterface(REFIID iid, void **ppv);
- STDMETHODIMP_(ULONG) AddRef(void) { return InterlockedIncrement(&m_cRef); }
- STDMETHODIMP_(ULONG) Release(void) { if (InterlockedDecrement(&m_cRef) == 0) { delete this; return 0; } return 1; }
-
- // IMyProperties
- STDMETHODIMP GetColor(COLORREF* pcr);
- STDMETHODIMP PutColor(COLORREF cr);
- STDMETHODIMP GetUserName(WCHAR szUserName[20]);
- STDMETHODIMP PutUserName(WCHAR szUserName[20]);
-
- // data members
- LONG m_cRef;
- public:
- COLORREF m_crColor;
- BOOL m_fDenyPutColor;
- WCHAR m_rgchUserName[20];
- BOOL m_fDenyPutUserName;
-
- // constructors/destructors
- CSecureObject();
- ~CSecureObject();
- };
-
- // %%Prototypes: -------------------------------------------------------------
- void MyServiceMain(DWORD cArg, LPTSTR *rgszArg);
- void MyServiceHandler(DWORD dwControl);
- void ErrorMessage(HWND hwnd, LPTSTR szFunction, HRESULT hr);
-
- // %%Globals: ----------------------------------------------------------------
- CClassFactory s_ClassFactory;
- struct {
- SERVICE_STATUS Status;
- SERVICE_STATUS_HANDLE hStatus;
- DWORD dwRegister;
- } s_Service;
- SERVICE_TABLE_ENTRY s_rgsteServices[2] = { { (TCHAR*)szServiceName, MyServiceMain },
- { NULL, NULL } };
- HWND s_hwndDlg;
- UINT s_cInstances;
- HANDLE s_hevtDone;
- CRITICAL_SECTION s_csDone;
- BOOL s_fDone, s_fServer, s_fService;
- ENTRY rgAuthnLevelEntries[] = {
- ENTRY(TEXT("Default "), RPC_C_AUTHN_DEFAULT),
- ENTRY(TEXT("None "), RPC_C_AUTHN_LEVEL_NONE),
- ENTRY(TEXT("Connect "), RPC_C_AUTHN_LEVEL_CONNECT),
- ENTRY(TEXT("Call "), RPC_C_AUTHN_LEVEL_CALL),
- ENTRY(TEXT("Packet "), RPC_C_AUTHN_LEVEL_PKT),
- ENTRY(TEXT("Integrity "), RPC_C_AUTHN_LEVEL_PKT_INTEGRITY),
- ENTRY(TEXT("Privacy "), RPC_C_AUTHN_LEVEL_PKT_PRIVACY),
- };
-
- ENTRY rgImpLevelEntries[] = {
- ENTRY(TEXT("Anonymous "), RPC_C_IMP_LEVEL_ANONYMOUS),
- ENTRY(TEXT("Identify "), RPC_C_IMP_LEVEL_IDENTIFY),
- ENTRY(TEXT("Impersonate"), RPC_C_IMP_LEVEL_IMPERSONATE),
- ENTRY(TEXT("Delegate "), RPC_C_IMP_LEVEL_DELEGATE),
- };
-
-
- // ===========================================================================
- // C C L A S S F A C T O R Y
- // ===========================================================================
-
- // ---------------------------------------------------------------------------
- // %%Function: CClassFactory::QueryInterface
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CClassFactory::QueryInterface(REFIID iid, void **ppv)
- {
- if (iid == IID_IClassFactory || iid == IID_IUnknown)
- {
- *ppv = (IClassFactory *)this;
- AddRef();
- return S_OK;
- }
- *ppv = NULL;
- return E_NOINTERFACE;
- } // CClassFactory::QueryInterface
-
- // ---------------------------------------------------------------------------
- // %%Function: CClassFactory::CreateInstance
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CClassFactory::CreateInstance(LPUNKNOWN punkOuter, REFIID riid, void **ppv)
- {
- LPUNKNOWN punk;
- HRESULT hr;
-
- *ppv = NULL;
-
- if (punkOuter != NULL)
- return CLASS_E_NOAGGREGATION;
-
- if (s_fServer)
- {
- EnterCriticalSection(&s_csDone);
- if (s_fDone == TRUE)
- {
- LeaveCriticalSection(&s_csDone);
- return E_FAIL;
- }
- LeaveCriticalSection(&s_csDone);
- }
-
- punk = new CSecureObject;
- if (punk == NULL)
- return E_OUTOFMEMORY;
-
- hr = punk->QueryInterface(riid, ppv);
- punk->Release();
- return hr;
- } // CClassFactory::CreateInstance
-
- // ---------------------------------------------------------------------------
- // %%Function: CClassFactory::LockServer
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CClassFactory::LockServer(BOOL fLock)
- {
- // LockServer not supported by the GUI server -- shutdown is
- // completely controlled by the UI's Exit command
- if (!s_fServer)
- return E_FAIL;
-
- // LockServer acts like having an artificial object outstanding:
- // this code mimics the lifetime management found in the constructor
- // and destructor of CSecureObject
- EnterCriticalSection(&s_csDone);
- if (fLock)
- s_cInstances++;
- else
- {
- if (!--s_cInstances && !s_fService) /* could perform other shutdown management here */
- {
- s_fDone = TRUE;
- SetEvent(s_hevtDone);
- }
- }
- LeaveCriticalSection(&s_csDone);
- return S_OK;
- } // CClassFactory::LockServer
-
-
- // ===========================================================================
- // C S e c u r e O b j e c t
- // ===========================================================================
-
- // ---------------------------------------------------------------------------
- // %%Function: CSecureObject::CSecureObject
- // ---------------------------------------------------------------------------
- CSecureObject::CSecureObject()
- {
- static int s_ID = 0;
-
- // initialize the object's state
- m_cRef = 1;
- m_crColor = 0;
- m_fDenyPutColor = FALSE;
- lstrcpyW(m_rgchUserName, L"Default");
- m_fDenyPutUserName = FALSE;
-
- if (!s_fServer)
- {
- TCHAR rgchName[20];
- HWND hwnd;
- int iPos;
-
- // insert the object into the server UI. put our this-pointer into the item
- // data field of the entry so that we can remove the entry in our destructor
- wsprintf(rgchName, TEXT("Object %d"), s_ID++);
- hwnd = GetDlgItem(s_hwndDlg, IDC_OBJECTS);
- iPos = SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)rgchName);
- SendMessage(hwnd, CB_SETITEMDATA, iPos, (LPARAM)this);
- }
- else
- {
- EnterCriticalSection(&s_csDone);
- s_cInstances++;
- LeaveCriticalSection(&s_csDone);
- }
- } // CSecureObject::CSecureObject
-
- CSecureObject::~CSecureObject()
- {
- if (!s_fServer)
- {
- HWND hwnd;
- int i, iSel, iMac;
-
- // remove the reference to us from the server UI. our this-pointer is in
- // the item-data field of the entry -- find it.
- hwnd = GetDlgItem(s_hwndDlg, IDC_OBJECTS);
- iSel = SendMessage(hwnd, CB_GETCURSEL, 0, 0);
- iMac = SendMessage(hwnd, CB_GETCOUNT, 0, 0);
- for (i=0; i<iMac; i++)
- {
- if ((LRESULT)this == SendMessage(hwnd, CB_GETITEMDATA, i, 0))
- {
- SendMessage(hwnd, CB_DELETESTRING, i, 0);
-
- // if the item being deleted is the current selection,
- // change the selection
- if (i == iSel)
- {
- SendMessage(hwnd, CB_SETCURSEL, 0, 0);
- PostMessage(s_hwndDlg, WM_COMMAND, MAKELONG(IDC_OBJECTS, CBN_SELCHANGE),
- (LPARAM)hwnd);
- }
- break;
- }
- }
- }
- else
- {
- EnterCriticalSection(&s_csDone);
- if (!--s_cInstances && !s_fService) /* could perform other shutdown management here */
- {
- s_fDone = TRUE;
- SetEvent(s_hevtDone);
- }
- LeaveCriticalSection(&s_csDone);
- }
- } // CSecureObject::~CSecureObject
-
- // ---------------------------------------------------------------------------
- // %%Function: CSecureObject::QueryInterface
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CSecureObject::QueryInterface(REFIID iid, void **ppv)
- {
- if (iid == IID_IMyProperties || iid == IID_IUnknown)
- {
- *ppv = (IMyProperties *)this;
- AddRef();
- return S_OK;
- }
- *ppv = NULL;
- return E_NOINTERFACE;
- } // CSecureObject::QueryInterface
-
- // ---------------------------------------------------------------------------
- // %%Function: CSecureObject::GetColor
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CSecureObject::GetColor(COLORREF* pcr)
- {
- *pcr = m_crColor;
- return S_OK;
- } // CSecureObject::GetColor
-
- // ---------------------------------------------------------------------------
- // %%Function: CSecureObject::PutColor
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CSecureObject::PutColor(COLORREF cr)
- {
- // a naive security check under control of the local-server's UI
- if (m_fDenyPutColor == TRUE)
- return E_ACCESSDENIED;
-
- m_crColor = cr;
-
- // update the UI to reflect a valid PutColor occurred
- if (!s_fServer)
- PostMessage(s_hwndDlg, WM_COMMAND, MAKELONG(IDC_OBJECTS,CBN_SELCHANGE),
- (LPARAM)GetDlgItem(s_hwndDlg, IDC_OBJECTS));
-
- return S_OK;
- } // CSecureObject::PutColor
-
- // ---------------------------------------------------------------------------
- // %%Function: CSecureObject::GetUserName
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CSecureObject::GetUserName(WCHAR szUserName[20])
- {
- lstrcpynW(szUserName, m_rgchUserName, 20);
- return S_OK;
- } // CSecureObject::GetUserName
-
- // ---------------------------------------------------------------------------
- // %%Function: CSecureObject::PutUserName
- // ---------------------------------------------------------------------------
- STDMETHODIMP
- CSecureObject::PutUserName(WCHAR szUserName[20])
- {
- // a naive security check under control of the local-server's UI
- if (m_fDenyPutUserName == TRUE)
- return E_ACCESSDENIED;
-
- lstrcpynW(m_rgchUserName, szUserName, 20);
-
- // update the UI to reflect a valid PutUserName occurred
- if (!s_fServer)
- PostMessage(s_hwndDlg, WM_COMMAND, MAKELONG(IDC_OBJECTS,CBN_SELCHANGE),
- (LPARAM)GetDlgItem(s_hwndDlg, IDC_OBJECTS));
-
- return S_OK;
- } // CSecureObject::PutUserName
-
-
- // ---------------------------------------------------------------------------
- // %%Function: FAutoRegister
- // ---------------------------------------------------------------------------
- BOOL
- FAutoRegister(HINSTANCE hinst)
- {
- static const TCHAR szCLSIDEntryServer[] = TEXT("CLSID\\{28f64ee0-4656-11cf-8110-00aa00389b71}");
- static const TCHAR szLocalServer32[] = TEXT("LocalServer32");
- static const TCHAR szAllowRemoteActivation[] = TEXT("AllowRemoteActivation");
- static const TCHAR szCLSIDEntryService[] = TEXT("CLSID\\{28f64ee2-4656-11cf-8110-00aa00389b71}");
- static const TCHAR szLocalService[] = TEXT("LocalService");
- static const TCHAR szServiceParameters[] = TEXT("ServiceParameters");
- static const TCHAR szParameters[] = TEXT("-Service");
- static const TCHAR szEmpty[] = TEXT("");
- SC_HANDLE hManager = NULL, hService = NULL;
- TCHAR szPath[MAX_PATH], *szError = TEXT("Registry Manipulation");
- HKEY hkeyT = NULL, hkey2;
-
- // install the CLSID_SecureObject key and get the FQP to this executable
- if ((RegSetValue(HKEY_CLASSES_ROOT, szCLSIDEntryServer, REG_SZ, szDescription,
- lstrlen(szDescription)) != ERROR_SUCCESS) ||
- (RegCreateKey(HKEY_CLASSES_ROOT, szCLSIDEntryServer, &hkeyT) != ERROR_SUCCESS) ||
- !GetModuleFileName(hinst, szPath, sizeof(szPath)/sizeof(TCHAR)))
- goto LErrExit;
-
- // install the LocalServer32 key and the AllowRemoteActivation key
- if ((RegSetValue(hkeyT, szLocalServer32, REG_SZ, szPath, lstrlen(szPath))
- != ERROR_SUCCESS) ||
- (RegSetValue(hkeyT, szAllowRemoteActivation, REG_SZ, szEmpty, lstrlen(szEmpty))
- != ERROR_SUCCESS))
- goto LErrExit;
- RegCloseKey(hkeyT);
- hkeyT = NULL;
-
- // install the CLSID_SecureObjectService key
- if ((RegSetValue(HKEY_CLASSES_ROOT, szCLSIDEntryService, REG_SZ, szDescription,
- lstrlen(szDescription)) != ERROR_SUCCESS) ||
- (RegCreateKey(HKEY_CLASSES_ROOT, szCLSIDEntryService, &hkeyT) != ERROR_SUCCESS))
- goto LErrExit;
-
- // install the LocalService key and the ServiceParameters named-value
- if ((RegSetValue(hkeyT, szLocalService, REG_SZ, szServiceName, lstrlen(szServiceName))
- != ERROR_SUCCESS) ||
- (RegOpenKey(hkeyT, szLocalService, &hkey2) != ERROR_SUCCESS))
- goto LErrExit;
- RegCloseKey(hkeyT);
- hkeyT = hkey2;
- if (RegSetValueEx(hkeyT, szServiceParameters, 0, REG_SZ, (const BYTE*)szParameters,
- (lstrlen(szParameters)+1) * sizeof(TCHAR)) != ERROR_SUCCESS)
- goto LErrExit;
-
- RegCloseKey(hkeyT);
- hkeyT = NULL;
-
- // install the application to run as a service
- hManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if (hManager == NULL)
- {
- szError = TEXT("OpenSCManager");
- goto LErrExit;
- }
-
- hService = OpenService(hManager, szServiceName, SERVICE_ALL_ACCESS);
- if (hService != NULL)
- {
- if (!ChangeServiceConfig(hService,
- SERVICE_WIN32_OWN_PROCESS,
- SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szPath,
- NULL, NULL, NULL, NULL, NULL, szDescription))
- {
- szError = TEXT("ChangeServiceConfig");
- goto LErrExit;
- }
- return TRUE;
- }
-
- hService = CreateService(hManager, szServiceName, szDescription,
- SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
- SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szPath,
- NULL, NULL, NULL, NULL, NULL);
- if (hService == NULL)
- {
- szError = TEXT("CreateService");
- goto LErrExit;
- }
-
- CloseServiceHandle(hService);
- CloseServiceHandle(hManager);
- return TRUE;
-
- LErrExit:
- ErrorMessage(GetDesktopWindow(), szError, GetLastError());
- if (hkeyT != NULL)
- RegCloseKey(hkeyT);
- if (hService != NULL)
- CloseServiceHandle(hService);
- if (hManager != NULL)
- CloseServiceHandle(hManager);
- return FALSE;
- } // FAutoRegister
-
- // ---------------------------------------------------------------------------
- // %%Function: ErrorMessage
- // ---------------------------------------------------------------------------
- void
- ErrorMessage(HWND hwnd, LPTSTR szFunction, HRESULT hr)
- {
- LPTSTR szMessage;
-
- if (HRESULT_FACILITY(hr) == FACILITY_WINDOWS)
- hr = HRESULT_CODE(hr);
-
- if (!FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, hr,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language
- (LPTSTR)&szMessage, 0, NULL))
- return;
-
- if (hwnd == NULL)
- {
- OutputDebugString(szFunction);
- OutputDebugString(TEXT(": "));
- OutputDebugString(szMessage);
- OutputDebugString(TEXT("\n"));
- }
- else
- MessageBox(hwnd, szMessage, szFunction, MB_OK);
-
- LocalFree(szMessage);
- } // ErrorMessage
-
- // ---------------------------------------------------------------------------
- // %%Function: SelectEntry
- // ---------------------------------------------------------------------------
- void
- SelectEntry(HWND hwnd, ENTRY* rgEntries, int cEntries, DWORD dwVal)
- {
- for (int i=0; i<cEntries; i++)
- {
- if (rgEntries[i].dwVal == dwVal)
- {
- SendMessage(hwnd, CB_SETCURSEL, i, 0);
- return;
- }
- }
- } // SelectEntry
-
- // ---------------------------------------------------------------------------
- // %%Function: GetField
- // ---------------------------------------------------------------------------
- DWORD
- GetField(HWND hwndDlg, UINT idItem)
- {
- HWND hwnd;
- int iCur;
-
- hwnd = GetDlgItem(hwndDlg, idItem);
- iCur = SendMessage(hwnd, CB_GETCURSEL, 0, 0);
- return SendMessage(hwnd, CB_GETITEMDATA, iCur, 0);
- } // GetField
-
- // ---------------------------------------------------------------------------
- // %%Function: ServerDialogProc
- // ---------------------------------------------------------------------------
- BOOL CALLBACK
- ServerDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- static DWORD s_dwRegister = 0;
- static BOOL s_fInitialized = FALSE;
- static CSecureObject* s_pcso = NULL;
- static COLORREF s_rgcrCustom[16];
- static HBRUSH s_hbrCurrent = NULL;
- HRESULT hr;
-
- switch (message)
- {
- case WM_INITDIALOG:
- {
- HWND hwnd;
- int cxScreen, cyScreen, i;
- RECT rcDlg;
-
- // save the hwndDlg into a global
- s_hwndDlg = hwndDlg;
-
- // Center the UI on screen
- cxScreen = GetSystemMetrics(SM_CXFULLSCREEN);
- cyScreen = GetSystemMetrics(SM_CYFULLSCREEN);
- GetWindowRect(hwndDlg, &rcDlg);
- OffsetRect(&rcDlg,
- (cxScreen - rcDlg.right - rcDlg.left)/2,
- (cyScreen - rcDlg.bottom - rcDlg.top)/2);
- MoveWindow(hwndDlg, rcDlg.left, rcDlg.top,
- rcDlg.right-rcDlg.left, rcDlg.bottom-rcDlg.top, TRUE);
-
- // build the lists of authentication levels. choose None for the
- // process default.
- hwnd = GetDlgItem(hwndDlg, IDC_SERVER_AUTHNLEVEL);
- for (i=0; i<cAuthnLevelEntries; i++)
- {
- SendMessage(hwnd, CB_INSERTSTRING, i, (LPARAM)rgAuthnLevelEntries[i].szName);
- SendMessage(hwnd, CB_SETITEMDATA, i, rgAuthnLevelEntries[i].dwVal);
- }
- SelectEntry(hwnd, rgAuthnLevelEntries, cAuthnLevelEntries, RPC_C_AUTHN_LEVEL_NONE);
-
- // build the lists of impersonation levels. choose Anonymous for the
- // process default.
- hwnd = GetDlgItem(hwndDlg, IDC_SERVER_IMPLEVEL);
- for (i=0; i<cImpLevelEntries; i++)
- {
- SendMessage(hwnd, CB_INSERTSTRING, i, (LPARAM)rgImpLevelEntries[i].szName);
- SendMessage(hwnd, CB_SETITEMDATA, i, rgImpLevelEntries[i].dwVal);
- }
- SelectEntry(hwnd, rgImpLevelEntries, cImpLevelEntries, RPC_C_IMP_LEVEL_ANONYMOUS);
- return 1;
- }
-
- case WM_SYSCOMMAND:
- if (wParam == SC_CLOSE)
- goto LClose;
- break;
-
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDCANCEL:
- LClose:
- if (s_hbrCurrent != NULL)
- {
- DeleteObject(s_hbrCurrent);
- s_hbrCurrent = NULL;
- }
- if (s_dwRegister != 0)
- {
- CoRevokeClassObject(s_dwRegister);
- s_dwRegister = 0;
- }
- if (s_fInitialized == TRUE)
- {
- CoUninitialize();
- s_fInitialized = FALSE;
- }
- EndDialog(hwndDlg, 0);
- break;
-
- case IDC_INITIALIZE:
- // initialize as apartment-threaded to synchronize the UI
- // with calls to the objects
- hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- if (FAILED(hr))
- {
- ErrorMessage(hwndDlg, TEXT("CoInitialize"), hr);
- break;
- }
-
- // initialize security layer with our choices
- hr = CoInitializeSecurity(NULL,
- -1,
- NULL,
- NULL,
- GetField(hwndDlg, IDC_SERVER_AUTHNLEVEL),
- GetField(hwndDlg, IDC_SERVER_IMPLEVEL),
- NULL,
- 0,
- NULL);
- if (FAILED(hr))
- {
- ErrorMessage(hwndDlg, TEXT("CoInitializeSecurity"), hr);
- break;
- }
-
- hr = CoRegisterClassObject(CLSID_SecureObject, &s_ClassFactory,
- CLSCTX_SERVER, REGCLS_MULTIPLEUSE, &s_dwRegister);
- if (FAILED(hr))
- {
- ErrorMessage(hwndDlg, TEXT("CoRegisterClassObject"), hr);
- CoUninitialize();
- break;
- }
-
- // Disable Initialization Step (#1)
- EnableWindow(GetDlgItem(hwndDlg, IDC_INITIALIZE), FALSE);
- EnableWindow(GetDlgItem(hwndDlg, IDC_SERVER_AUTHNLEVEL), FALSE);
- EnableWindow(GetDlgItem(hwndDlg, IDC_SERVER_IMPLEVEL), FALSE);
-
- // Enable Object Viewing Steps (#2)
- // (choosing a valid object in the list box will enable the
- // other controls)
- EnableWindow(GetDlgItem(hwndDlg, IDC_OBJECTS), TRUE);
-
- s_fInitialized = TRUE;
- break;
-
- case IDC_OBJECTS:
- {
- int iCur;
-
- if (HIWORD(wParam) != CBN_SELCHANGE)
- break;
-
- // a different object was chosen, or a property has changed.
- // retrieve the object's pointer from the item-data of the
- // current list-box item and update the UI.
- iCur = SendMessage(GetDlgItem(hwndDlg, IDC_OBJECTS),
- CB_GETCURSEL, 0, 0);
- if (iCur == CB_ERR)
- s_pcso = NULL;
- else
- {
- s_pcso = (CSecureObject*)SendMessage(GetDlgItem(hwndDlg, IDC_OBJECTS),
- CB_GETITEMDATA, iCur, 0);
- if (s_pcso == (LPVOID)CB_ERR)
- s_pcso = NULL;
- }
-
- if (s_hbrCurrent != NULL)
- {
- DeleteObject(s_hbrCurrent);
- s_hbrCurrent = NULL;
- }
- SetWindowText(GetDlgItem(hwndDlg, IDC_USERNAME), TEXT(""));
- InvalidateRect(GetDlgItem(hwndDlg, IDC_CHOOSECOLOR), NULL, TRUE);
- InvalidateRect(GetDlgItem(hwndDlg, IDC_COLOR), NULL, TRUE);
- InvalidateRect(GetDlgItem(hwndDlg, IDC_USERNAME), NULL, TRUE);
- InvalidateRect(GetDlgItem(hwndDlg, IDC_NOPUTCOLOR), NULL, TRUE);
- InvalidateRect(GetDlgItem(hwndDlg, IDC_NOPUTUSERNAME), NULL, TRUE);
-
- if (s_pcso != NULL)
- {
- SetWindowTextW(GetDlgItem(hwndDlg, IDC_USERNAME), s_pcso->m_rgchUserName);
- s_hbrCurrent = CreateSolidBrush(s_pcso->m_crColor);
- }
-
- // enable/disable the object-specific windows
- EnableWindow(GetDlgItem(hwndDlg, IDC_CHOOSECOLOR), s_pcso != NULL);
- EnableWindow(GetDlgItem(hwndDlg, IDC_COLOR), s_pcso != NULL);
- EnableWindow(GetDlgItem(hwndDlg, IDC_USERNAME), s_pcso != NULL);
- EnableWindow(GetDlgItem(hwndDlg, IDC_NOPUTCOLOR), s_pcso != NULL);
- EnableWindow(GetDlgItem(hwndDlg, IDC_NOPUTUSERNAME), s_pcso != NULL);
- break;
- }
-
- case IDC_NOPUTCOLOR:
- s_pcso->m_fDenyPutColor = SendMessage(
- GetDlgItem(hwndDlg, IDC_NOPUTCOLOR), BM_GETCHECK, 0, 0);
- break;
-
- case IDC_NOPUTUSERNAME:
- s_pcso->m_fDenyPutUserName = SendMessage(
- GetDlgItem(hwndDlg, IDC_NOPUTUSERNAME), BM_GETCHECK, 0, 0);
- break;
-
- case IDC_CHOOSECOLOR:
- {
- CHOOSECOLOR cc;
-
- cc.lStructSize = sizeof(CHOOSECOLOR);
- cc.hwndOwner = hwndDlg;
- cc.rgbResult = s_pcso->m_crColor;
- cc.lpCustColors = s_rgcrCustom;
- cc.Flags = CC_RGBINIT | CC_SHOWHELP;
-
- if (ChooseColor(&cc))
- {
- s_pcso->m_crColor = cc.rgbResult;
- if (s_hbrCurrent != NULL)
- DeleteObject(s_hbrCurrent);
- s_hbrCurrent = CreateSolidBrush(cc.rgbResult);
- InvalidateRect((HWND)lParam, NULL, TRUE);
- }
- break;
- }
-
- case IDC_USERNAME:
- {
- static s_fDirty = FALSE;
-
- if (HIWORD(wParam) == EN_CHANGE)
- {
- s_fDirty = TRUE;
- }
- else if (HIWORD(wParam) == EN_KILLFOCUS && s_fDirty)
- {
- GetWindowTextW(GetDlgItem(hwndDlg, IDC_USERNAME),
- s_pcso->m_rgchUserName, 20);
- s_fDirty = FALSE;
- }
- break;
- }
- }
- break;
-
- case WM_DRAWITEM:
- {
- LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
-
- FillRect(lpdis->hDC, &lpdis->rcItem,
- s_hbrCurrent != NULL ? s_hbrCurrent : (HBRUSH)GetStockObject(WHITE_BRUSH));
- FrameRect(lpdis->hDC, &lpdis->rcItem, (HBRUSH)GetStockObject(BLACK_BRUSH));
- if (lpdis->itemState & ODS_SELECTED)
- InvertRect(lpdis->hDC, (LPRECT)&lpdis->rcItem);
- if (lpdis->itemState & ODS_FOCUS)
- DrawFocusRect(lpdis->hDC, (LPRECT) &lpdis->rcItem);
- return TRUE;
- }
- }
- return FALSE;
- } // ServerDialogProc
-
- // ---------------------------------------------------------------------------
- // %%Function: MyServiceMain
- // ---------------------------------------------------------------------------
- void
- MyServiceMain(DWORD dwArgc, LPTSTR *pszArgv)
- {
- HRESULT hr;
-
- s_Service.Status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- s_Service.Status.dwCurrentState = SERVICE_START_PENDING;
- s_Service.Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
- s_Service.Status.dwWin32ExitCode = 0;
- s_Service.Status.dwServiceSpecificExitCode = 0;
- s_Service.Status.dwCheckPoint = 0;
- s_Service.Status.dwWaitHint = 0;
-
- s_Service.hStatus = RegisterServiceCtrlHandler(szServiceName, MyServiceHandler);
-
- if (s_Service.hStatus == NULL)
- return;
-
- // used to gaurd the s_fDone variable that prevents new instances
- // from being created in IClassFactory::CreateInstance during shutdown
- InitializeCriticalSection(&s_csDone);
-
- // event used to signal the service has stopped
- s_hevtDone = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (s_hevtDone == NULL)
- {
- ErrorMessage(NULL, TEXT("CreateEvent"), GetLastError());
- goto LErrExit;
- }
-
- hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
- if (FAILED(hr))
- {
- ErrorMessage(NULL, TEXT("CoInitialize"), hr);
- goto LErrExit;
- }
-
- // the Service CLSID is used here, different from the LocalServer case
- hr = CoRegisterClassObject(CLSID_SecureObjectService, &s_ClassFactory,
- CLSCTX_SERVER, REGCLS_MULTIPLEUSE, &s_Service.dwRegister);
-
- if (FAILED(hr))
- {
- ErrorMessage(NULL, TEXT("CoRegisterClassObject"), hr);
- CoUninitialize();
- goto LErrExit;
- }
-
- // Initialization complete - report running status
- s_Service.Status.dwCurrentState = SERVICE_RUNNING;
- s_Service.Status.dwCheckPoint = 0;
- s_Service.Status.dwWaitHint = 0;
-
- // notify the service-manager that the service is running
- if (!SetServiceStatus(s_Service.hStatus, &s_Service.Status))
- ErrorMessage(NULL, TEXT("SetServiceStatus(SERVICE_RUNNING)"), GetLastError());
-
- // wait for the signal from MyServiceHandler:SERVICE_CONTROL_STOP
- WaitForSingleObject(s_hevtDone, INFINITE);
-
- CloseHandle(s_hevtDone);
- s_hevtDone = NULL;
-
- CoRevokeClassObject(s_Service.dwRegister);
- CoUninitialize();
-
- // notify the service-manager that the service has totally stopped
- s_Service.Status.dwCurrentState = SERVICE_STOPPED;
- if (!SetServiceStatus(s_Service.hStatus, &s_Service.Status))
- ErrorMessage(NULL, TEXT("SetServiceStatus(SERVICE_STOPPED)"), GetLastError());
- return;
-
- LErrExit:
- if (s_hevtDone != NULL)
- {
- CloseHandle(s_hevtDone);
- s_hevtDone = NULL;
- }
- s_Service.Status.dwCurrentState = SERVICE_STOPPED;
- s_Service.Status.dwCheckPoint = 0;
- s_Service.Status.dwWaitHint = 0;
- s_Service.Status.dwWin32ExitCode = hr;
- s_Service.Status.dwServiceSpecificExitCode = hr;
- SetServiceStatus(s_Service.hStatus, &s_Service.Status);
- return;
- } // MyServiceMain
-
- // ---------------------------------------------------------------------------
- // %%Function: MyServiceHandler
- // ---------------------------------------------------------------------------
- void
- MyServiceHandler(DWORD dwControl)
- {
- switch (dwControl)
- {
- case SERVICE_CONTROL_STOP:
- s_Service.Status.dwWin32ExitCode = 0;
- s_Service.Status.dwCurrentState = SERVICE_STOP_PENDING;
- s_Service.Status.dwCheckPoint = 0;
- s_Service.Status.dwWaitHint = 0;
- if (!SetServiceStatus (s_Service.hStatus, &s_Service.Status))
- ErrorMessage(NULL, TEXT("SetServiceStatus"), GetLastError());
-
- EnterCriticalSection(&s_csDone);
-
- // prevent further instances from being created in IClassFactory::CreateInstance
- s_fDone = TRUE;
-
- // restart the waiting MyServiceMain thread and allow it to uninitialize and exit.
- SetEvent(s_hevtDone);
-
- LeaveCriticalSection(&s_csDone);
- return;
-
- case SERVICE_CONTROL_INTERROGATE:
- // fall out and send the current status of s_Service.Status
- break;
-
- default:
- break;
- }
-
- // send current status.
- if (!SetServiceStatus(s_Service.hStatus, &s_Service.Status))
- ErrorMessage(NULL, TEXT("SetServiceStatus"), GetLastError());
-
- return;
- } // MyServiceHandler
-
- // ---------------------------------------------------------------------------
- // %%Function: WinMain
- // ---------------------------------------------------------------------------
- int WINAPI
- WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nCmdShow)
- {
- HRESULT hr;
-
- // DebugBreak();
-
- // parse the command-line
- if (szCmdLine)
- {
- char *sz = strtok(szCmdLine, " \t");
- if (sz)
- {
- if (!strcmpi(sz, "-Embedding"))
- s_fServer = TRUE;
-
- // Auto-register, display success or failure, and exit
- else if (!strcmpi(sz, "-AutoRegister"))
- {
- if (FAutoRegister(hInstance))
- MessageBox(GetDesktopWindow(),
- TEXT("Registered Successfully!"),
- szDescription,
- MB_OK);
- return S_OK;
- }
-
- // any other argument besides interactive causes help to be displayed
- else if (strcmpi(sz, "-Interactive"))
- {
- // MessageBox some help here
- }
- }
- else
- {
- s_fService = TRUE;
- s_fServer = TRUE;
- }
- }
-
- // when launched without command-line args, run as a service, without any UI
- // and running multi-threaded
- if (s_fService)
- return StartServiceCtrlDispatcher(s_rgsteServices) ? 0 : GetLastError();
-
- // when launched with -Embedding, come up
- // without any UI and run multi-threaded
- else if (s_fServer)
- {
- DWORD dwRegister;
-
- InitializeCriticalSection(&s_csDone);
-
- s_hevtDone = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (s_hevtDone == NULL)
- return HRESULT_FROM_WIN32(GetLastError());
-
- hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
- if (FAILED(hr))
- return hr;
-
- hr = CoRegisterClassObject(CLSID_SecureObject, &s_ClassFactory,
- CLSCTX_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
- if (FAILED(hr))
- goto LServerExit;
-
- // wait for all open connections to the server to go away
- WaitForSingleObject(s_hevtDone, INFINITE);
-
- // Destroy the event handle
- CloseHandle(s_hevtDone);
- s_hevtDone = NULL;
-
- // destroy the critsec used to determine when we're done
- DeleteCriticalSection(&s_csDone);
-
- CoRevokeClassObject(dwRegister);
-
- LServerExit:
- CoUninitialize();
- return hr;
- }
-
- // when launched with -Interactive, run with UI.
- // this allows the user to adjust the exact security parameters of the
- // process and to monitor individual client objects. in this case, we will
- // eventually initialize COM (once the user selects security parameters
- // and hits the Initialize button) to use the apartment model in order
- // to synchronize calls with our UI.
- DialogBox(hInstance, MAKEINTRESOURCE(IDD_SECSVR), GetDesktopWindow(),
- (DLGPROC)ServerDialogProc);
-
- return 0;
- } // WinMain
-
- // EOF =======================================================================
-
-