|
|
/*******************************************************************************
* * (C) COPYRIGHT MICROSOFT CORP., 1993-1994 * * TITLE: PCCARD.C * * VERSION: 1.0 * * AUTHOR: RAL * * DATE: 11/01/94 * ******************************************************************************** * * CHANGE LOG: * * DATE REV DESCRIPTION * ----------- --- ------------------------------------------------------------- * Nov. 11, 94 RAL Original * Oct 23, 95 Shawnb UNICODE enabled * *******************************************************************************/
#include "stdafx.h"
#include "systray.h"
#define PCMCIAMENU_PROPERTIES 100
#define PCMCIAMENU_DISABLE 101
#define PCMCIAMENU_SOCKET 200
extern HANDLE g_hPCCARD; extern HINSTANCE g_hInstance;
static BOOL g_bPCMCIAEnabled = FALSE; static BOOL g_bPCMCIAIconShown = FALSE; static HICON g_hPCMCIAIcon = NULL;
#define MAX_DEVNODES 20
static DWORD g_aDevnodes[MAX_DEVNODES]; static BYTE g_aSktState[MAX_DEVNODES] = {0}; static UINT g_numskts = 0; static DWORD g_PCMCIAFlags = 0; static TCHAR g_szDevNodeKeyFmt[] = REGSTR_PATH_DYNA_ENUM TEXT ("\\%X"); static const TCHAR g_szEnumKeyPrefix[] = REGSTR_PATH_ENUM TEXT ("\\"); static const TCHAR g_szPCMCIAFlags[] = REGSTR_VAL_SYSTRAYPCCARDFLAGS; static const TCHAR g_szClass[] = REGSTR_VAL_CLASS; static const TCHAR g_szModemClass[] = REGSTR_KEY_MODEM_CLASS; #if NOTYET
static const TCHAR g_szDiskDriveClass[] = REGSTR_KEY_DISKDRIVE_CLASS; #endif
#define SKTSTATE_GOODEJECT 1
#define SKTSTATE_SHOULDWARN 2
#define SKTSTATE_TYPEKNOWN 4
HKEY OpenDevnodeDynKey(DWORD dwDevnode) { TCHAR szScratch[MAX_PATH]; HKEY hkDyn = NULL;
wsprintf(szScratch, g_szDevNodeKeyFmt, dwDevnode); if (RegOpenKey(HKEY_DYN_DATA, szScratch, &hkDyn) != ERROR_SUCCESS) { return(NULL); } return hkDyn; }
UINT GetDynInfo(DWORD dwDevNode, LPCTSTR lpszValName, LPVOID lpBuffer, UINT cbBuffer) { UINT cbSize = 0; HKEY hkDyn = OpenDevnodeDynKey(dwDevNode);
if (hkDyn) { if (RegQueryValueEx(hkDyn, lpszValName, NULL, NULL, lpBuffer, &cbBuffer) == ERROR_SUCCESS) { cbSize = cbBuffer; } RegCloseKey(hkDyn); } return(cbSize); }
HKEY OpenDevnodeHwKey(DWORD dwDevnode) { TCHAR szScratch[MAX_PATH]; HKEY hkDyn, hkHw = NULL; UINT cbSize; UINT cchOffset;
if ((hkDyn = OpenDevnodeDynKey(dwDevnode)) == NULL) { return(NULL); } lstrcpy(szScratch, g_szEnumKeyPrefix);
cbSize = sizeof(szScratch) - sizeof(g_szEnumKeyPrefix); cchOffset = ARRAYSIZE(g_szEnumKeyPrefix) - 1;
if (RegQueryValueEx(hkDyn, REGSTR_VAL_HARDWARE_KEY, NULL, NULL, (LPSTR)&(szScratch[cchOffset]), &cbSize) == ERROR_SUCCESS) { if (RegOpenKey(HKEY_LOCAL_MACHINE, szScratch, &hkHw) != ERROR_SUCCESS) { hkHw = NULL; } } RegCloseKey(hkDyn); return(hkHw); }
UINT GetHwInfo(DWORD dwDevNode, LPCTSTR lpszValName, LPVOID lpBuffer, UINT cbBuffer) { UINT cbSize = 0; HKEY hkHw = OpenDevnodeHwKey(dwDevNode);
if (hkHw) { if (RegQueryValueEx(hkHw, lpszValName, NULL, NULL, lpBuffer, &cbBuffer) == ERROR_SUCCESS) { cbSize = cbBuffer; } RegCloseKey(hkHw); } return(cbSize); }
void UpdateSktTypes() { UINT i; TCHAR szClassName[32];
for (i = 0; i < g_numskts; i++) { if (g_aSktState[i] == 0 && g_aDevnodes[i] != 0) { if (GetHwInfo(g_aDevnodes[i], g_szClass, szClassName, sizeof(szClassName))) { g_aSktState[i] |= SKTSTATE_TYPEKNOWN; if (lstrcmpi(g_szModemClass, szClassName) != 0) { g_aSktState[i] |= SKTSTATE_SHOULDWARN; } } } } }
void UpdateSocketInfo() { UINT cbReturned; if (DeviceIoControl(g_hPCCARD, PCCARD_IOCTL_GET_DEVNODES, NULL, 0, g_aDevnodes, sizeof(g_aDevnodes), &cbReturned, NULL)) { g_numskts = cbReturned / 4; } else { g_numskts = 0; } UpdateSktTypes(); }
void UpdateGlobalFlags() { HKEY hk; if (RegOpenKey(HKEY_CURRENT_USER, REGSTR_PATH_SYSTRAY, &hk) == ERROR_SUCCESS) { UINT cb = sizeof(g_PCMCIAFlags); if (RegQueryValueEx(hk, g_szPCMCIAFlags, NULL, NULL, (LPSTR)(&g_PCMCIAFlags), &cb) != ERROR_SUCCESS) { g_PCMCIAFlags = 0; }
RegCloseKey(hk); } }
BOOL PCMCIA_Init(HWND hWnd) { if (g_hPCCARD == INVALID_HANDLE_VALUE) { g_hPCCARD = CreateFile(TEXT ("\\\\.\\PCCARD"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); UpdateGlobalFlags(); }
return(g_hPCCARD != INVALID_HANDLE_VALUE); }
//
// NOTE: This function expects the caller to have called UpdateSocketInfo
// prior to calling it.
//
void PCMCIA_UpdateStatus(HWND hWnd, BOOL bShowIcon, DWORD dnRemove) { if (bShowIcon) { UINT i; bShowIcon = FALSE; // Assume no devnodes
for (i = 0; i < g_numskts; i++) { if (g_aDevnodes[i] != 0 && g_aDevnodes[i] != dnRemove) { bShowIcon = TRUE; break; } } }
if (bShowIcon != g_bPCMCIAIconShown) { g_bPCMCIAIconShown = bShowIcon; if (bShowIcon) { LPTSTR pStr = LoadDynamicString(IDS_PCMCIATIP); g_hPCMCIAIcon = LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_PCMCIA), IMAGE_ICON, 16, 16, 0); SysTray_NotifyIcon(hWnd, STWM_NOTIFYPCMCIA, NIM_ADD, g_hPCMCIAIcon, pStr); DeleteDynamicString(pStr); } else { SysTray_NotifyIcon(hWnd, STWM_NOTIFYPCMCIA, NIM_DELETE, NULL, NULL); if (g_hPCMCIAIcon) { DestroyIcon(g_hPCMCIAIcon); } } } }
#define DEVNODE_NOT_IN_LIST -1
int FindSocketIndex(DWORD dn) { int i; for (i = 0; i < (int)g_numskts; i++) { if (g_aDevnodes[i] == dn) { return(i); } } return(DEVNODE_NOT_IN_LIST); }
void PCMCIA_DeviceChange(HWND hDlg, WPARAM wParam, LPARAM lParam) { int i;
#define lpdbd ((PDEV_BROADCAST_DEVNODE)lParam)
#define DN_STARTED 0x00000008 // WARNING KEEP THIS IN SYNC WITH CONFIGMG.H
if ((wParam != DBT_DEVICEREMOVEPENDING && wParam != DBT_DEVICEARRIVAL && wParam != DBT_DEVICEREMOVECOMPLETE) || lpdbd->dbcd_devicetype != DBT_DEVTYP_DEVNODE) { return; }
switch (wParam) { case DBT_DEVICEREMOVEPENDING: // Query remove succeeded
i = FindSocketIndex(lpdbd->dbcd_devnode); if (i != DEVNODE_NOT_IN_LIST) { g_aSktState[i] |= SKTSTATE_GOODEJECT; } break;
case DBT_DEVICEARRIVAL: UpdateSocketInfo(); i = FindSocketIndex(lpdbd->dbcd_devnode); if (i != DEVNODE_NOT_IN_LIST) { g_aSktState[i] = 0; UpdateSktTypes(); PCMCIA_UpdateStatus(hDlg, TRUE, 0); } break;
case DBT_DEVICEREMOVECOMPLETE: { ULONG Status = 0L; ULONG Size = sizeof(ULONG); TCHAR szDevNode[REGSTR_MAX_VALUE_LENGTH]; HKEY hkDevDyna; wsprintf(szDevNode, TEXT ("%s\\%8X"),REGSTR_PATH_DYNA_ENUM,lpdbd->dbcd_devnode); if (RegOpenKey( HKEY_DYN_DATA, szDevNode, &hkDevDyna ) == ERROR_SUCCESS) { RegQueryValueEx( hkDevDyna, REGSTR_VAL_STATUS, 0, NULL, (LPSTR)&Status, &Size ); RegCloseKey(hkDevDyna); } if (Status & DN_STARTED) { i = FindSocketIndex(lpdbd->dbcd_devnode); if (i != DEVNODE_NOT_IN_LIST) { //
// Check to see if we're supposed to warn the user about this
// eject. Only warn if NOT good eject and class is one we warn
// about.
//
BOOL fWarnUser = (g_aSktState[i] & (SKTSTATE_SHOULDWARN | SKTSTATE_GOODEJECT)) == SKTSTATE_SHOULDWARN; g_aSktState[i] = 0; UpdateSocketInfo(); PCMCIA_UpdateStatus(hDlg, TRUE, lpdbd->dbcd_devnode); if (fWarnUser) { // Make sure the user did not turn this off earlier
UpdateGlobalFlags(); if (!(g_PCMCIAFlags & PCMCIA_REGFLAG_NOWARN)) { const TCHAR szOpen[] = TEXT ("open"); const TCHAR szRunDLL[] = TEXT ("RUNDLL32.EXE"); const TCHAR szParams[] = TEXT ("RUNDLL mspcic.dll,EjectWarningDlg"); ShellExecute(NULL, szOpen, szRunDLL, szParams, NULL, SW_SHOW); } } } } break; } } #undef lpdbd
}
//
// Called at init time and whenever services are enabled/disabled.
// Returns false if PCMCIA services are not active.
//
BOOL PCMCIA_CheckEnable(HWND hWnd, BOOL bSvcEnabled) { BOOL bEnable = bSvcEnabled && PCMCIA_Init(hWnd);
if (bEnable != g_bPCMCIAEnabled) { g_bPCMCIAEnabled = bEnable; UpdateSocketInfo(); PCMCIA_UpdateStatus(hWnd, bEnable, 0); if (!bEnable) { CloseIfOpen(&g_hPCCARD); } }
return(bEnable); }
/*----------------------------------------------------------------------------
* PCMCIA_CreateMenu() * * build a menu containing all sockets. * *----------------------------------------------------------------------------*/
//static CRITICAL_SECTION csMenu;
static HMENU _hMenu[2] = {0};
HMENU PCMCIA_CreateMenu(LONG l) { //EnterCriticalSection(&csMenu);
if (l > 0) { if (_hMenu[1] == NULL) { HMENU hmenu = _hMenu[l] = CreatePopupMenu(); LPTSTR lpszMenu;
if ((lpszMenu = LoadDynamicString(IDS_PCCARDMENU1)) != NULL) { AppendMenu(hmenu,MF_STRING,PCMCIAMENU_PROPERTIES,lpszMenu); DeleteDynamicString(lpszMenu); } if ((lpszMenu = LoadDynamicString(IDS_PCCARDMENU2)) != NULL) { AppendMenu(hmenu,MF_STRING,PCMCIAMENU_DISABLE,lpszMenu); DeleteDynamicString(lpszMenu); } SetMenuDefaultItem(hmenu,PCMCIAMENU_PROPERTIES,FALSE); } } else { HMENU hMenu;
if (_hMenu[0]) { DestroyMenu(_hMenu[0]); }
hMenu = _hMenu[0] = CreatePopupMenu();
if (g_hPCCARD != INVALID_HANDLE_VALUE) { TCHAR szDesc[80]; LPTSTR lpszMenuText; UINT i;
UpdateSocketInfo(); for (i = 0; i < g_numskts; i++) { if (g_aDevnodes[i] && GetHwInfo(g_aDevnodes[i], REGSTR_VAL_DEVDESC, szDesc, sizeof(szDesc))) { #if NOTYET
DWORD dwChild; TCHAR szClassName[32]; TCHAR szDriveLetters[32];
if (GetDynInfo(g_aDevnodes[i], REGSTR_VAL_CHILD, &dwChild, sizeof(dwChild)) && GetHwInfo(dwChild, g_szClass, szClassName, sizeof(szClassName)) && lstrcmpi(g_szDiskDriveClass, szClassName) == 0 && GetHwInfo(dwChild, REGSTR_VAL_CURDRVLET, szDriveLetters, sizeof(szDriveLetters)) && lstrlen(szDriveLetters) > 0) { lpszMenuText = LoadDynamicString(IDS_EJECTFMTDISKDRIVE, szDesc, szDriveLetters[0]); } else #endif
{ lpszMenuText = LoadDynamicString(IDS_EJECTFMT, szDesc); }
if (lpszMenuText) { AppendMenu(hMenu,MF_STRING,PCMCIAMENU_SOCKET+i,lpszMenuText); DeleteDynamicString(lpszMenuText); } } } } }
//LeaveCriticalSection(&csMenu);
return _hMenu[l]; }
void PCMCIA_Menu(HWND hwnd, UINT uMenuNum, UINT uButton) { POINT pt; UINT iCmd;
SetForegroundWindow(hwnd); GetCursorPos(&pt); iCmd = TrackPopupMenu(PCMCIA_CreateMenu(uMenuNum), uButton | TPM_RETURNCMD | TPM_NONOTIFY, pt.x, pt.y, 0, hwnd, NULL); if (iCmd >= PCMCIAMENU_SOCKET) { const TCHAR szOpen[] = TEXT ("open"); const TCHAR szRunDLL[] = TEXT ("RUNDLL32.EXE"); LPTSTR lpszCommand = LoadDynamicString(IDS_RUNEJECT, iCmd-PCMCIAMENU_SOCKET); if (lpszCommand == NULL) return; ShellExecute(NULL, szOpen, szRunDLL, lpszCommand, NULL, SW_SHOW); DeleteDynamicString(lpszCommand); } else { switch (iCmd) { case PCMCIAMENU_PROPERTIES: SysTray_RunProperties(IDS_RUNPCMCIAPROPERTIES); break;
case PCMCIAMENU_DISABLE: PostMessage(hwnd, STWM_ENABLESERVICE, STSERVICE_PCMCIA, FALSE); break; } } }
void PCMCIA_Notify(HWND hwnd, WPARAM wParam, LPARAM lParam) { switch (lParam) { case WM_RBUTTONUP: PCMCIA_Menu(hwnd, 1, TPM_RIGHTBUTTON); break;
case WM_LBUTTONDOWN: SetTimer(hwnd, PCMCIA_TIMER_ID, GetDoubleClickTime()+100, NULL); break;
case WM_LBUTTONDBLCLK: KillTimer(hwnd, PCMCIA_TIMER_ID); SysTray_RunProperties(IDS_RUNPCMCIAPROPERTIES); break; } }
void PCMCIA_Timer(HWND hwnd) { KillTimer(hwnd, PCMCIA_TIMER_ID); PCMCIA_Menu(hwnd, 0, TPM_LEFTBUTTON); }
|