Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/nt/procrun/src/gui.c URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/nt/procrun/src/gui.c?rev=980662&view=auto ============================================================================== --- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/nt/procrun/src/gui.c (added) +++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/nt/procrun/src/gui.c Fri Jul 30 06:50:12 2010 @@ -0,0 +1,1025 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apxwin.h" +#include "private.h" + +#define BALLON_TIMEOUT 1000 +/* Offset for listview dots */ +#define DOTOFFSET 0 + +static HMODULE _st_sys_riched; +static APXGUISTORE _st_sys_gui; +static HIMAGELIST _st_sel_users_il = NULL; +static WNDPROC _st_sel_users_lvm; + +typedef struct PROGRESS_DLGPARAM { + LPCTSTR szHead; + LPCWSTR szText; + LPVOID cbData; + LPAPXFNCALLBACK fnCb; + HANDLE hThread; + HWND hDialog; +} PROGRESS_DLGPARAM, *LPPROGRESS_DLGPARAM; + +APXLVITEM lvUsers[] = { + { 0, FALSE, 180, 180, LVCFMT_LEFT, TEXT("User") }, + { 0, TRUE, 180, 180, LVCFMT_LEFT, TEXT("Full Name") }, + { 0, TRUE, 235, 235, LVCFMT_LEFT, TEXT("Comment") } +}; + + +#define NUMLVUSERS (sizeof(lvUsers) / sizeof(lvUsers[0])) + +static UINT __getWhellScrollLines() +{ + HWND hdlMsWheel; + UINT ucNumLines = 3; /* 3 is the default */ + UINT uiMsh_MsgScrollLines; + + APX_OSLEVEL os = apxGetOsLevel(); + /* In Windows 9x & Windows NT 3.51, query MSWheel for the + * number of scroll lines. In Windows NT 4.0 and later, + * use SystemParametersInfo. + */ + if (os < APX_WINVER_NT_4) { + hdlMsWheel = FindWindow(MSH_WHEELMODULE_CLASS, + MSH_WHEELMODULE_TITLE); + if (hdlMsWheel) { + uiMsh_MsgScrollLines = RegisterWindowMessage(MSH_SCROLL_LINES); + if (uiMsh_MsgScrollLines) + ucNumLines = (int)SendMessage(hdlMsWheel, + uiMsh_MsgScrollLines, + 0, 0); + } + } + else { + SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, + &ucNumLines, 0); + } + return ucNumLines; +} + +/* Initialize the Gui + */ +LPAPXGUISTORE apxGuiInitialize(WNDPROC lpfnWndProc, LPCTSTR szAppName) +{ + INITCOMMONCONTROLSEX stCmn; + WNDCLASSEX wcex; + + _st_sys_gui.hInstance = GetModuleHandleA(NULL); + GetStartupInfo(&_st_sys_gui.stStartupInfo); + + lstrcpy(_st_sys_gui.szWndClass, szAppName); + lstrcat(_st_sys_gui.szWndClass, TEXT("_CLASS")); + + /* Single instance or general application mutex */ + lstrcpy(_st_sys_gui.szWndMutex, szAppName); + lstrcat(_st_sys_gui.szWndMutex, TEXT("_MUTEX")); + + + stCmn.dwSize = sizeof(INITCOMMONCONTROLSEX); + stCmn.dwICC = ICC_WIN95_CLASSES | ICC_USEREX_CLASSES | ICC_COOL_CLASSES | + ICC_INTERNET_CLASSES | ICC_PAGESCROLLER_CLASS | ICC_BAR_CLASSES; + + InitCommonControlsEx(&stCmn); + + _st_sys_riched = LoadLibraryA("RICHED32.DLL"); + _st_sys_gui.hIconSm = LoadImage(_st_sys_gui.hInstance, MAKEINTRESOURCE(IDI_MAINICON), + IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + _st_sys_gui.hIcon = LoadImage(_st_sys_gui.hInstance, MAKEINTRESOURCE(IDI_MAINICON), + IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR); + _st_sys_gui.hIconHg = LoadImage(_st_sys_gui.hInstance, MAKEINTRESOURCE(IDI_MAINICON), + IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR); + _st_sys_gui.hAccel = LoadAccelerators(_st_sys_gui.hInstance, + MAKEINTRESOURCE(IDC_APPLICATION)); + _st_sys_gui.stState.rcPosition.left = CW_USEDEFAULT; + _st_sys_gui.stState.rcPosition.top = CW_USEDEFAULT; + _st_sys_gui.stState.rcPosition.right = CW_USEDEFAULT; + _st_sys_gui.stState.rcPosition.bottom = CW_USEDEFAULT; + + _st_sys_gui.nWhellScroll = __getWhellScrollLines(); + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = 0; + wcex.lpfnWndProc = lpfnWndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = _st_sys_gui.hInstance; + wcex.hIcon = _st_sys_gui.hIcon; + wcex.hIconSm = _st_sys_gui.hIconSm; + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_INACTIVEBORDER+1); + wcex.lpszMenuName = MAKEINTRESOURCE(IDC_APPLICATION); + wcex.lpszClassName = _st_sys_gui.szWndClass; + + if (RegisterClassEx(&wcex)) { + return &_st_sys_gui; + } + else + return NULL; +} + + +BOOL apxCenterWindow(HWND hwndChild, HWND hwndParent) +{ + RECT rChild, rParent, rWorkArea; + int wChild, hChild, wParent, hParent; + int xNew, yNew; + BOOL bResult; + + /* Get the Height and Width of the child window */ + GetWindowRect(hwndChild, &rChild); + wChild = rChild.right - rChild.left; + hChild = rChild.bottom - rChild.top; + + /* Get the Height and Width of the parent window */ + GetWindowRect(hwndParent, &rParent); + wParent = rParent.right - rParent.left; + hParent = rParent.bottom - rParent.top; + + if (wParent < wChild && hParent < hChild) { + GetWindowRect(GetDesktopWindow(), &rParent); + wParent = rParent.right - rParent.left; + hParent = rParent.bottom - rParent.top; + } + /* Get the limits of the 'workarea' */ + bResult = SystemParametersInfo(SPI_GETWORKAREA, sizeof(RECT), + &rWorkArea, 0); + if (!bResult) { + rWorkArea.left = rWorkArea.top = 0; + rWorkArea.right = GetSystemMetrics(SM_CXSCREEN); + rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN); + } + + /* Calculate new X position, then adjust for workarea */ + xNew = rParent.left + ((wParent - wChild) /2); + if (xNew < rWorkArea.left) + xNew = rWorkArea.left; + else if ((xNew+wChild) > rWorkArea.right) + xNew = rWorkArea.right - wChild; + + /* Calculate new Y position, then adjust for workarea */ + yNew = rParent.top + ((hParent - hChild) /2); + if (yNew < rWorkArea.top) + yNew = rWorkArea.top; + else if ((yNew+hChild) > rWorkArea.bottom) + yNew = rWorkArea.bottom - hChild; + + /* Set it, and return */ + return SetWindowPos(hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER); +} + +/*************************************************************************** + * Function: LoadRcString + * + * Purpose: Loads a resource string from string table and returns a pointer + * to the string. + * + * Parameters: wID - resource string id + * + */ + +/** Load the resource string with the ID given, and return a + * pointer to it. Notice that the buffer is common memory so + * the string must be used before this call is made a second time. + */ + +LPSTR apxLoadResourceA(UINT wID, UINT nBuf) + +{ + static CHAR szBuf[4][SIZ_BUFLEN]; + if (nBuf > 4) + return ""; + if (LoadStringA(_st_sys_gui.hInstance,wID ,szBuf[nBuf], SIZ_BUFMAX) > 0) + return szBuf[nBuf]; + else + return ""; +} + +LPWSTR apxLoadResourceW(UINT wID, UINT nBuf) + +{ + static WCHAR szBuf[4][SIZ_BUFLEN]; + if (nBuf > 4) + return L""; + if (LoadStringW(_st_sys_gui.hInstance,wID ,szBuf[nBuf], SIZ_BUFMAX) > 0) + return szBuf[nBuf]; + else + return L""; +} + +/* Add the item to the Try popup menu + */ +void apxAppendMenuItem(HMENU hMenu, UINT idMenu, LPCTSTR szName, + BOOL bDefault, BOOL bEnabled) +{ + MENUITEMINFO miI; + + AplZeroMemory(&miI, sizeof(MENUITEMINFO)); + miI.cbSize = sizeof(MENUITEMINFO); + miI.fMask = MIIM_TYPE | MIIM_STATE; + if (szName && lstrlen(szName)) { + miI.fMask |= MIIM_ID; + miI.fType = MFT_STRING; + miI.wID = idMenu; + if (bDefault) + miI.fState = MFS_DEFAULT; + if (!bEnabled) + miI.fState |= MFS_DISABLED; + miI.dwTypeData = (LPTSTR)szName; + } + else { + miI.fType = MFT_SEPARATOR; + } + InsertMenuItem(hMenu, idMenu, FALSE, &miI); +} + +/* Add the item to the Try popup menu + */ +void apxAppendMenuItemBmp(HMENU hMenu, UINT idMenu, LPCTSTR szName) +{ + MENUITEMINFO miI; + HBITMAP hBmp; + + hBmp = LoadImage(_st_sys_gui.hInstance, szName, + IMAGE_BITMAP, 0, 0, + LR_CREATEDIBSECTION | LR_SHARED); + + AplZeroMemory(&miI, sizeof(MENUITEMINFO)); + miI.cbSize = sizeof(MENUITEMINFO); + miI.fMask = MIIM_BITMAP | MFT_MENUBARBREAK; + + miI.hbmpItem = hBmp; + InsertMenuItem(hMenu, idMenu, FALSE, &miI); +} + +/* Try icon helper + * Add/Change/Delete icon from the windows try. + */ +void apxManageTryIconA(HWND hWnd, DWORD dwMessage, LPCSTR szInfoTitle, + LPCSTR szInfo, HICON hIcon) +{ + static BOOL inTry = FALSE; + NOTIFYICONDATAA nId; + AplZeroMemory(&nId, sizeof(NOTIFYICONDATAA)); + + nId.cbSize = sizeof(NOTIFYICONDATAA); + nId.hWnd = hWnd; + nId.uID = 0xFF; + nId.uCallbackMessage = WM_TRAYMESSAGE; + nId.uFlags = NIF_MESSAGE; + + if (dwMessage == NIM_ADD && inTry) + return; + if (dwMessage != NIM_DELETE) { + nId.uFlags |= NIF_ICON; + if (! szInfoTitle) { + nId.uFlags |= NIF_TIP; + lstrcpynA(nId.szTip, szInfo, 63); + } + else if (szInfo) { + nId.uFlags |= NIF_INFO; + lstrcpynA(nId.szInfo, szInfo, 255); + lstrcpynA(nId.szInfoTitle, szInfoTitle, 63); + nId.dwInfoFlags = NIIF_INFO; + nId.uTimeout = BALLON_TIMEOUT; + } + + nId.hIcon = hIcon ? hIcon : _st_sys_gui.hIconSm; + inTry = TRUE; + } + else + inTry = FALSE; + + Shell_NotifyIconA(dwMessage, &nId); +} + +void apxManageTryIconW(HWND hWnd, DWORD dwMessage, LPCWSTR szInfoTitle, + LPCWSTR szInfo, HICON hIcon) +{ + + NOTIFYICONDATAW nId; + AplZeroMemory(&nId, sizeof(NOTIFYICONDATAW)); + + nId.cbSize = sizeof(NOTIFYICONDATAW); + nId.hWnd = hWnd; + nId.uID = 0xFF; + nId.uCallbackMessage = WM_TRAYMESSAGE; + nId.uFlags = NIF_MESSAGE; + + if (dwMessage != NIM_DELETE) { + nId.uFlags |= NIF_ICON; + if (! szInfoTitle) { + nId.uFlags |= NIF_TIP; + lstrcpynW(nId.szTip, szInfo, 63); + } + else if (szInfo) { + nId.uFlags |= NIF_INFO; + lstrcpynW(nId.szInfo, szInfo, 255); + lstrcpynW(nId.szInfoTitle, szInfoTitle, 63); + nId.dwInfoFlags = NIIF_INFO; + nId.uTimeout = BALLON_TIMEOUT; + } + nId.hIcon = hIcon ? hIcon : _st_sys_gui.hIconSm; + } + + Shell_NotifyIconW(dwMessage, &nId); +} + +static void __apxShellAbout(HWND hWnd) +{ + TCHAR szApplication[512]; + + wsprintf(szApplication , TEXT("About - %s#Windows"), + apxLoadResource(IDS_APPLICATION, 0)); + + ShellAbout(hWnd, szApplication, + apxLoadResource(IDS_APPDESCRIPTION, 1), + _st_sys_gui.hIconHg); +} + + +static LRESULT CALLBACK __apxAboutDlgProc(HWND hDlg, UINT uMsg, + WPARAM wParam, LPARAM lParam) +{ + static HWND hRich = NULL; + static POINT ptScroll; + HRSRC hRsrc; + HGLOBAL hGlob; + LPSTR szTxt; + + switch (uMsg) { + case WM_INITDIALOG: + apxCenterWindow(hDlg, _st_sys_gui.hMainWnd); + hRich = GetDlgItem(hDlg, IDC_LICENSE); + hRsrc = FindResource(GetModuleHandleA(NULL), MAKEINTRESOURCE(IDR_LICENSE), + TEXT("RTF")); + hGlob = LoadResource(GetModuleHandleA(NULL), hRsrc); + szTxt = (LPSTR)LockResource(hGlob); + + SendMessageA(hRich, WM_SETTEXT, 0, (LPARAM)szTxt); + SetDlgItemText(hDlg, IDC_ABOUTAPP, apxLoadResource(IDS_APPFULLNAME, 0)); + ptScroll.x = 0; + ptScroll.y = 0; + return TRUE; + break; + case WM_COMMAND: + if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + else if (LOWORD(wParam) == IAB_SYSINF) + __apxShellAbout(hDlg); + break; + case WM_MOUSEWHEEL: + { + int nScroll, nLines; + if ((SHORT)HIWORD(wParam) < 0) + nScroll = _st_sys_gui.nWhellScroll; + else + nScroll = _st_sys_gui.nWhellScroll * (-1); + ptScroll.y += (nScroll * 11); + if (ptScroll.y < 0) + ptScroll.y = 0; + nLines = (int)SendMessage(hRich, EM_GETLINECOUNT, 0, 0) + 1; + if (ptScroll.y / 11 > nLines) + ptScroll.y = nLines * 11; + SendMessage(hRich, EM_SETSCROLLPOS, 0, (LPARAM)&ptScroll); + } + break; + + } + return FALSE; +} + +void apxAboutBox(HWND hWnd) +{ + DialogBox(_st_sys_gui.hInstance, + MAKEINTRESOURCE(IDD_ABOUTBOX), + hWnd, + (DLGPROC)__apxAboutDlgProc); +} + +static DWORD WINAPI __apxProgressWorkerThread(LPVOID lpParameter) +{ + LPPROGRESS_DLGPARAM lpDlgParam = (LPPROGRESS_DLGPARAM)lpParameter; + + (*lpDlgParam->fnCb)(NULL, WM_USER+1, 0, (LPARAM)lpDlgParam->hDialog); + CloseHandle(lpDlgParam->hThread); + ExitThread(0); + return 0; +} + +static LRESULT CALLBACK __apxProgressDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LPPROGRESS_DLGPARAM lpDlgParam; + DWORD dwId; + switch (uMsg) { + case WM_INITDIALOG: + lpDlgParam = (LPPROGRESS_DLGPARAM)lParam; + apxCenterWindow(hDlg, _st_sys_gui.hMainWnd); + if (lpDlgParam && lpDlgParam->szHead && lpDlgParam->szText) { + SetDlgItemText(hDlg, IDDP_HEAD, lpDlgParam->szHead); + SetDlgItemTextW(hDlg, IDDP_TEXT, lpDlgParam->szText); + } + lpDlgParam->hDialog = hDlg; + lpDlgParam->hThread = CreateThread(NULL, 0, __apxProgressWorkerThread, + lpDlgParam, 0, &dwId); + break; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + break; + } + break; + case WM_USER+1: + SendMessage(GetDlgItem(hDlg, IDDP_PROGRESS), PBM_STEPIT, 0, 0); + break; + } + return FALSE; +} + +int apxProgressBox(HWND hWnd, LPCTSTR szHeader, + LPCWSTR szText, + LPAPXFNCALLBACK fnProgressCallback, + LPVOID cbData) +{ + PROGRESS_DLGPARAM dlgParam; + int rv; + + dlgParam.szHead = szHeader; + dlgParam.szText = szText; + dlgParam.cbData = cbData; + dlgParam.fnCb = fnProgressCallback; + dlgParam.hThread = NULL; + rv = (int)DialogBoxParam(_st_sys_gui.hInstance, + MAKEINTRESOURCE(IDD_PROGRESS), + hWnd, + (DLGPROC)__apxProgressDlgProc, + (LPARAM)&dlgParam); + return rv; +} + +BOOL apxYesNoMessage(LPCTSTR szTitle, LPCTSTR szMessage, BOOL bStop) +{ + UINT uType = MB_YESNO; + int rv; + + if (bStop) + uType |= MB_DEFBUTTON2 | MB_ICONEXCLAMATION; + else + uType |= MB_DEFBUTTON1 | MB_ICONQUESTION; + + rv = MessageBox(_st_sys_gui.hMainWnd, szMessage, szTitle, uType); + + return (rv == IDYES); +} + +LPWSTR apxGetDlgTextW(APXHANDLE hPool, HWND hDlg, int nIDDlgItem) +{ + DWORD l, n; + LPWSTR szT = NULL; + + l = (DWORD)SendMessageW(GetDlgItem(hDlg, nIDDlgItem), WM_GETTEXTLENGTH, 0, 0); + if (l > 0) { + szT = apxPoolAlloc(hPool, (l + 1) * sizeof(WCHAR)); + n = GetDlgItemTextW(hDlg, nIDDlgItem, szT, l + 1); + if (n == 0) { + apxFree(szT); + szT = NULL; + } + } + return szT; +} + +LPSTR apxGetDlgTextA(APXHANDLE hPool, HWND hDlg, int nIDDlgItem) +{ + DWORD l, n; + LPSTR szT = NULL; + + l = (DWORD)SendMessageA(GetDlgItem(hDlg, nIDDlgItem), WM_GETTEXTLENGTH, 0, 0); + if (l > 0) { + szT = apxPoolAlloc(hPool, (l + 1)); + n = GetDlgItemTextA(hDlg, nIDDlgItem, szT, l + 1); + if (n == 0) { + apxFree(szT); + szT = NULL; + } + } + return szT; +} + +/* Browse for folder dialog. + */ +LPSTR apxBrowseForFolderA(HWND hWnd, LPCSTR szTitle, LPCSTR szName) +{ + BROWSEINFOA bi; + LPITEMIDLIST il, ir; + LPMALLOC pMalloc; + CHAR szPath[MAX_PATH+1]; + LPSTR rv = NULL; + + AplZeroMemory(&bi, sizeof(BROWSEINFOW)); + SHGetSpecialFolderLocation(hWnd, CSIDL_DRIVES, &il); + bi.lpszTitle = szTitle; + bi.pszDisplayName = szPath; + bi.hwndOwner = hWnd; + bi.ulFlags = BIF_EDITBOX; + bi.lpfn = NULL; + bi.lParam = 0; + bi.iImage = 0; + bi.pidlRoot = il; + + if ((ir = SHBrowseForFolderA(&bi)) != NULL) { + if (SHGetPathFromIDListA(ir, szPath)) + rv = apxStrdupA(szPath); + } + if (SHGetMalloc(&pMalloc)) { + pMalloc->lpVtbl->Free(pMalloc, il); + pMalloc->lpVtbl->Release(pMalloc); + } + + return rv; +} + +LPWSTR apxBrowseForFolderW(HWND hWnd, LPCWSTR szTitle, LPCWSTR szName) +{ + BROWSEINFOW bi; + LPITEMIDLIST il, ir; + LPMALLOC pMalloc; + WCHAR szPath[MAX_PATH+1]; + LPWSTR rv = NULL; + + AplZeroMemory(&bi, sizeof(BROWSEINFOW)); + SHGetSpecialFolderLocation(hWnd, CSIDL_DRIVES, &il); + bi.lpszTitle = szTitle; + bi.pszDisplayName = szPath; + bi.hwndOwner = hWnd; + bi.ulFlags = BIF_EDITBOX; + bi.lpfn = NULL; + bi.lParam = 0; + bi.iImage = 0; + bi.pidlRoot = il; + + if ((ir = SHBrowseForFolderW(&bi)) != NULL) { + if (SHGetPathFromIDListW(ir, szPath)) + rv = apxStrdupW(szPath); + } + if (SHGetMalloc(&pMalloc)) { + pMalloc->lpVtbl->Free(pMalloc, il); + pMalloc->lpVtbl->Release(pMalloc); + } + + return rv; +} + +LPSTR apxGetFileNameA(HWND hWnd, LPCSTR szTitle, LPCSTR szFilter, + LPCSTR szDefExt, LPCSTR szDefPath, BOOL bOpenOrSave, + LPDWORD lpdwFindex) +{ + OPENFILENAMEA lpOf; + CHAR szFile[SIZ_BUFLEN]; + BOOL rv; + + AplZeroMemory(&lpOf, sizeof(OPENFILENAMEA)); + szFile[0] = '\0'; + lpOf.lStructSize = sizeof(OPENFILENAMEA); + lpOf.hwndOwner = hWnd; + lpOf.hInstance = _st_sys_gui.hInstance; + lpOf.lpstrTitle = szTitle; + lpOf.lpstrFilter = szFilter; + lpOf.lpstrDefExt = szDefExt; + lpOf.lpstrInitialDir = szDefPath; + lpOf.lpstrFile = szFile; + lpOf.nMaxFile = SIZ_BUFMAX; + lpOf.Flags = OFN_LONGNAMES | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + + if (bOpenOrSave) + rv = GetOpenFileNameA(&lpOf); + else + rv = GetSaveFileNameA(&lpOf); + + if (rv) { + if (lpdwFindex) + *lpdwFindex = lpOf.nFilterIndex; + return apxStrdupA(szFile); + } + else + return NULL; +} + +LPWSTR apxGetFileNameW(HWND hWnd, LPCWSTR szTitle, LPCWSTR szFilter, + LPCWSTR szDefExt, LPCWSTR szDefPath, BOOL bOpenOrSave, + LPDWORD lpdwFindex) +{ + OPENFILENAMEW lpOf; + WCHAR szFile[SIZ_BUFLEN]; + BOOL rv; + + AplZeroMemory(&lpOf, sizeof(OPENFILENAMEW)); + szFile[0] = L'\0'; + lpOf.lStructSize = sizeof(OPENFILENAMEW); + lpOf.hwndOwner = hWnd; + lpOf.hInstance = _st_sys_gui.hInstance; + lpOf.lpstrTitle = szTitle; + lpOf.lpstrFilter = szFilter; + lpOf.lpstrDefExt = szDefExt; + lpOf.lpstrInitialDir = szDefPath; + lpOf.lpstrFile = szFile; + lpOf.nMaxFile = SIZ_BUFMAX; + lpOf.Flags = OFN_LONGNAMES | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + + if (bOpenOrSave) + rv = GetOpenFileNameW(&lpOf); + else + rv = GetSaveFileNameW(&lpOf); + + if (rv) { + if (lpdwFindex) + *lpdwFindex = lpOf.nFilterIndex; + return apxStrdupW(szFile); + } + else + return NULL; +} + +static __apxSelectUserDlgResize(HWND hDlg, INT nWidth, INT nHeight) +{ + /* Combo box */ + MoveWindow(GetDlgItem(hDlg, IDSU_COMBO), + 70, 10, + nWidth - 70, + 120, + TRUE); + /* List Window */ + MoveWindow(GetDlgItem(hDlg, IDSU_LIST), + 0, 36, + nWidth, + nHeight - 74, + TRUE); + + /* Name label */ + MoveWindow(GetDlgItem(hDlg, IDSU_SELNAME), + 16, + nHeight - 30, + 50, + 24, + TRUE); + + /* Edit Box */ + MoveWindow(GetDlgItem(hDlg, IDSU_SELECTED), + 70, + nHeight - 32, + nWidth - 300, + 24, + TRUE); + + /* OK Button */ + MoveWindow(GetDlgItem(hDlg, IDOK), + nWidth - 200, + nHeight - 32, + 80, + 24, + TRUE); + + /* Cancel Button */ + MoveWindow(GetDlgItem(hDlg, IDCANCEL), + nWidth - 110, + nHeight - 32, + 80, + 24, + TRUE); + + +} + +static LRESULT CALLBACK +__apxSelectUserCreateLvSubclass(HWND hWnd, UINT uMsg, WPARAM wParam, + LPARAM lParam) +{ + static POINTS mouseClick; + int iS; + LVHITTESTINFO iHit; + switch (uMsg) { + case WM_LBUTTONDBLCLK: + /* Call the original window proc */ + CallWindowProc(_st_sel_users_lvm, hWnd, uMsg, wParam, lParam); + mouseClick = MAKEPOINTS(lParam); + iHit.pt.x = mouseClick.x; + iHit.pt.y = mouseClick.y; + iS = ListView_HitTest(hWnd, &iHit); + if (iS >= 0) { + DWORD i; + WCHAR szUser[SIZ_RESLEN] = L""; + LPWSTR szP; + HWND hCombo; + HWND hDlg = GetParent(hWnd); + hCombo = GetDlgItem(hDlg, IDSU_COMBO); + if ((i = ComboBox_GetCurSel(hCombo)) == 0) { + lstrcpyW(szUser, L".\\"); + } + else { + COMBOBOXEXITEMW cbEi; + cbEi.mask = CBEIF_TEXT; + cbEi.iItem = i; + cbEi.cchTextMax = SIZ_RESMAX; + cbEi.pszText = szUser; + SendMessage(hCombo, CBEM_GETITEM, 0, (LPARAM)&cbEi); + lstrcatW(szUser, L"\\"); + } + szP = &szUser[lstrlenW(szUser)]; + ListView_GetItemTextW(hWnd, iS, 0, szP, SIZ_RESMAX); + if (*szP) { + SetDlgItemTextW(hDlg, IDSU_SELECTED, szUser); + } + } + return TRUE; + break; + } + return CallWindowProc(_st_sel_users_lvm, hWnd, uMsg, wParam, lParam); +} + +#define SUMIN_WIDTH 600 +#define SUMIN_HEIGHT 200 + +static void __apxSelectUserCreateLv(HWND hDlg) +{ + DWORD i; + LV_COLUMN lvC; + HBITMAP hBmp; + + HWND hList = GetDlgItem(hDlg, IDSU_LIST); + + lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + for (i = 0; i < NUMLVUSERS; i++) { + lvC.iSubItem = i; + lvC.cx = lvUsers[i].iWidth; + lvC.pszText = lvUsers[i].szLabel; + lvC.fmt = lvUsers[i].iFmt; + ListView_InsertColumn(hList, i, &lvC ); + } +#ifdef LVS_EX_FULLROWSELECT + ListView_SetExtendedListViewStyleEx(hList, 0, + LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); +#endif + _st_sel_users_il = ImageList_Create(16, 16, ILC_COLOR4, 0, 16); + hBmp = LoadImage(GetModuleHandleA(NULL), MAKEINTRESOURCE(IDB_SUSERS), + IMAGE_BITMAP, 0, 0, LR_LOADTRANSPARENT); + + ImageList_Add(_st_sel_users_il, hBmp, NULL); + DeleteObject(hBmp); + + ListView_SetImageList(hList, _st_sel_users_il, LVSIL_SMALL); + _st_sel_users_lvm = (WNDPROC)((SIZE_T)SetWindowLong(hList, GWLP_WNDPROC, + (LONG)((SIZE_T)__apxSelectUserCreateLvSubclass))); + +} + +static void __apxSelectUserPopulate(HWND hDlg, LPCWSTR szComputer) +{ + PNET_DISPLAY_USER pBuff, p; + INT row = 0x7FFFFFFF; + DWORD res, dwRec, i = 0; + + HWND hList = GetDlgItem(hDlg, IDSU_LIST); + + ListView_DeleteAllItems(hList); + + do { + res = NetQueryDisplayInformation(szComputer, 1, i, 1000, MAX_PREFERRED_LENGTH, + &dwRec, &pBuff); + if ((res == ERROR_SUCCESS) || (res == ERROR_MORE_DATA)) { + p = pBuff; + for (;dwRec > 0; dwRec--) { + LV_ITEMW lvI; + AplZeroMemory(&lvI, sizeof(LV_ITEMW)); + lvI.mask = LVIF_IMAGE | LVIF_TEXT; + lvI.iItem = 0x7FFFFFFF; + lvI.pszText = p->usri1_name; + if (p->usri1_flags & UF_ACCOUNTDISABLE) + lvI.iImage = 5; + else + lvI.iImage = 4; + row = ListView_InsertItemW(hList, &lvI); + if (row != -1) { + if (p->usri1_full_name) { + ListView_SetItemTextW(hList, row, 1, + p->usri1_full_name); + } + if (p->usri1_comment) { + ListView_SetItemTextW(hList, row, 2, + p->usri1_comment); + } + } + i = p->usri1_next_index; + p++; + } + NetApiBufferFree(pBuff); + } + } while (res == ERROR_MORE_DATA); + +} + +static void __apxSelectUserCreateCbex(HWND hDlg) +{ + COMBOBOXEXITEMW cbEi; + LPBYTE lpNetBuf; + LPWKSTA_INFO_100 lpWksta; + DWORD res; + HWND hCombo = GetDlgItem(hDlg, IDSU_COMBO); + +#ifndef _UNICODE + SendMessageW(hCombo, CBEM_SETUNICODEFORMAT, TRUE, 0); +#endif + + cbEi.mask = CBEIF_TEXT | CBEIF_INDENT | + CBEIF_IMAGE | CBEIF_SELECTEDIMAGE; + + res = NetWkstaGetInfo(NULL, 101, (LPBYTE *)&lpWksta); + if (res != ERROR_SUCCESS) { + EnableWindow(hCombo, FALSE); + return; + } + /* add localhost computer */ + cbEi.iItem = 0; + cbEi.pszText = (LPWSTR)lpWksta->wki100_computername; + cbEi.iIndent = 0; + cbEi.iImage = 1; + cbEi.iSelectedImage = 1; + SendMessageW(hCombo, CBEM_INSERTITEMW, 0, (LPARAM)&cbEi); + NetApiBufferFree(lpWksta); + + ComboBox_SetCurSel(hCombo, 0); + res = NetGetDCName(NULL, NULL, &lpNetBuf); + if ((res == ERROR_SUCCESS) || (res == ERROR_MORE_DATA)) { + + cbEi.iItem = 1; + cbEi.pszText = ((LPWSTR)lpNetBuf) + 2; + cbEi.iIndent = 0; + cbEi.iImage = 0; + cbEi.iSelectedImage = 0; + SendMessageW(hCombo, CBEM_INSERTITEMW, 0, (LPARAM)&cbEi); + EnableWindow(hCombo, TRUE); + NetApiBufferFree(lpNetBuf); + } + else + EnableWindow(hCombo, FALSE); + + SendMessageW(hCombo, CBEM_SETIMAGELIST, 0, (LPARAM)_st_sel_users_il); +} + +static LRESULT CALLBACK __apxSelectUserDlgProc(HWND hDlg, UINT uMsg, + WPARAM wParam, LPARAM lParam) +{ + static HWND hList; + static LPWSTR lpUser; + RECT r, *l; + + switch (uMsg) { + case WM_INITDIALOG: + /* Set the application icon */ + SetClassLong(hDlg, GCLP_HICON, + (LONG)(SIZE_T)LoadIcon(_st_sys_gui.hInstance, + MAKEINTRESOURCE(IDI_MAINICON))); + apxCenterWindow(hDlg, _st_sys_gui.hMainWnd); + hList = GetDlgItem(hDlg, IDSU_LIST); + __apxSelectUserCreateLv(hDlg); + __apxSelectUserCreateCbex(hDlg); + GetClientRect(hDlg, &r); + /* Resize the controls */ + __apxSelectUserDlgResize(hDlg, r.right - r.left, + r.bottom - r.top); + lpUser = (LPWSTR)lParam; + __apxSelectUserPopulate(hDlg, NULL); + return TRUE; + break; + case WM_SIZING: + l = (LPRECT)lParam; + /* limit the window size */ + switch (wParam) { + case WMSZ_BOTTOM: + case WMSZ_BOTTOMRIGHT: + if ((l->bottom - l->top) < SUMIN_HEIGHT) + l->bottom = l->top + SUMIN_HEIGHT; + if ((l->right - l->left) < SUMIN_WIDTH) + l->right = l->left + SUMIN_WIDTH; + break; + case WMSZ_TOPLEFT: + if ((l->bottom - l->top) < SUMIN_HEIGHT) + l->top = l->bottom - SUMIN_HEIGHT; + if ((l->right - l->left) < SUMIN_WIDTH) + l->left = l->right - SUMIN_WIDTH; + break; + case WMSZ_TOP: + case WMSZ_RIGHT: + case WMSZ_TOPRIGHT: + if ((l->bottom - l->top) < SUMIN_HEIGHT) + l->top = l->bottom - SUMIN_HEIGHT; + if ((l->right - l->left) < SUMIN_WIDTH) + l->right = l->left + SUMIN_WIDTH; + break; + case WMSZ_BOTTOMLEFT: + case WMSZ_LEFT: + if ((l->bottom - l->top) < SUMIN_HEIGHT) + l->bottom = l->top + SUMIN_HEIGHT; + if ((l->right - l->left) < SUMIN_WIDTH) + l->left = l->right - SUMIN_WIDTH; + break; + } + break; + case WM_SIZE: + __apxSelectUserDlgResize(hDlg, LOWORD(lParam), + HIWORD(lParam)); + GetClientRect(hDlg, &r); + InvalidateRect(hDlg, &r, FALSE); + break; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + case IDCANCEL: + /* Clear the user name buffer */ + *lpUser = L'\0'; + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + break; + case IDSU_SELECTED: + if (HIWORD(wParam) == EN_CHANGE) { + /* enable OK button if there is a user */ + GetDlgItemTextW(hDlg, IDSU_SELECTED, lpUser, SIZ_RESMAX); + if (lstrlenW(lpUser)) + Button_Enable(GetDlgItem(hDlg, IDOK), TRUE); + else + Button_Enable(GetDlgItem(hDlg, IDOK), FALSE); + } + break; + case IDSU_COMBO: + if (HIWORD(wParam) == CBN_SELCHANGE) { + COMBOBOXEXITEMW cbEi; + DWORD i; + WCHAR szServer[SIZ_RESLEN] = L"\\\\"; + HWND hCombo = GetDlgItem(hDlg, IDSU_COMBO); + if ((i = ComboBox_GetCurSel(hCombo)) >= 0) { + cbEi.mask = CBEIF_TEXT; + cbEi.iItem = i; + cbEi.cchTextMax = SIZ_RESMAX; + cbEi.pszText = &szServer[2]; + SendMessageW(hCombo, CBEM_GETITEM, 0, (LPARAM)&cbEi); + } + if (szServer[2]) + __apxSelectUserPopulate(hDlg, szServer); + } + break; + + } + break; + case WM_MOUSEWHEEL: + { + int nScroll; + if ((SHORT)HIWORD(wParam) < 0) + nScroll = _st_sys_gui.nWhellScroll; + else + nScroll = _st_sys_gui.nWhellScroll * (-1); + } + break; + + } + return FALSE; +} + + +LPCWSTR apxDlgSelectUser(HWND hWnd, LPWSTR szUser) +{ + szUser[0] = L'\0'; + + DialogBoxParam(_st_sys_gui.hInstance, + MAKEINTRESOURCE(IDD_SELUSER), + hWnd, + (DLGPROC)__apxSelectUserDlgProc, + (LPARAM)szUser); + if (_st_sel_users_il) + ImageList_Destroy(_st_sel_users_il); + _st_sel_users_il = NULL; + if (szUser[0] != '\0') + return szUser; + else + return NULL; +}
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/nt/procrun/src/gui.c ------------------------------------------------------------------------------ svn:eol-style = native Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/nt/procrun/src/handles.c URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/nt/procrun/src/handles.c?rev=980662&view=auto ============================================================================== --- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/nt/procrun/src/handles.c (added) +++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/nt/procrun/src/handles.c Fri Jul 30 06:50:12 2010 @@ -0,0 +1,689 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apxwin.h" +#include "private.h" + +#define ALLOCBLOCK_INVALID 0xdeadbeef + +typedef struct APXPOOL APXPOOL; +typedef APXPOOL* LPAPXPOOL; + +typedef struct ALLOCBLOCK { + DWORD dwSize; + APXHANDLE lpPool; + APXMEMWORD lpAlign; +} ALLOCBLOCK, *LPALLOCBLOCK; + +struct APXPOOL { + TAILQ_HEAD(_lHandles, stAPXHANDLE) lHandles; + TAILQ_HEAD(_lPools, stAPXHANDLE) lPools; +}; + +static SYSTEM_INFO _st_sys_info; +static APXHANDLE _st_sys_pool = NULL; +static int _st_sys_init = 0; +static LPVOID _st_sys_page = NULL; +LPWSTR *_st_sys_argvw = NULL; +int _st_sys_argc = 0; + +#ifdef _DEBUG +static INT _heap_count = 0; +static INT _heap_alloc_count = 0; +static INT _heap_realloc_count = 0; + +HANDLE HeapCREATE(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize) +{ + _heap_count++; + return HeapCreate(flOptions, dwInitialSize, dwMaximumSize); +} + +BOOL HeapDESTROY(HANDLE hHeap) +{ + _heap_count--; + return HeapDestroy(hHeap); +} + + +LPVOID HeapALLOC(HANDLE hHeap, DWORD dwFlags, SIZE_T nSize) +{ + _heap_alloc_count++; + return HeapAlloc(hHeap, dwFlags, nSize); +} + +BOOL HeapFREE(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) +{ + _heap_alloc_count--; + return HeapFree(hHeap, dwFlags, lpMem); +} + +LPVOID HeapREALLOC(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes) +{ + + _heap_realloc_count++; + return HeapReAlloc(hHeap, dwFlags, lpMem, dwBytes); +} +#endif + +static LPVOID __apxPoolAllocCore(APXHANDLE hPool, + DWORD dwSize, DWORD dwOptions) +{ + DWORD dwPhysicalSize; + LPALLOCBLOCK lpBlock; + + if (!hPool) + hPool = _st_sys_pool; + dwPhysicalSize = APX_ALIGN_DEFAULT(dwSize + sizeof(ALLOCBLOCK)); + lpBlock = HeapALLOC(hPool->hHeap, dwOptions, dwPhysicalSize); + lpBlock->dwSize = dwPhysicalSize; + lpBlock->lpPool = hPool; + + return ((char *)lpBlock + sizeof(ALLOCBLOCK)); +} + +static LPVOID __apxPoolReallocCore(APXHANDLE hPool, LPVOID lpMem, + DWORD dwSize, DWORD dwOptions) +{ + DWORD dwPhysicalSize; + LPALLOCBLOCK lpBlock; + LPALLOCBLOCK lpOrg; + + if (!lpMem) + return __apxPoolAllocCore(hPool, dwSize, dwOptions); + lpOrg = (LPALLOCBLOCK)((char *)lpMem - sizeof(ALLOCBLOCK)); + if (!hPool) + hPool = _st_sys_pool; + /* Trying to realloc something that isn't valid */ + if (lpOrg->lpPool == APXHANDLE_INVALID || + lpOrg->lpPool != hPool) + return NULL; + dwPhysicalSize = APX_ALIGN_DEFAULT(dwSize + sizeof(ALLOCBLOCK)); + lpBlock = HeapREALLOC(hPool->hHeap, dwOptions, lpOrg, dwPhysicalSize); + lpBlock->dwSize = dwPhysicalSize; + lpBlock->lpPool = hPool; + + return ((char *)lpBlock + sizeof(ALLOCBLOCK)); +} + +static void __apxPoolFreeCore(LPVOID lpMem) +{ + APXHANDLE hPool; + LPALLOCBLOCK lpBlock = (LPALLOCBLOCK)((char *)lpMem - sizeof(ALLOCBLOCK)); + + if (lpBlock->lpPool != APXHANDLE_INVALID) { + hPool = lpBlock->lpPool; + lpBlock->lpPool = APXHANDLE_INVALID; + } + else + return; + HeapFREE(hPool->hHeap, 0, lpBlock); +} +/* + * + */ +static DWORD WINAPI __apxHandleEventThread(LPVOID lpParameter) +{ + APXHANDLE hHandle = (APXHANDLE)lpParameter; + DWORD rv = 0; + while (hHandle->dwType != APXHANDLE_TYPE_INVALID) { + DWORD dwState; + dwState = WaitForSingleObject(hHandle->hEventHandle, INFINITE); + /* the flags can be changed to invalid meaning we are killing + * this event. + */ + if (dwState == WAIT_OBJECT_0 && + hHandle->dwType != APXHANDLE_TYPE_INVALID) { + if (hHandle->uMsg && (hHandle->wParam || hHandle->lParam)) { + APXCALLHOOK *lpCall; + rv = (*hHandle->fnCallback)(hHandle, hHandle->uMsg, + hHandle->wParam, hHandle->lParam); + TAILQ_FOREACH(lpCall, &hHandle->lCallbacks, queue) { + (*lpCall->fnCallback)(hHandle, hHandle->uMsg, + hHandle->wParam, hHandle->lParam); + } + hHandle->uMsg = 0; + if (!rv) + break; + } + ResetEvent(hHandle->hEventHandle); + SwitchToThread(); + } + else + break; + } + ResetEvent(hHandle->hEventHandle); + /* This will rise the Thread waiting function */ + return 0; +} + +static BOOL __apxPoolCallback(APXHANDLE hObject, UINT uMsg, + WPARAM wParam, LPARAM lParam) +{ + LPAPXPOOL lpPool; + APXHANDLE hCur; + if (hObject->dwType != APXHANDLE_TYPE_POOL) + return FALSE; + lpPool = APXHANDLE_DATA(hObject); + + /* recurse the subpools */ + TAILQ_FOREACH(hCur, &lpPool->lPools, queue) { + __apxPoolCallback(hCur, uMsg, 0, 0); + } + /* call the handles callback */ + for(hCur = TAILQ_FIRST(&lpPool->lHandles) ; + hCur != NULL ; + hCur = TAILQ_FIRST(&lpPool->lHandles)) { + apxCloseHandle(hCur); + } + /* if we are closing this pool destroy the private Heap */ + if (uMsg == WM_CLOSE) { + if (hObject->dwFlags & APXHANDLE_HAS_HEAP) + HeapDESTROY(hObject->hHeap); + hObject->dwSize = 0; + } + else if (uMsg == WM_CLEAR) + hObject->dwSize = 0; + + return TRUE; +} + +static BOOL __apxHandleCallback(APXHANDLE hObject, UINT uMsg, + WPARAM wParam, LPARAM lParam) +{ + BOOL rv = FALSE; + if (hObject->dwType == APXHANDLE_TYPE_INVALID) + return FALSE; + /* Default handler handles only close event */ + if (uMsg != WM_CLOSE) + return FALSE; + if (hObject->dwType == APXHANDLE_TYPE_WINHANDLE && + !(IS_INVALID_HANDLE(hObject->uData.hWinHandle))) { + rv = CloseHandle(hObject->uData.hWinHandle); + hObject->uData.hWinHandle = NULL; + } + /* Invalidate the handle */ + hObject->dwType = APXHANDLE_TYPE_INVALID; + + if (hObject->dwFlags & APXHANDLE_HAS_EVENT) { + DWORD dwState; + /* Signal the EventThread to exit */ + SetEvent(hObject->hEventHandle); + /* Wait for EventThread to Exit */ + dwState = WaitForSingleObject(hObject->hEventThread, 1000); + SAFE_CLOSE_HANDLE(hObject->hEventHandle); + if (dwState == WAIT_TIMEOUT) + TerminateThread(hObject->hEventThread, 0); + SAFE_CLOSE_HANDLE(hObject->hEventThread); + /* Reset the evant flag */ + hObject->dwFlags &= ~APXHANDLE_HAS_EVENT; + } + return rv; +} + +static BOOL __apxCreateSystemPool() +{ + LPAPXPOOL lpPool; + HANDLE hHeap; + + GetSystemInfo(&_st_sys_info); + apxGetOsLevel(); + /* First create the shared data segment */ + _st_sys_page = VirtualAlloc(NULL, _st_sys_info.dwAllocationGranularity, + MEM_RESERVE, PAGE_NOACCESS); + if (!_st_sys_page) + return FALSE; + _st_sys_page = VirtualAlloc(_st_sys_page, _st_sys_info.dwAllocationGranularity, + MEM_COMMIT, PAGE_READWRITE); + + /* Create the main Heap */ + hHeap = HeapCREATE(0, _st_sys_info.dwAllocationGranularity, 0); + _st_sys_pool = HeapALLOC(hHeap, HEAP_ZERO_MEMORY, + APX_ALIGN_DEFAULT(APXHANDLE_SZ + sizeof(APXPOOL))); + _st_sys_pool->hHeap = hHeap; + _st_sys_pool->dwType = APXHANDLE_TYPE_INVALID; + if (IS_INVALID_HANDLE(_st_sys_pool->hHeap)) + return FALSE; + _st_sys_pool->fnCallback = __apxPoolCallback; + lpPool = APXHANDLE_DATA(_st_sys_pool); + /* Initialize the pool and object lists */ + TAILQ_INIT(&lpPool->lHandles); + TAILQ_INIT(&lpPool->lPools); + _st_sys_pool->dwType = APXHANDLE_TYPE_POOL; + + /** TODO: For each unsupported function make a surrogate */ + _st_sys_argvw = CommandLineToArgvW(GetCommandLineW(), &_st_sys_argc); + + return TRUE; +} + +BOOL +apxHandleManagerInitialize() +{ + BOOL rv; + if (_st_sys_init++) + return TRUE; + rv = __apxCreateSystemPool(); + + return rv; +} + +BOOL +apxHandleManagerDestroy() +{ + HANDLE hHeap; + + if (--_st_sys_init == 0) { + hHeap = _st_sys_pool->hHeap; + apxCloseHandle(_st_sys_pool); + /* Destroy the main Heap */ + HeapDESTROY(hHeap); + _st_sys_pool = NULL; + VirtualFree(_st_sys_page, 0, MEM_RELEASE); + GlobalFree(_st_sys_argvw); + _st_sys_argvw = NULL; + _st_sys_argc = 0; +#ifdef _DEBUG + apxLogWrite(APXLOG_MARK_DEBUG "Alloc Count %d", _heap_alloc_count); + apxLogWrite(APXLOG_MARK_DEBUG "Realloc Count %d", _heap_realloc_count); + apxLogWrite(APXLOG_MARK_DEBUG "Heap Count %d", _heap_count); +#endif + return TRUE; + } + + return FALSE; +} + +APXHANDLE +apxPoolCreate(APXHANDLE hParent, DWORD dwOptions) +{ + APXHANDLE hHandle; + LPAPXPOOL lpPool; + HANDLE hHeap; + + if (IS_INVALID_HANDLE(hParent)) + hParent = _st_sys_pool; + if (hParent->dwType != APXHANDLE_TYPE_POOL) { + apxLogWrite(APXLOG_MARK_ERROR "Parent Handle type is not POOL %d", + hParent->dwType); + return INVALID_HANDLE_VALUE; + } + /* Allocate the handle from the parent */ + hHandle = __apxPoolAllocCore(hParent, APXHANDLE_SZ + sizeof(APXPOOL), + HEAP_ZERO_MEMORY); + + if (dwOptions & APXHANDLE_HAS_HEAP) { + /* Create the private Heap */ + hHeap = HeapCREATE(0, _st_sys_info.dwAllocationGranularity, 0); + hHandle->dwFlags |= APXHANDLE_HAS_HEAP; + } + else + hHeap = hParent->hHeap; + hHandle->hHeap = hHeap; + hHandle->dwType = APXHANDLE_TYPE_POOL; + hHandle->hPool = hParent; + hHandle->fnCallback = __apxPoolCallback; + lpPool = APXHANDLE_DATA(hHandle); + TAILQ_INIT(&lpPool->lHandles); + TAILQ_INIT(&lpPool->lPools); + + /* Insert the pool to the head of parent pool */ + lpPool = APXHANDLE_DATA(hParent); + APXHANDLE_SPINLOCK(hParent); + TAILQ_INSERT_HEAD(&lpPool->lPools, hHandle, queue); + ++hParent->dwSize; + APXHANDLE_SPINUNLOCK(hParent); + + return hHandle; +} + +LPVOID +apxPoolAlloc(APXHANDLE hPool, DWORD dwSize) +{ + if (IS_INVALID_HANDLE(hPool) || + (hPool->dwType != APXHANDLE_TYPE_POOL)) + hPool = _st_sys_pool; + return __apxPoolAllocCore(hPool, dwSize, 0); +} + +LPVOID +apxPoolCalloc(APXHANDLE hPool, DWORD dwSize) +{ + if (IS_INVALID_HANDLE(hPool) || + (hPool->dwType != APXHANDLE_TYPE_POOL)) + hPool = _st_sys_pool; + return __apxPoolAllocCore(hPool, dwSize, HEAP_ZERO_MEMORY); +} + +LPVOID +apxPoolRealloc(APXHANDLE hPool, LPVOID lpMem, DWORD dwNewSize) +{ + if (IS_INVALID_HANDLE(hPool) || + (hPool->dwType != APXHANDLE_TYPE_POOL)) + hPool = _st_sys_pool; + return __apxPoolReallocCore(hPool, lpMem, dwNewSize, HEAP_ZERO_MEMORY); +} + +LPVOID +apxAlloc(DWORD dwSize) +{ + return __apxPoolAllocCore(_st_sys_pool, dwSize, 0); +} + +LPVOID +apxCalloc(DWORD dwSize) +{ + return __apxPoolAllocCore(_st_sys_pool, dwSize, HEAP_ZERO_MEMORY); +} + +LPVOID +apxRealloc(LPVOID lpMem, DWORD dwNewSize) +{ + return __apxPoolReallocCore(_st_sys_pool, lpMem, dwNewSize, HEAP_ZERO_MEMORY); +} + +VOID +apxFree(LPVOID lpMem) +{ + if (lpMem) + __apxPoolFreeCore(lpMem); + +} + +LPWSTR +apxPoolWStrdupA(APXHANDLE hPool, LPCSTR szSource) +{ + if (szSource) { + LPWSTR szDest; + int cch = MultiByteToWideChar(CP_UTF8, 0, szSource, -1, NULL, 0); + szDest = (LPWSTR)apxPoolAlloc(hPool, cch * sizeof(WCHAR)); + if (!MultiByteToWideChar(CP_UTF8, 0, szSource, -1, szDest, cch)) { + apxFree(szDest); + return NULL; + } + return szDest; + } + else + return NULL; +} + +LPWSTR apxWStrdupA(LPCTSTR szSource) +{ + return apxPoolWStrdup(_st_sys_pool, szSource); +} + +LPSTR +apxPoolStrdupA(APXHANDLE hPool, LPCSTR szSource) +{ + if (szSource) { + LPSTR szDest; + DWORD l = lstrlenA(szSource); + szDest = apxPoolAlloc(hPool, l + 1); + lstrcpyA(szDest, szSource); + return szDest; + } + else + return NULL; +} + +LPWSTR +apxPoolStrdupW(APXHANDLE hPool, LPCWSTR szSource) +{ + if (szSource) { + LPWSTR szDest; + DWORD l = lstrlenW(szSource); + szDest = apxPoolAlloc(hPool, (l + 1) * sizeof(WCHAR)); + lstrcpyW(szDest, szSource); + return szDest; + } + else + return NULL; +} + +LPSTR +apxStrdupA(LPCSTR szSource) +{ + return apxPoolStrdupA(_st_sys_pool, szSource); +} + +LPWSTR +apxStrdupW(LPCWSTR szSource) +{ + return apxPoolStrdupW(_st_sys_pool, szSource); +} + +APXHANDLE +apxHandleCreate(APXHANDLE hPool, DWORD dwFlags, + LPVOID lpData, DWORD dwDataSize, + LPAPXFNCALLBACK fnCallback) +{ + APXHANDLE hHandle; + LPAPXPOOL lpPool; + + if (IS_INVALID_HANDLE(hPool)) + hPool = _st_sys_pool; + if (hPool->dwType != APXHANDLE_TYPE_POOL) { + apxLogWrite(APXLOG_MARK_ERROR "Parent Handle type is not POOL %d", + hPool->dwType); + return INVALID_HANDLE_VALUE; + } + hHandle = __apxPoolAllocCore(hPool, APXHANDLE_SZ + dwDataSize, + HEAP_ZERO_MEMORY); + + hHandle->hPool = hPool; + if (fnCallback) + hHandle->fnCallback = fnCallback; + else + hHandle->fnCallback = __apxHandleCallback; + + if (dwFlags & APXHANDLE_TYPE_WINHANDLE) { + hHandle->dwFlags |= APXHANDLE_HAS_USERDATA; + hHandle->dwFlags |= APXHANDLE_TYPE_WINHANDLE; + hHandle->uData.hWinHandle = lpData; + } + else if (dwFlags & APXHANDLE_TYPE_LPTR) { + hHandle->dwFlags |= APXHANDLE_HAS_USERDATA; + hHandle->dwFlags |= APXHANDLE_TYPE_LPTR; + hHandle->uData.lpPtr = lpData; + } + else if (dwDataSize && lpData) { + hHandle->dwFlags |= APXHANDLE_HAS_USERDATA; + AplCopyMemory(APXHANDLE_DATA(hHandle), lpData, dwDataSize); + hHandle->dwSize = dwDataSize; + } + + if (dwFlags & APXHANDLE_HAS_EVENT) { + /* Create the message event and message wathcing thread */ + hHandle->hEventHandle = CreateEvent(NULL, TRUE, FALSE, NULL); + hHandle->hEventThread = CreateThread(NULL, 0, __apxHandleEventThread, + hHandle, 0, + &(hHandle->hEventThreadId)); + if (IS_INVALID_HANDLE(hHandle->hEventThread)) { + SAFE_CLOSE_HANDLE(hHandle->hEventHandle); + } + else + hHandle->dwFlags |= APXHANDLE_HAS_EVENT; + } + TAILQ_INIT(&hHandle->lCallbacks); + /* Add the handle to the pool's object list */ + lpPool = APXHANDLE_DATA(hPool); + APXHANDLE_SPINLOCK(hPool); + TAILQ_INSERT_HEAD(&lpPool->lHandles, hHandle, queue); + ++hPool->dwSize; + APXHANDLE_SPINUNLOCK(hPool); + + return hHandle; +} + +BOOL +apxCloseHandle(APXHANDLE hObject) +{ + LPAPXPOOL lpPool; + APXCALLHOOK *lpCall; + + if (IS_INVALID_HANDLE(hObject) || hObject->dwType == APXHANDLE_TYPE_INVALID) + return FALSE; + /* Call the user callback first */ + (*hObject->fnCallback)(hObject, WM_CLOSE, 0, 0); + /* Now go through the callback chain */ + TAILQ_FOREACH(lpCall, &hObject->lCallbacks, queue) { + (*lpCall->fnCallback)(hObject, WM_CLOSE, 0, 0); + TAILQ_REMOVE(&hObject->lCallbacks, lpCall, queue); + __apxPoolFreeCore(lpCall); + } + + hObject->dwType = APXHANDLE_TYPE_INVALID; + if (hObject->dwFlags & APXHANDLE_HAS_EVENT) { + DWORD dwState; + + SetEvent(hObject->hEventHandle); + dwState = WaitForSingleObject(hObject->hEventThread, 1000); + SAFE_CLOSE_HANDLE(hObject->hEventHandle); + if (dwState == WAIT_TIMEOUT) + TerminateThread(hObject->hEventThread, 0); + SAFE_CLOSE_HANDLE(hObject->hEventThread); + + hObject->dwFlags &= ~APXHANDLE_HAS_EVENT; + } + + /* finaly remove the object from the pool's object list */ + if (!IS_INVALID_HANDLE(hObject->hPool)) { + lpPool = APXHANDLE_DATA(hObject->hPool); + APXHANDLE_SPINLOCK(hObject->hPool); + TAILQ_REMOVE(&lpPool->lHandles, hObject, queue); + hObject->hPool->dwSize--; + APXHANDLE_SPINUNLOCK(hObject->hPool); + __apxPoolFreeCore(hObject); + } + return TRUE; +} + +LPVOID +apxHandleGetUserData(APXHANDLE hObject) +{ + if (hObject->dwType == APXHANDLE_TYPE_INVALID) + return NULL; + if (hObject->dwFlags & APXHANDLE_HAS_USERDATA) + return APXHANDLE_DATA(hObject); + else + return hObject->uData.lpPtr; +} + +LPVOID +apxHandleSetUserData(APXHANDLE hObject, LPVOID lpData, DWORD dwDataSize) +{ + if (hObject->dwType == APXHANDLE_TYPE_INVALID) + return NULL; + if (hObject->dwFlags & APXHANDLE_HAS_USERDATA && hObject->dwSize > 0) { + AplCopyMemory(APXHANDLE_DATA(hObject), lpData, + MIN(hObject->dwSize, dwDataSize)); + return APXHANDLE_DATA(hObject); + } + else { + LPVOID lpOrg = hObject->uData.lpPtr; + hObject->uData.lpPtr = lpData; + return lpOrg; + } +} + +BOOL apxHandleSendMessage(APXHANDLE hObject, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + BOOL rv = TRUE; + APXCALLHOOK *lpCall; + if (hObject->dwType == APXHANDLE_TYPE_INVALID) + return FALSE; + /* Serialize requests to the callback */ + APXHANDLE_SPINLOCK(hObject); + if (hObject->fnCallback) + rv = (*hObject->fnCallback)(hObject, uMsg, wParam, lParam); + TAILQ_FOREACH(lpCall, &hObject->lCallbacks, queue) { + (*lpCall->fnCallback)(hObject, uMsg, wParam, lParam); + } + APXHANDLE_SPINUNLOCK(hObject); + + return rv; +} + +BOOL apxHandlePostMessage(APXHANDLE hObject, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (hObject->dwType == APXHANDLE_TYPE_INVALID) + return FALSE; + if (hObject->dwFlags & APXHANDLE_HAS_EVENT) { + /* TODO: Create a thread message queue + * Right now wait while the event gets nonsignaled + */ + while (WaitForSingleObject(hObject->hEventHandle, 0) == WAIT_OBJECT_0) + SwitchToThread(); + APXHANDLE_SPINLOCK(hObject); + SuspendThread(hObject->hEventThread); + hObject->uMsg = uMsg; + hObject->wParam = wParam; + hObject->lParam = lParam; + /* Signal the event thread to call the user callback */ + SetEvent(hObject->hEventHandle); + ResumeThread(hObject->hEventThread); + APXHANDLE_SPINUNLOCK(hObject); + + return TRUE; + } + return FALSE; +} + +BOOL apxHandleLock(APXHANDLE hObject, BOOL bLock) +{ + if (bLock) + APXHANDLE_SPINLOCK(hObject); + else + APXHANDLE_SPINUNLOCK(hObject); + + return TRUE; +} + +BOOL apxHandleAddHook(APXHANDLE hObject, DWORD dwWhere, + LPAPXFNCALLBACK fnCallback) +{ + APXCALLHOOK *lpCall; + + if (hObject->dwType == APXHANDLE_TYPE_INVALID || !fnCallback) + return FALSE; + lpCall = (APXCALLHOOK *)__apxPoolAllocCore(hObject->hPool, + sizeof(APXCALLHOOK), 0); + if (!lpCall) + return FALSE; + lpCall->fnCallback = fnCallback; + APXHANDLE_SPINLOCK(hObject); + if (dwWhere == APXHANDLE_HOOK_FIRST) { + TAILQ_INSERT_HEAD(&hObject->lCallbacks, lpCall, queue); + } + else { + TAILQ_INSERT_TAIL(&hObject->lCallbacks, lpCall, queue); + } + APXHANDLE_SPINUNLOCK(hObject); + + return TRUE; +} + +DWORD apxHandleWait(APXHANDLE hHandle, DWORD dwMilliseconds, BOOL bKill) +{ + if (IS_INVALID_HANDLE(hHandle)) + return WAIT_ABANDONED; + if (hHandle->dwType == APXHANDLE_TYPE_JVM) + return apxJavaWait(hHandle, dwMilliseconds, bKill); + else if (hHandle->dwType == APXHANDLE_TYPE_PROCESS) + return apxProcessWait(hHandle, dwMilliseconds, bKill); + else + return WAIT_ABANDONED; +} + Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/nt/procrun/src/handles.c ------------------------------------------------------------------------------ svn:eol-style = native