windows-nt/Source/XPSP1/NT/net/irda/irprops/irprops.cpp
2020-09-26 16:20:57 +08:00

389 lines
9.7 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: irprops.cpp
//
//--------------------------------------------------------------------------
// irprops.cpp : Defines the initialization routines for the DLL.
//
#include "precomp.hxx"
#include "irprops.h"
#include "irpropsheet.h"
#include "debug.h"
BOOL InitInstance();
INT ExitInstance();
BOOL IsFirstInstance();
INT_PTR WINAPI DoPropertiesA(HWND hwnd, LPCSTR CmdLine);
INT_PTR WINAPI DoPropertiesW(HWND hwnd, LPCWSTR CmdLine);
HINSTANCE gHInst;
//
// This records the current active property sheet window handle created
// by this instance. It is set/reset by CIrPropSheet object.
//
HWND g_hwndPropSheet = NULL;
HANDLE g_hMutex = NULL;
BOOL g_bFirstInstance = TRUE;
//
// This records our registered message for inter-instances communications
// The message is registered in CIrpropsApp::InitInstance.
//
UINT g_uIPMsg;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern "C" {
BOOL APIENTRY
DllMain(HANDLE hDll,
DWORD dwReason,
LPVOID lpReserved)
{
IRINFO((_T("DllMain reason %x"), dwReason));
switch (dwReason) {
case DLL_PROCESS_ATTACH:
gHInst = (HINSTANCE) hDll;
return InitInstance();
break;
case DLL_PROCESS_DETACH:
return ExitInstance();
break;
case DLL_THREAD_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
default:
break;
}
return TRUE;
}
}
////////////////////////////////////////////////////////////////////////
//some globals
APPLETS IRApplet[NUM_APPLETS] = {
{IDI_IRPROPS, IDS_APPLETNAME, IDS_APPLETDESC}
};
/////////////////////////////////////////////////////////////////////////
// CPlApplet function for the control panel
//
LONG CALLBACK CPlApplet(
HWND hwndCPL,
UINT uMsg,
LPARAM lParam1,
LPARAM lParam2)
{
int i;
LPCPLINFO lpCPlInfo;
i = (int) lParam1;
IRINFO((_T("CplApplet message %x"), uMsg));
switch (uMsg)
{
case CPL_INIT: // first message, sent once
if (!IrPropSheet::IsIrDASupported()) {
HPSXA hpsxa;
//
// Check for any installed extensions.
//
hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, sc_szRegWireless, 8);
if (hpsxa) {
//
// We have extensions installed so we have to show the CPL,
// whether IRDA exists or not.
//
SHDestroyPropSheetExtArray(hpsxa);
return TRUE;
}
return FALSE;
}
return TRUE;
case CPL_GETCOUNT: // second message, sent once
return NUM_APPLETS;
break;
case CPL_INQUIRE: // third message, sent once per application
lpCPlInfo = (LPCPLINFO) lParam2;
lpCPlInfo->lData = 0;
lpCPlInfo->idIcon = IRApplet[i].icon;
lpCPlInfo->idName = IRApplet[i].namestring;
lpCPlInfo->idInfo = IRApplet[i].descstring;
break;
case CPL_STARTWPARMSA:
if (-1 == DoPropertiesA(hwndCPL, (LPCSTR)lParam2))
MsgBoxWinError(hwndCPL);
// return true so that we won't get CPL_DBLCLK.
return 1;
break;
case CPL_STARTWPARMSW:
if (-1 == DoPropertiesW(hwndCPL, (LPCWSTR)lParam2))
MsgBoxWinError(hwndCPL);
// return true so that we won't get CPL_DBLCLK.
return 1;
break;
case CPL_DBLCLK: // application icon double-clicked
if (-1 == DoPropertiesA(hwndCPL, (LPCSTR)lParam2))
MsgBoxWinError(hwndCPL);
return 1;
break;
case CPL_STOP: // sent once per application before CPL_EXIT
break;
case CPL_EXIT: // sent once before FreeLibrary is called
break;
default:
break;
}
return 0;
}
//
// This function presents the Wireless link property sheet.
// INPUT:
// hwndParent -- window handle to be used as parent window of
// the property sheet
// lpCmdLine -- optional command line
// 'n" (n in decimal) is start page number(zero-based).
// OUTPUT:
// Return value of PropertySheet API
INT_PTR
DoPropertiesW(
HWND hwndParent,
LPCWSTR lpCmdLine
)
{
INT_PTR Result;
INT StartPage;
IRINFO((_T("DoPropertiesW")));
//
// Assuming no start page was specified.
//
StartPage = -1;
//
// Command line specifies start page number
//
if (lpCmdLine)
{
// skip white chars
while (_T('\0') != *lpCmdLine &&
(_T(' ') == *lpCmdLine || _T('\t') == *lpCmdLine))
{
lpCmdLine++;
}
if (_T('0') <= *lpCmdLine && _T('9') >= *lpCmdLine)
{
StartPage = 0;
do
{
StartPage = StartPage * 10 + *lpCmdLine - _T('0');
lpCmdLine++;
} while (_T('0') <= *lpCmdLine && _T('9') >= *lpCmdLine);
}
}
if (!IsFirstInstance() || NULL != g_hwndPropSheet)
{
IRINFO((_T("Not the first instance")));
HWND hwndPropSheet = HWND_DESKTOP;
if (NULL == g_hwndPropSheet)
{
IRINFO((_T("No window created")));
//
// We are not the first instance. Look for the property sheet
// window created by the first instance.
//
EnumWindows(EnumWinProc, (LPARAM)&hwndPropSheet);
}
else
{
IRINFO((_T("Window active")));
//
// This is not the first call and we have a
// property sheet active(same process, multiple calls)
//
hwndPropSheet = g_hwndPropSheet;
}
if (HWND_DESKTOP != hwndPropSheet)
{
IRINFO((_T("Found the active property sheet.")));
//
// We found the active property sheet
//
// Select the new active page if necessary
//
if (-1 != StartPage)
PropSheet_SetCurSel(hwndPropSheet, NULL, StartPage);
//
// bring the property sheet to the foreground.
//
::SetForegroundWindow(hwndPropSheet);
}
Result = IDCANCEL;
}
else
{
IRINFO((_T("First instance, creating propertysheet")));
IrPropSheet PropSheet(gHInst, IDS_APPLETNAME, hwndParent, StartPage);
}
return Result;
}
//
// This is our callback function for EnumWindows API.
// It probes for each window handle to see if it is the property sheet
// window created by the previous instance. If it is, it returns
// the window handle in the provided buffer, lParam)
// Input:
// hWnd -- the window handle
// lParam -- (HWND *)
// Output:
// TRUE -- Let Windows continue to call us
// FALSE -- Stop Windows from calling us again
//
BOOL
CALLBACK
EnumWinProc(
HWND hWnd,
LPARAM lParam
)
{
//
// Verify with this window to see if it is the one we are looking for.
//
LRESULT lr;
lr = ::SendMessage(hWnd, g_uIPMsg, (WPARAM)IPMSG_SIGNATURECHECK,
(LPARAM)IPMSG_REQUESTSIGNATURE);
if (IPMSG_REPLYSIGNATURE == lr)
{
if (lParam)
{
// this is the one
*((HWND *)(lParam)) = hWnd;
}
//
// We are done with enumeration.
//
return FALSE;
}
return TRUE;
}
INT_PTR
DoPropertiesA(
HWND hwndParent,
LPCSTR lpCmdLine
)
{
WCHAR CmdLineW[MAX_PATH];
UINT Size;
if (!lpCmdLine)
return DoPropertiesW(hwndParent, NULL);
MultiByteToWideChar(CP_ACP, 0, lpCmdLine, -1, CmdLineW, sizeof(CmdLineW) / sizeof(WCHAR));
return DoPropertiesW(hwndParent, CmdLineW);
}
// This function creates and displays a message box for the given
// win32 error(or last error)
// INPUT:
// hwndParent -- the parent window for the will-be-created message box
// Type -- message styles(MB_xxxx)
// Error -- Error code. If the value is 0
// GetLastError() will be called to retreive the
// real error code.
// CaptionId -- optional string id for caption
// OUTPUT:
// the value return from MessageBox
//
int
MsgBoxWinError(
HWND hwndParent,
DWORD Options,
DWORD Error,
int CaptionId
)
{
if (ERROR_SUCCESS == Error)
Error = GetLastError();
// nonsense to report success!
if (ERROR_SUCCESS == Error)
return IDOK;
TCHAR szMsg[MAX_PATH];
TCHAR szCaption[MAX_PATH];
if (!CaptionId)
CaptionId = IDS_APPLETNAME;
::LoadString(gHInst, CaptionId, szCaption, sizeof(szCaption) / sizeof(TCHAR));
FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, Error, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
szMsg, sizeof(szMsg) / sizeof(TCHAR), NULL);
return MessageBox(hwndParent, szMsg, szCaption, Options);
}
BOOL InitInstance()
{
//
// Try to create a named mutex. This give us a clue
// if we are the first instance. We will not close
// the mutex until exit.
//
g_hMutex = CreateMutex(NULL, TRUE, SINGLE_INST_MUTEX);
if (g_hMutex)
{
g_bFirstInstance = ERROR_ALREADY_EXISTS != GetLastError();
//
// register a message for inter-instances communication
//
g_uIPMsg = RegisterWindowMessage(WIRELESSLINK_INTERPROCESSMSG);
SHFusionInitializeFromModuleID(gHInst, 124);
return TRUE;
}
return FALSE;
}
BOOL ExitInstance()
{
if (g_hMutex)
{
CloseHandle(g_hMutex);
g_hMutex = NULL;
}
SHFusionUninitialize();
return TRUE;
}
BOOL IsFirstInstance()
{
return g_bFirstInstance;
}