Compare commits
34 Commits
taskmgr_ac
...
GSoC_2017/
Author | SHA1 | Date | |
---|---|---|---|
|
3c6def4711 | ||
|
e040b84aa6 | ||
|
76cb54455c | ||
|
51cda605ff | ||
|
dd524eab21 | ||
|
93a5cfc0ef | ||
|
b421d735af | ||
|
d13b13ec76 | ||
|
287232ea2f | ||
|
e0959b80b1 | ||
|
bbf1ae346a | ||
|
fe273d3531 | ||
|
c8c4bcfa52 | ||
|
180321d87a | ||
|
26958e704b | ||
|
8a98b9a578 | ||
|
9e52604cad | ||
|
5809f6ada6 | ||
|
8c802b5ece | ||
|
02f6a567fa | ||
|
ba53ff00eb | ||
|
aa5d11c9c2 | ||
|
2613fc122b | ||
|
f6af139f35 | ||
|
96612d92b8 | ||
|
abfd95f82e | ||
|
a34b262695 | ||
|
e53d4a63ce | ||
|
f6e5c08bc6 | ||
|
16ddc047d9 | ||
|
48c992a2c2 | ||
|
e77b6e64ca | ||
|
b1b599d5d9 | ||
|
5489577226 |
@@ -6,5 +6,6 @@ add_subdirectory(devcpux)
|
||||
add_subdirectory(fontext)
|
||||
add_subdirectory(netshell)
|
||||
add_subdirectory(ntobjshex)
|
||||
add_subdirectory(qcklnch)
|
||||
add_subdirectory(shellbtrfs)
|
||||
add_subdirectory(stobject)
|
||||
|
0
reactos/dll/shellext/qcklnch/.gitignore
vendored
Normal file
587
reactos/dll/shellext/qcklnch/CISFBand.cpp
Normal file
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
* PROJECT: ReactOS shell extensions
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: dll/shellext/qcklnch/CISFBand.cpp
|
||||
* PURPOSE: Quick Launch Toolbar (Taskbar Shell Extension)
|
||||
* PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com>
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <commoncontrols.h>
|
||||
|
||||
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
|
||||
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(qcklnch);
|
||||
|
||||
// ***Extras***
|
||||
/*++
|
||||
* @name _ILIsDesktop
|
||||
*
|
||||
* Checks whether the given PIDL is of Desktop folder or not.
|
||||
*
|
||||
* @param pidl
|
||||
* PIDL to be checked.
|
||||
*
|
||||
* @return True if PIDL is of Desktop, otherwise false.
|
||||
*
|
||||
*--*/
|
||||
BOOL WINAPI _ILIsDesktop(LPCITEMIDLIST pidl)
|
||||
{
|
||||
return (pidl == NULL || pidl->mkid.cb == 0);
|
||||
}
|
||||
|
||||
//*****************************************************************************************
|
||||
// *** CISFBand ***
|
||||
|
||||
CISFBand::CISFBand() :
|
||||
m_BandID(0),
|
||||
m_pidl(NULL),
|
||||
m_textFlag(true),
|
||||
m_iconFlag(true)
|
||||
{
|
||||
}
|
||||
|
||||
CISFBand::~CISFBand()
|
||||
{
|
||||
CloseDW(0);
|
||||
}
|
||||
|
||||
// Toolbar
|
||||
/*++
|
||||
* @name CreateSimpleToolbar
|
||||
*
|
||||
* Creates a toolbar and fills it up with buttons for enumerated objects.
|
||||
*
|
||||
* @param hWndParent
|
||||
* Handle to the parent window, which receives the appropriate messages from child toolbar.
|
||||
*
|
||||
* @return The error code.
|
||||
*
|
||||
*--*/
|
||||
HRESULT CISFBand::CreateSimpleToolbar(HWND hWndParent)
|
||||
{
|
||||
// Declare and initialize local constants.
|
||||
const DWORD buttonStyles = BTNS_AUTOSIZE;
|
||||
|
||||
// Create the toolbar.
|
||||
m_hWnd = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
|
||||
WS_CHILD | TBSTYLE_FLAT | TBSTYLE_LIST | CCS_NORESIZE | CCS_NODIVIDER, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0,
|
||||
hWndParent, NULL, 0, NULL);
|
||||
if (m_hWnd == NULL)
|
||||
return E_FAIL;
|
||||
|
||||
// Set the image list.
|
||||
HIMAGELIST* piml;
|
||||
HRESULT hr = SHGetImageList(SHIL_SMALL, IID_IImageList, (void**)&piml);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
{
|
||||
DestroyWindow();
|
||||
return hr;
|
||||
}
|
||||
SendMessage(m_hWnd, TB_SETIMAGELIST, 0, (LPARAM)piml);
|
||||
|
||||
// Enumerate objects
|
||||
CComPtr<IEnumIDList> pEndl;
|
||||
LPITEMIDLIST pidl;
|
||||
STRRET stret;
|
||||
hr = m_pISF->EnumObjects(0, SHCONTF_FOLDERS, &pEndl);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
{
|
||||
DestroyWindow();
|
||||
return hr;
|
||||
}
|
||||
|
||||
for (int i=0; pEndl->Next(1, &pidl, NULL) != S_FALSE; i++)
|
||||
{
|
||||
WCHAR sz[MAX_PATH];
|
||||
int index = SHMapPIDLToSystemImageListIndex(m_pISF, pidl, NULL);
|
||||
hr = m_pISF->GetDisplayNameOf(pidl, SHGDN_NORMAL, &stret);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
{
|
||||
strcpyW(sz, L"<Unknown-Name>");
|
||||
}
|
||||
else
|
||||
StrRetToBuf(&stret, pidl, sz, _countof(sz));
|
||||
|
||||
TBBUTTON tb = { MAKELONG(index, 0), i, TBSTATE_ENABLED, buttonStyles,{ 0 }, (DWORD_PTR)pidl, (INT_PTR)sz };
|
||||
SendMessage(m_hWnd, TB_INSERTBUTTONW, i, (LPARAM)&tb);
|
||||
}
|
||||
|
||||
// Resize the toolbar, and then show it.
|
||||
SendMessage(m_hWnd, TB_AUTOSIZE, 0, 0);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
// *** IObjectWithSite ***
|
||||
STDMETHODIMP CISFBand::SetSite(IUnknown *pUnkSite)
|
||||
{
|
||||
HRESULT hr;
|
||||
HWND hwndParent;
|
||||
|
||||
TRACE("CISFBand::SetSite(0x%p)\n", pUnkSite);
|
||||
|
||||
hr = IUnknown_GetWindow(pUnkSite, &hwndParent);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
TRACE("Querying site window failed: 0x%x\n", hr);
|
||||
return hr;
|
||||
}
|
||||
m_Site = pUnkSite;
|
||||
|
||||
hr = CreateSimpleToolbar(hwndParent);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::GetSite(IN REFIID riid, OUT VOID **ppvSite)
|
||||
{
|
||||
TRACE("CISFBand::GetSite(0x%p,0x%p)\n", riid, ppvSite);
|
||||
|
||||
HRESULT hr;
|
||||
if (m_Site != NULL)
|
||||
{
|
||||
hr = m_Site->QueryInterface(riid, ppvSite);
|
||||
if (FAILED(hr)) return hr;
|
||||
}
|
||||
|
||||
*ppvSite = NULL;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// *** IDeskBand ***
|
||||
STDMETHODIMP CISFBand::GetWindow(OUT HWND *phwnd)
|
||||
{
|
||||
if (!m_hWnd)
|
||||
return E_FAIL;
|
||||
if (!phwnd)
|
||||
return E_POINTER;
|
||||
*phwnd = m_hWnd;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::ContextSensitiveHelp(IN BOOL fEnterMode)
|
||||
{
|
||||
/* FIXME: Implement */
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::ShowDW(IN BOOL bShow)
|
||||
{
|
||||
if (m_hWnd)
|
||||
{
|
||||
ShowWindow(bShow ? SW_SHOW : SW_HIDE);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::CloseDW(IN DWORD dwReserved)
|
||||
{
|
||||
if (m_hWnd)
|
||||
{
|
||||
ShowWindow(SW_HIDE);
|
||||
|
||||
TBBUTTON tb;
|
||||
for (int i = 0; SendMessage(m_hWnd, TB_GETBUTTON, i, (LPARAM)&tb); i++)
|
||||
{
|
||||
CoTaskMemFree((LPITEMIDLIST)tb.dwData);
|
||||
}
|
||||
|
||||
DestroyWindow();
|
||||
m_hWnd = NULL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
|
||||
{
|
||||
/* No need to implement this method */
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::GetBandInfo(IN DWORD dwBandID, IN DWORD dwViewMode, IN OUT DESKBANDINFO *pdbi)
|
||||
{
|
||||
TRACE("CTaskBand::GetBandInfo(0x%x,0x%x,0x%p) hWnd=0x%p\n", dwBandID, dwViewMode, pdbi, m_hWnd);
|
||||
|
||||
if (m_hWnd && pdbi)
|
||||
{
|
||||
m_BandID = dwBandID;
|
||||
|
||||
RECT actualRect;
|
||||
POINTL actualSize;
|
||||
POINTL idealSize;
|
||||
POINTL maxSize;
|
||||
POINTL itemSize;
|
||||
|
||||
GetWindowRect(&actualRect);
|
||||
actualSize.x = actualRect.right - actualRect.left;
|
||||
actualSize.y = actualRect.bottom - actualRect.top;
|
||||
|
||||
// Obtain the ideal size, to be used as min and max
|
||||
SendMessageW(m_hWnd, TB_AUTOSIZE, 0, 0);
|
||||
SendMessageW(m_hWnd, TB_GETMAXSIZE, 0, reinterpret_cast<LPARAM>(&maxSize));
|
||||
|
||||
idealSize = maxSize;
|
||||
SendMessageW(m_hWnd, TB_GETIDEALSIZE, FALSE, reinterpret_cast<LPARAM>(&idealSize));
|
||||
|
||||
// Obtain the button size, to be used as the integral size
|
||||
DWORD size = SendMessageW(m_hWnd, TB_GETBUTTONSIZE, 0, 0);
|
||||
itemSize.x = GET_X_LPARAM(size);
|
||||
itemSize.y = GET_Y_LPARAM(size);
|
||||
|
||||
if (pdbi->dwMask & DBIM_MINSIZE)
|
||||
{
|
||||
pdbi->ptMinSize.x = -1;
|
||||
pdbi->ptMinSize.y = idealSize.y;
|
||||
}
|
||||
if (pdbi->dwMask & DBIM_MAXSIZE)
|
||||
{
|
||||
pdbi->ptMaxSize = maxSize;
|
||||
}
|
||||
if (pdbi->dwMask & DBIM_INTEGRAL)
|
||||
{
|
||||
pdbi->ptIntegral = itemSize;
|
||||
}
|
||||
if (pdbi->dwMask & DBIM_ACTUAL)
|
||||
{
|
||||
pdbi->ptActual = actualSize;
|
||||
}
|
||||
if (pdbi->dwMask & DBIM_TITLE)
|
||||
wcscpy(pdbi->wszTitle, L"Quick Launch");
|
||||
if (pdbi->dwMask & DBIM_MODEFLAGS)
|
||||
{
|
||||
pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT | DBIMF_USECHEVRON | DBIMF_NOMARGINS | DBIMF_BKCOLOR | DBIMF_ADDTOFRONT;
|
||||
}
|
||||
if (pdbi->dwMask & DBIM_BKCOLOR)
|
||||
pdbi->dwMask &= ~DBIM_BKCOLOR;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// *** IPersistStream ***
|
||||
STDMETHODIMP CISFBand::GetClassID(OUT CLSID *pClassID)
|
||||
{
|
||||
TRACE("CISFBand::GetClassID(0x%p)\n", pClassID);
|
||||
/* We're going to return the (internal!) CLSID of the quick launch band */
|
||||
*pClassID = CLSID_QuickLaunchBand;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::IsDirty()
|
||||
{
|
||||
/* The object hasn't changed since the last save! */
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::Load(IN IStream *pStm)
|
||||
{
|
||||
TRACE("CISFBand::Load called\n");
|
||||
/* Nothing to do */
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::Save(IN IStream *pStm, IN BOOL fClearDirty)
|
||||
{
|
||||
/* Nothing to do */
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::GetSizeMax(OUT ULARGE_INTEGER *pcbSize)
|
||||
{
|
||||
TRACE("CISFBand::GetSizeMax called\n");
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// *** IWinEventHandler ***
|
||||
STDMETHODIMP CISFBand::ContainsWindow(IN HWND hWnd)
|
||||
{
|
||||
if (hWnd == m_hWnd || IsChild(hWnd))
|
||||
{
|
||||
TRACE("CISFBand::ContainsWindow(0x%p) returns S_OK\n", hWnd);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_COMMAND:
|
||||
{
|
||||
TBBUTTON tb;
|
||||
bool chk = SendMessage(m_hWnd, TB_GETBUTTON, LOWORD(wParam), (LPARAM)&tb);
|
||||
if (chk)
|
||||
SHInvokeDefaultCommand(m_hWnd, m_pISF, (LPITEMIDLIST)tb.dwData);
|
||||
|
||||
*theResult = TRUE;
|
||||
break;
|
||||
}
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
switch (((LPNMHDR)lParam)->code)
|
||||
{
|
||||
case NM_RCLICK:
|
||||
{
|
||||
HRESULT hr;
|
||||
POINT pt = ((LPNMMOUSE)lParam)->pt;
|
||||
CComPtr<IContextMenu> picm;
|
||||
HMENU fmenu = CreatePopupMenu();
|
||||
TBBUTTON tb;
|
||||
|
||||
bool chk = SendMessage(m_hWnd, TB_GETBUTTON, ((LPNMMOUSE)lParam)->dwItemSpec, (LPARAM)&tb);
|
||||
LPITEMIDLIST pidl = (LPITEMIDLIST)tb.dwData;
|
||||
|
||||
if (chk)
|
||||
{
|
||||
ClientToScreen(&pt);
|
||||
hr = m_pISF->GetUIObjectOf(m_hWnd, 1, &pidl, IID_NULL_PPV_ARG(IContextMenu, &picm));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
hr = picm->QueryContextMenu(fmenu, 0, 1, 0x7FFF, CMF_DEFAULTONLY);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
int id = TrackPopupMenuEx(fmenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_RETURNCMD, pt.x, pt.y, m_hWnd, 0);
|
||||
if (id > 0)
|
||||
{
|
||||
CMINVOKECOMMANDINFOEX info = { 0 };
|
||||
info.cbSize = sizeof(info);
|
||||
info.fMask = CMIC_MASK_PTINVOKE;
|
||||
if (GetKeyState(VK_CONTROL) < 0)
|
||||
{
|
||||
info.fMask |= CMIC_MASK_CONTROL_DOWN;
|
||||
}
|
||||
if (GetKeyState(VK_SHIFT) < 0)
|
||||
{
|
||||
info.fMask |= CMIC_MASK_SHIFT_DOWN;
|
||||
}
|
||||
info.hwnd = m_hWnd;
|
||||
info.lpVerb = MAKEINTRESOURCEA(id - 1);
|
||||
info.nShow = SW_SHOWNORMAL;
|
||||
info.ptInvoke = pt;
|
||||
picm->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
|
||||
}
|
||||
}
|
||||
DestroyMenu(fmenu);
|
||||
|
||||
*theResult = TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
*theResult = FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
*theResult = FALSE;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::IsWindowOwner(HWND hWnd)
|
||||
{
|
||||
return (hWnd == m_hWnd) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// *** IOleCommandTarget methods ***
|
||||
STDMETHODIMP CISFBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
|
||||
{
|
||||
if (IsEqualIID(*pguidCmdGroup, IID_IBandSite))
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (IsEqualIID(*pguidCmdGroup, IID_IDeskBand))
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
UNIMPLEMENTED;
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// *** IShellFolderBand ***
|
||||
STDMETHODIMP CISFBand::GetBandInfoSFB(PBANDINFOSFB pbi)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::InitializeSFB(IShellFolder *psf, PCIDLIST_ABSOLUTE pidl)
|
||||
{
|
||||
if (_ILIsDesktop(pidl))
|
||||
{
|
||||
m_pISF = psf;
|
||||
m_pidl = ILClone(pidl);
|
||||
}
|
||||
else
|
||||
{
|
||||
psf->BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder, &m_pISF));
|
||||
m_pidl = ILClone(pidl);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::SetBandInfoSFB( PBANDINFOSFB pbi)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// *** IContextMenu ***
|
||||
STDMETHODIMP CISFBand::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT *pwReserved, LPSTR pszName, UINT cchMax)
|
||||
{
|
||||
/*HRESULT hr = E_INVALIDARG;
|
||||
|
||||
if (idCmd == IDM_DISPLAY)
|
||||
{
|
||||
switch (uFlags)
|
||||
{
|
||||
case GCS_HELPTEXTW:
|
||||
// Only useful for pre-Vista versions of Windows that
|
||||
// have a Status bar.
|
||||
hr = StringCchCopyW(reinterpret_cast<PWSTR>(pszName),
|
||||
cchMax,
|
||||
L"Display File Name");
|
||||
break;
|
||||
|
||||
case GCS_VERBW:
|
||||
// GCS_VERBW is an optional feature that enables a caller
|
||||
// to discover the canonical name for the verb that is passed in
|
||||
// through idCommand.
|
||||
hr = StringCchCopyW(reinterpret_cast<PWSTR>(pszName),
|
||||
cchMax,
|
||||
L"DisplayFileName");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return hr; */
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
|
||||
{
|
||||
if (!HIWORD(pici->lpVerb))
|
||||
{
|
||||
switch (LOWORD(pici->lpVerb))
|
||||
{
|
||||
case IDM_LARGE_ICONS:
|
||||
{
|
||||
m_iconFlag = false;
|
||||
|
||||
HIMAGELIST* piml = (HIMAGELIST*) SendMessage(m_hWnd, TB_GETIMAGELIST, 0, 0);
|
||||
HRESULT hr = SHGetImageList(SHIL_LARGE, IID_IImageList, (void**)&piml);
|
||||
if (FAILED_UNEXPECTEDLY(hr)) return hr;
|
||||
SendMessage(m_hWnd, TB_SETIMAGELIST, 0, (LPARAM)piml);
|
||||
hr = IUnknown_Exec(m_Site, IID_IDeskBand, DBID_BANDINFOCHANGED, 0, NULL, NULL);
|
||||
if (FAILED_UNEXPECTEDLY(hr)) return hr;
|
||||
break;
|
||||
}
|
||||
case IDM_SMALL_ICONS:
|
||||
{
|
||||
m_iconFlag = true;
|
||||
|
||||
HIMAGELIST* piml = (HIMAGELIST*)SendMessage(m_hWnd, TB_GETIMAGELIST, 0, 0);
|
||||
HRESULT hr = SHGetImageList(SHIL_SMALL, IID_IImageList, (void**)&piml);
|
||||
if (FAILED_UNEXPECTEDLY(hr)) return hr;
|
||||
SendMessage(m_hWnd, TB_SETIMAGELIST, 0, (LPARAM)piml);
|
||||
hr = IUnknown_Exec(m_Site, IID_IDeskBand, DBID_BANDINFOCHANGED, 0, NULL, NULL);
|
||||
if (FAILED_UNEXPECTEDLY(hr)) return hr;
|
||||
break;
|
||||
}
|
||||
case IDM_SHOW_TEXT:
|
||||
{
|
||||
if (m_textFlag)
|
||||
{
|
||||
m_textFlag = false;
|
||||
SendMessage(m_hWnd, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS);
|
||||
HRESULT hr = IUnknown_Exec(m_Site, IID_IDeskBand, DBID_BANDINFOCHANGED, 0, NULL, NULL);
|
||||
if (FAILED_UNEXPECTEDLY(hr)) return hr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_textFlag = true;
|
||||
SendMessage(m_hWnd, TB_SETEXTENDEDSTYLE, 0, 0);
|
||||
HRESULT hr = IUnknown_Exec(m_Site, IID_IDeskBand, DBID_BANDINFOCHANGED, 0, NULL, NULL);
|
||||
if (FAILED_UNEXPECTEDLY(hr)) return hr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CISFBand::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
|
||||
{
|
||||
HMENU qMenu = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_POPUPMENU));
|
||||
if(m_textFlag)
|
||||
CheckMenuItem(qMenu, IDM_SHOW_TEXT, MF_CHECKED);
|
||||
else
|
||||
CheckMenuItem(qMenu, IDM_SHOW_TEXT, MF_UNCHECKED);
|
||||
|
||||
if (m_iconFlag)
|
||||
{
|
||||
CheckMenuItem(qMenu, IDM_SMALL_ICONS, MF_CHECKED);
|
||||
CheckMenuItem(qMenu, IDM_LARGE_ICONS, MF_UNCHECKED);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckMenuItem(qMenu, IDM_LARGE_ICONS, MF_CHECKED);
|
||||
CheckMenuItem(qMenu, IDM_SMALL_ICONS, MF_UNCHECKED);
|
||||
}
|
||||
|
||||
UINT idMax = Shell_MergeMenus(hmenu, GetSubMenu(qMenu, 0), indexMenu, idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS);
|
||||
DestroyMenu(qMenu);
|
||||
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(idMax - idCmdFirst +1));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// C Constructor
|
||||
extern "C"
|
||||
HRESULT WINAPI CISFBand_CreateInstance(REFIID riid, void** ppv)
|
||||
{
|
||||
return ShellObjectCreator<CISFBand>(riid, ppv);
|
||||
}
|
||||
|
196
reactos/dll/shellext/qcklnch/CISFBand.h
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* PROJECT: ReactOS shell extensions
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: dll/shellext/qcklnch/CISFBand.h
|
||||
* PURPOSE: Quick Launch Toolbar (Taskbar Shell Extension)
|
||||
* PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com>
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// COM class for cisfband
|
||||
class CISFBand :
|
||||
public CWindow,
|
||||
public CComCoClass<CISFBand>,
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
public IObjectWithSite,
|
||||
public IDeskBand,
|
||||
public IPersistStream,
|
||||
public IWinEventHandler,
|
||||
public IOleCommandTarget,
|
||||
public IShellFolderBand,
|
||||
public IContextMenu
|
||||
{
|
||||
// Band
|
||||
DWORD m_BandID;
|
||||
CComPtr<IUnknown> m_Site;
|
||||
|
||||
// Toolbar
|
||||
CComPtr<IShellFolder> m_pISF;
|
||||
PCIDLIST_ABSOLUTE m_pidl;
|
||||
|
||||
// Menu
|
||||
BOOL m_textFlag;
|
||||
BOOL m_iconFlag;
|
||||
|
||||
public:
|
||||
|
||||
CISFBand();
|
||||
virtual ~CISFBand();
|
||||
|
||||
// Personal Methods
|
||||
HRESULT CreateSimpleToolbar(HWND hWndParent);
|
||||
|
||||
// IObjectWithSite
|
||||
|
||||
virtual STDMETHODIMP GetSite(
|
||||
IN REFIID riid,
|
||||
OUT void **ppvSite
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP SetSite(
|
||||
IN IUnknown *pUnkSite
|
||||
);
|
||||
|
||||
// IDeskBand
|
||||
|
||||
virtual STDMETHODIMP GetWindow(
|
||||
OUT HWND *phwnd
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP ContextSensitiveHelp(
|
||||
IN BOOL fEnterMode
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP ShowDW(
|
||||
IN BOOL bShow
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP CloseDW(
|
||||
IN DWORD dwReserved
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP ResizeBorderDW(
|
||||
LPCRECT prcBorder,
|
||||
IUnknown *punkToolbarSite,
|
||||
BOOL fReserved
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP GetBandInfo(
|
||||
IN DWORD dwBandID,
|
||||
IN DWORD dwViewMode,
|
||||
IN OUT DESKBANDINFO *pdbi
|
||||
);
|
||||
|
||||
// IPersistStream
|
||||
|
||||
virtual STDMETHODIMP GetClassID(
|
||||
OUT CLSID *pClassID
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP GetSizeMax(
|
||||
OUT ULARGE_INTEGER *pcbSize
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP IsDirty();
|
||||
|
||||
virtual STDMETHODIMP Load(
|
||||
IN IStream *pStm
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP Save(
|
||||
IN IStream *pStm,
|
||||
IN BOOL fClearDirty
|
||||
);
|
||||
|
||||
// IWinEventHandler
|
||||
|
||||
virtual STDMETHODIMP ContainsWindow(
|
||||
IN HWND hWnd
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP OnWinEvent(
|
||||
HWND hWnd,
|
||||
UINT uMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
LRESULT *theResult
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP IsWindowOwner(
|
||||
HWND hWnd
|
||||
);
|
||||
|
||||
// IOleCommandTarget
|
||||
|
||||
virtual STDMETHODIMP Exec(
|
||||
IN const GUID *pguidCmdGroup,
|
||||
IN DWORD nCmdID,
|
||||
IN DWORD nCmdexecopt,
|
||||
IN VARIANT *pvaIn,
|
||||
IN OUT VARIANT *pvaOut
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP QueryStatus(
|
||||
IN const GUID *pguidCmdGroup,
|
||||
IN ULONG cCmds,
|
||||
IN OUT OLECMD prgCmds[],
|
||||
IN OUT OLECMDTEXT *pCmdText
|
||||
);
|
||||
|
||||
// IShellFolderBand
|
||||
virtual STDMETHODIMP GetBandInfoSFB(
|
||||
PBANDINFOSFB pbi
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP InitializeSFB(
|
||||
IShellFolder *psf,
|
||||
PCIDLIST_ABSOLUTE pidl
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP SetBandInfoSFB(
|
||||
PBANDINFOSFB pbi
|
||||
);
|
||||
|
||||
// IContextMenu
|
||||
virtual STDMETHODIMP GetCommandString(
|
||||
UINT_PTR idCmd,
|
||||
UINT uFlags,
|
||||
UINT *pwReserved,
|
||||
LPSTR pszName,
|
||||
UINT cchMax
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP InvokeCommand(
|
||||
LPCMINVOKECOMMANDINFO pici
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP QueryContextMenu(
|
||||
HMENU hmenu,
|
||||
UINT indexMenu,
|
||||
UINT idCmdFirst,
|
||||
UINT idCmdLast,
|
||||
UINT uFlags
|
||||
);
|
||||
|
||||
//*****************************************************************************************************
|
||||
|
||||
DECLARE_NOT_AGGREGATABLE(CISFBand)
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
BEGIN_COM_MAP(CISFBand)
|
||||
COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, IDeskBand)
|
||||
COM_INTERFACE_ENTRY2_IID(IID_IDockingWindow, IDockingWindow, IDeskBand)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler, IWinEventHandler)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IShellFolderBand, IShellFolderBand)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
|
||||
END_COM_MAP()
|
||||
};
|
||||
|
||||
// C Constructor
|
||||
extern "C"
|
||||
HRESULT WINAPI CISFBand_CreateInstance(REFIID riid, void** ppv);
|
43
reactos/dll/shellext/qcklnch/CMakeLists.txt
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
project(SHELL)
|
||||
|
||||
set_cpp(WITH_RUNTIME)
|
||||
|
||||
if(NOT MSVC)
|
||||
# HACK: this should be enabled globally!
|
||||
add_compile_flags_language("-std=c++11" "CXX")
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${REACTOS_SOURCE_DIR}/sdk/lib/atl
|
||||
${REACTOS_SOURCE_DIR})
|
||||
|
||||
spec2def(qcklnch.dll qcklnch.spec)
|
||||
|
||||
add_library(qcklnch SHARED
|
||||
qcklnch.rc
|
||||
qcklnch.cpp
|
||||
CQuickLaunchBand.cpp
|
||||
CISFBand.cpp
|
||||
CQuickLaunchBand.h
|
||||
CISFBand.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/qcklnch.def)
|
||||
|
||||
set_module_type(qcklnch win32dll UNICODE)
|
||||
target_link_libraries(qcklnch uuid wine atlnew)
|
||||
|
||||
add_importlibs(qcklnch
|
||||
advapi32
|
||||
winmm
|
||||
ole32
|
||||
oleaut32
|
||||
shlwapi
|
||||
shell32
|
||||
comctl32
|
||||
msvcrt
|
||||
gdi32
|
||||
user32
|
||||
kernel32
|
||||
ntdll)
|
||||
|
||||
add_cd_file(TARGET qcklnch DESTINATION reactos/system32 FOR all)
|
361
reactos/dll/shellext/qcklnch/CQuickLaunchBand.cpp
Normal file
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
* PROJECT: ReactOS shell extensions
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: dll/shellext/qcklnch/CQuickLaunchBand.cpp
|
||||
* PURPOSE: Quick Launch Toolbar (Taskbar Shell Extension)
|
||||
* PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com>
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(qcklnch);
|
||||
|
||||
// {260CB95D-4544-44F6-A079-575BAA60B72F}
|
||||
static const GUID CLSID_QuickLaunchBand = { 0x260cb95d, 0x4544, 0x44f6, { 0xa0, 0x79, 0x57, 0x5b, 0xaa, 0x60, 0xb7, 0x2f } };
|
||||
|
||||
// Componenet Category Registration
|
||||
HRESULT RegisterComCat()
|
||||
{
|
||||
CComPtr<ICatRegister> pcr;
|
||||
HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(ICatRegister, &pcr));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
CATID catid = CATID_DeskBand;
|
||||
hr = pcr->RegisterClassImplCategories(CLSID_QuickLaunchBand, 1, &catid);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT UnregisterComCat()
|
||||
{
|
||||
CComPtr<ICatRegister> pcr;
|
||||
HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(ICatRegister, &pcr));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
CATID catid = CATID_DeskBand;
|
||||
hr = pcr->UnRegisterClassImplCategories(CLSID_QuickLaunchBand, 1, &catid);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Pidl Browser
|
||||
/*++
|
||||
* @name PidlBrowse
|
||||
*
|
||||
* Opens a folder browser dialog,
|
||||
* allowing the user to select a folder for enumeration.
|
||||
*
|
||||
* @param hwnd
|
||||
* A handle to browser dialog window.
|
||||
* @param nCSIDL
|
||||
* A CSIDL representing the root from which the browse folder dialog shows the files and folders.
|
||||
*
|
||||
* @return The PIDL to selected folder.
|
||||
*
|
||||
*--*/
|
||||
LPITEMIDLIST PidlBrowse(HWND hwnd, int nCSIDL)
|
||||
{
|
||||
CComHeapPtr<ITEMIDLIST> pidlRoot;
|
||||
|
||||
WCHAR path[MAX_PATH];
|
||||
|
||||
if (nCSIDL)
|
||||
{
|
||||
SHGetSpecialFolderLocation(hwnd, nCSIDL, &pidlRoot);
|
||||
}
|
||||
|
||||
CString biTitle((LPCSTR)IDS_BROWSEINFO_TITLE);
|
||||
BROWSEINFO bi = { hwnd, pidlRoot, path, biTitle, 0, NULL, 0, 0 };
|
||||
LPITEMIDLIST pidlSelected = SHBrowseForFolder(&bi);
|
||||
|
||||
return pidlSelected;
|
||||
}
|
||||
|
||||
// CQuickLaunchBand
|
||||
|
||||
CQuickLaunchBand::CQuickLaunchBand() {}
|
||||
|
||||
CQuickLaunchBand::~CQuickLaunchBand() {}
|
||||
|
||||
/*****************************************************************************/
|
||||
// ATL Construct
|
||||
/*++
|
||||
* @name FinalConstruct
|
||||
*
|
||||
* Creates an instance of CISFBand, and initializes its Shell Folder Band for enumeration.
|
||||
*
|
||||
* @return The error code.
|
||||
*
|
||||
*--*/
|
||||
HRESULT CQuickLaunchBand::FinalConstruct()
|
||||
{
|
||||
HRESULT hr = CISFBand_CreateInstance(IID_PPV_ARG(IUnknown, &m_punkISFB));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
CComPtr<IShellFolderBand> pISFB;
|
||||
hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IShellFolderBand, &pISFB));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
CComPtr<IShellFolder> pISF;
|
||||
hr = SHGetDesktopFolder(&pISF);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
CComHeapPtr<ITEMIDLIST> pidl(PidlBrowse(m_hWndBro, CSIDL_DESKTOP));
|
||||
if (pidl == NULL)
|
||||
return E_FAIL;
|
||||
pISFB->InitializeSFB(pISF, pidl);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
// IObjectWithSite
|
||||
STDMETHODIMP CQuickLaunchBand::SetSite(IUnknown *pUnkSite)
|
||||
{
|
||||
TRACE("CQuickLaunchBand::SetSite(0x%p)\n", pUnkSite);
|
||||
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IObjectWithSite> pIOWS;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IObjectWithSite, &pIOWS));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pIOWS->SetSite(pUnkSite);
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::GetSite(IN REFIID riid, OUT VOID **ppvSite)
|
||||
{
|
||||
TRACE("CQuickLaunchBand::GetSite(0x%p,0x%p)\n", riid, ppvSite);
|
||||
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IObjectWithSite> pIOWS;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IObjectWithSite, &pIOWS));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pIOWS->GetSite(riid, ppvSite);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// IDeskBand
|
||||
STDMETHODIMP CQuickLaunchBand::GetWindow(OUT HWND *phwnd)
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IDeskBand> pIDB;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pIDB->GetWindow(phwnd);
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::ContextSensitiveHelp(IN BOOL fEnterMode)
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IDeskBand> pIDB;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pIDB->ContextSensitiveHelp(fEnterMode);
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::ShowDW(IN BOOL bShow)
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IDeskBand> pIDB;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pIDB->ShowDW(bShow);
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::CloseDW(IN DWORD dwReserved)
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IDeskBand> pIDB;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pIDB->CloseDW(dwReserved);
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IDeskBand> pIDB;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pIDB->ResizeBorderDW(prcBorder, punkToolbarSite, fReserved);
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::GetBandInfo(IN DWORD dwBandID, IN DWORD dwViewMode, IN OUT DESKBANDINFO *pdbi)
|
||||
{
|
||||
TRACE("CQuickLaunchBand::GetBandInfo(0x%x,0x%x,0x%p)\n", dwBandID, dwViewMode, pdbi);
|
||||
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IDeskBand> pIDB;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pIDB->GetBandInfo(dwBandID, dwViewMode, pdbi);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// IPersistStream
|
||||
STDMETHODIMP CQuickLaunchBand::GetClassID(OUT CLSID *pClassID)
|
||||
{
|
||||
TRACE("CQuickLaunchBand::GetClassID(0x%p)\n", pClassID);
|
||||
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IPersistStream> pIPS;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream, &pIPS));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pIPS->GetClassID(pClassID);
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::IsDirty()
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IPersistStream> pIPS;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream, &pIPS));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pIPS->IsDirty();
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::Load(IN IStream *pStm)
|
||||
{
|
||||
TRACE("CQuickLaunchBand::Load called\n");
|
||||
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IPersistStream> pIPS;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream, &pIPS));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pIPS->Load(pStm);
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::Save(IN IStream *pStm, IN BOOL fClearDirty)
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IPersistStream> pIPS;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream, &pIPS));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pIPS->Save(pStm, fClearDirty);
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::GetSizeMax(OUT ULARGE_INTEGER *pcbSize)
|
||||
{
|
||||
TRACE("CQuickLaunchBand::GetSizeMax called\n");
|
||||
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IPersistStream> pIPS;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream, &pIPS));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pIPS->GetSizeMax(pcbSize);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
// IWinEventHandler
|
||||
STDMETHODIMP CQuickLaunchBand::ContainsWindow(IN HWND hWnd)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IWinEventHandler> pWEH;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IWinEventHandler, &pWEH));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pWEH->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::IsWindowOwner(HWND hWnd)
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IWinEventHandler> pWEH;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IWinEventHandler, &pWEH));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pWEH->IsWindowOwner(hWnd);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// *** IOleCommandTarget methods ***
|
||||
STDMETHODIMP CQuickLaunchBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IOleCommandTarget> pOCT;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &pOCT));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pOCT->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IOleCommandTarget> pOCT;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &pOCT));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pOCT->Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// *** IContextMenu ***
|
||||
STDMETHODIMP CQuickLaunchBand::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT *pwReserved, LPSTR pszName, UINT cchMax)
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IContextMenu> pICM;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IContextMenu, &pICM));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pICM->GetCommandString(idCmd, uFlags, pwReserved, pszName, cchMax);
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IContextMenu> pICM;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IContextMenu, &pICM));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pICM->InvokeCommand(pici);
|
||||
}
|
||||
|
||||
STDMETHODIMP CQuickLaunchBand::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
|
||||
{
|
||||
// Internal CISFBand Calls
|
||||
CComPtr<IContextMenu> pICM;
|
||||
HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IContextMenu, &pICM));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return pICM->QueryContextMenu(hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
|
||||
}
|
174
reactos/dll/shellext/qcklnch/CQuickLaunchBand.h
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* PROJECT: ReactOS shell extensions
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: dll/shellext/qcklnch/CQuickLaunchBand.h
|
||||
* PURPOSE: Quick Launch Toolbar (Taskbar Shell Extension)
|
||||
* PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com>
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
extern const GUID CLSID_QuickLaunchBand;
|
||||
|
||||
// Component category registration
|
||||
HRESULT RegisterComCat();
|
||||
HRESULT UnregisterComCat();
|
||||
|
||||
// COM class for quick launch
|
||||
class CQuickLaunchBand :
|
||||
public CComCoClass<CQuickLaunchBand, &CLSID_QuickLaunchBand>,
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
public IObjectWithSite,
|
||||
public IDeskBand,
|
||||
public IPersistStream,
|
||||
public IWinEventHandler,
|
||||
public IOleCommandTarget,
|
||||
public IContextMenu
|
||||
{
|
||||
HWND m_hWndBro;
|
||||
CComPtr<IUnknown> m_punkISFB;
|
||||
|
||||
public:
|
||||
|
||||
CQuickLaunchBand();
|
||||
virtual ~CQuickLaunchBand();
|
||||
|
||||
// ATL construct
|
||||
|
||||
HRESULT FinalConstruct();
|
||||
|
||||
// IObjectWithSite
|
||||
|
||||
virtual STDMETHODIMP GetSite(
|
||||
IN REFIID riid,
|
||||
OUT void **ppvSite
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP SetSite(
|
||||
IN IUnknown *pUnkSite
|
||||
);
|
||||
|
||||
// IDeskBand
|
||||
|
||||
virtual STDMETHODIMP GetWindow(
|
||||
OUT HWND *phwnd
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP ContextSensitiveHelp(
|
||||
IN BOOL fEnterMode
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP ShowDW(
|
||||
IN BOOL bShow
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP CloseDW(
|
||||
IN DWORD dwReserved
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP ResizeBorderDW(
|
||||
LPCRECT prcBorder,
|
||||
IUnknown *punkToolbarSite,
|
||||
BOOL fReserved
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP GetBandInfo(
|
||||
IN DWORD dwBandID,
|
||||
IN DWORD dwViewMode,
|
||||
IN OUT DESKBANDINFO *pdbi
|
||||
);
|
||||
|
||||
// IPersistStream
|
||||
|
||||
virtual STDMETHODIMP GetClassID(
|
||||
OUT CLSID *pClassID
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP GetSizeMax(
|
||||
OUT ULARGE_INTEGER *pcbSize
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP IsDirty();
|
||||
|
||||
virtual STDMETHODIMP Load(
|
||||
IN IStream *pStm
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP Save(
|
||||
IN IStream *pStm,
|
||||
IN BOOL fClearDirty
|
||||
);
|
||||
|
||||
// IWinEventHandler
|
||||
|
||||
virtual STDMETHODIMP ContainsWindow(
|
||||
IN HWND hWnd
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP OnWinEvent(
|
||||
HWND hWnd,
|
||||
UINT uMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
LRESULT *theResult
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP IsWindowOwner(
|
||||
HWND hWnd
|
||||
);
|
||||
|
||||
// IOleCommandTarget
|
||||
|
||||
virtual STDMETHODIMP Exec(
|
||||
IN const GUID *pguidCmdGroup,
|
||||
IN DWORD nCmdID,
|
||||
IN DWORD nCmdexecopt,
|
||||
IN VARIANT *pvaIn,
|
||||
IN OUT VARIANT *pvaOut
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP QueryStatus(
|
||||
IN const GUID *pguidCmdGroup,
|
||||
IN ULONG cCmds,
|
||||
IN OUT OLECMD prgCmds[],
|
||||
IN OUT OLECMDTEXT *pCmdText
|
||||
);
|
||||
|
||||
// IContextMenu
|
||||
virtual STDMETHODIMP GetCommandString(
|
||||
UINT_PTR idCmd,
|
||||
UINT uFlags,
|
||||
UINT *pwReserved,
|
||||
LPSTR pszName,
|
||||
UINT cchMax
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP InvokeCommand(
|
||||
LPCMINVOKECOMMANDINFO pici
|
||||
);
|
||||
|
||||
virtual STDMETHODIMP QueryContextMenu(
|
||||
HMENU hmenu,
|
||||
UINT indexMenu,
|
||||
UINT idCmdFirst,
|
||||
UINT idCmdLast,
|
||||
UINT uFlags
|
||||
);
|
||||
|
||||
//*****************************************************************************************************
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_QCKLNCH)
|
||||
DECLARE_NOT_AGGREGATABLE(CQuickLaunchBand)
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
BEGIN_COM_MAP(CQuickLaunchBand)
|
||||
COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, IDeskBand)
|
||||
COM_INTERFACE_ENTRY2_IID(IID_IDockingWindow, IDockingWindow, IDeskBand)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler, IWinEventHandler)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
|
||||
END_COM_MAP()
|
||||
};
|
19
reactos/dll/shellext/qcklnch/lang/en-US.rc
Normal file
@@ -0,0 +1,19 @@
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
IDM_POPUPMENU MENUEX DISCARDABLE
|
||||
BEGIN
|
||||
POPUP ""
|
||||
BEGIN
|
||||
POPUP "&View", IDM_VIEW_MENU
|
||||
BEGIN
|
||||
MENUITEM "&Large Icons", IDM_LARGE_ICONS
|
||||
MENUITEM "&Small Icons", IDM_SMALL_ICONS
|
||||
END
|
||||
MENUITEM "&Show Text", IDM_SHOW_TEXT
|
||||
END
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_BROWSEINFO_TITLE "Choose a folder"
|
||||
END
|
41
reactos/dll/shellext/qcklnch/precomp.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#include <stdarg.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define WIN32_NO_STATUS
|
||||
#define _INC_WINDOWS
|
||||
#define COM_NO_WINDOWS_H
|
||||
#define NTOS_MODE_USER
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <winreg.h>
|
||||
#include <winuser.h>
|
||||
#include <wincon.h>
|
||||
#include <ddeml.h>
|
||||
#include <shlguid_undoc.h>
|
||||
#include <shlwapi.h>
|
||||
#include <shlguid.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlobj_undoc.h>
|
||||
#include <shlwapi_undoc.h>
|
||||
#include <tchar.h>
|
||||
#include <strsafe.h>
|
||||
#include <atlbase.h>
|
||||
#include <atlcom.h>
|
||||
#include <atlwin.h>
|
||||
#include <atlstr.h>
|
||||
#include <undocshell.h>
|
||||
#include <shellutils.h>
|
||||
|
||||
#include <shellapi.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
#include <wine/unicode.h>
|
||||
|
||||
#include "resource.h"
|
||||
#include "CQuickLaunchBand.h"
|
||||
#include "CISFBand.h"
|
70
reactos/dll/shellext/qcklnch/qcklnch.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* PROJECT: ReactOS shell extensions
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: dll/shellext/qcklnch/qcklnch.cpp
|
||||
* PURPOSE: Quick Launch Toolbar (Taskbar Shell Extension)
|
||||
* PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com>
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#include <atlwin.h>
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(qcklnch);
|
||||
|
||||
BEGIN_OBJECT_MAP(ObjectMap)
|
||||
OBJECT_ENTRY(CLSID_QuickLaunchBand, CQuickLaunchBand)
|
||||
END_OBJECT_MAP()
|
||||
|
||||
HINSTANCE g_hInstance;
|
||||
CComModule g_Module;
|
||||
|
||||
STDAPI_(BOOL)
|
||||
DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
||||
{
|
||||
if (fdwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
g_hInstance = hinstDLL;
|
||||
DisableThreadLibraryCalls(g_hInstance);
|
||||
|
||||
g_Module.Init(ObjectMap, g_hInstance, NULL);
|
||||
}
|
||||
else if (fdwReason == DLL_PROCESS_DETACH)
|
||||
{
|
||||
g_hInstance = NULL;
|
||||
g_Module.Term();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STDAPI
|
||||
DllRegisterServer(void)
|
||||
{
|
||||
HRESULT hr = g_Module.DllRegisterServer(FALSE);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return RegisterComCat();
|
||||
}
|
||||
|
||||
STDAPI
|
||||
DllUnregisterServer(void)
|
||||
{
|
||||
HRESULT hr = UnregisterComCat();
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return g_Module.DllUnregisterServer(FALSE);
|
||||
}
|
||||
|
||||
STDAPI
|
||||
DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
return g_Module.DllGetClassObject(rclsid, riid, ppv);
|
||||
}
|
||||
|
||||
STDAPI
|
||||
DllCanUnloadNow(void)
|
||||
{
|
||||
return g_Module.DllCanUnloadNow();
|
||||
}
|
15
reactos/dll/shellext/qcklnch/qcklnch.rc
Normal file
@@ -0,0 +1,15 @@
|
||||
#include <windef.h>
|
||||
#include <winuser.h>
|
||||
#include <commctrl.h>
|
||||
#include "resource.h"
|
||||
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
|
||||
IDR_QCKLNCH REGISTRY "rgs/qcklnch.rgs"
|
||||
|
||||
#include <reactos/manifest_dll.rc>
|
||||
|
||||
#ifdef LANGUAGE_EN_US
|
||||
#include "lang/en-US.rc"
|
||||
#endif
|
||||
|
4
reactos/dll/shellext/qcklnch/qcklnch.spec
Normal file
@@ -0,0 +1,4 @@
|
||||
@ stdcall -private DllCanUnloadNow()
|
||||
@ stdcall -private DllGetClassObject(ptr ptr ptr)
|
||||
@ stdcall -private DllRegisterServer()
|
||||
@ stdcall -private DllUnregisterServer()
|
11
reactos/dll/shellext/qcklnch/resource.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#define IDR_QCKLNCH 1001
|
||||
|
||||
#define IDM_POPUPMENU 2001
|
||||
#define IDM_LARGE_ICONS 1
|
||||
#define IDM_SMALL_ICONS 2
|
||||
#define IDM_SHOW_TEXT 3
|
||||
#define IDM_VIEW_MENU 4
|
||||
|
||||
#define IDS_BROWSEINFO_TITLE 101
|
13
reactos/dll/shellext/qcklnch/rgs/qcklnch.rgs
Normal file
@@ -0,0 +1,13 @@
|
||||
HKCR
|
||||
{
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {260CB95D-4544-44F6-A079-575BAA60B72F} = s 'Quick Launch'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'Apartment'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -23,12 +23,14 @@ add_library(stobject SHARED
|
||||
stobject.rc
|
||||
power.cpp
|
||||
volume.cpp
|
||||
hotplug.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/stobject.def)
|
||||
|
||||
set_module_type(stobject win32dll UNICODE)
|
||||
target_link_libraries(stobject uuid wine atlnew)
|
||||
|
||||
add_importlibs(stobject
|
||||
setupapi
|
||||
advapi32
|
||||
winmm
|
||||
ole32
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* FILE: dll/shellext/stobject/csystray.cpp
|
||||
* PURPOSE: Systray shell service object implementation
|
||||
* PROGRAMMERS: David Quintana <gigaherz@gmail.com>
|
||||
* Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com>
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
@@ -12,7 +13,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(stobject);
|
||||
|
||||
SysTrayIconHandlers_t g_IconHandlers [] = {
|
||||
{ Volume_Init, Volume_Shutdown, Volume_Update, Volume_Message },
|
||||
{ Power_Init, Power_Shutdown, Power_Update, Power_Message }
|
||||
{ Power_Init, Power_Shutdown, Power_Update, Power_Message },
|
||||
{ Hotplug_Init, Hotplug_Shutdown, Hotplug_Update, Hotplug_Message }
|
||||
};
|
||||
const int g_NumIcons = _countof(g_IconHandlers);
|
||||
|
||||
@@ -96,7 +98,27 @@ HRESULT CSysTray::ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, LR
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT CSysTray::NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip)
|
||||
/*++
|
||||
* @name NotifyIcon
|
||||
*
|
||||
* Basically a Shell_NotifyIcon wrapper.
|
||||
* Based on the parameters provided, it changes the current state of the notification icon.
|
||||
*
|
||||
* @param code
|
||||
* Determines whether to add, delete or modify the notification icon (represented by uId).
|
||||
* @param uId
|
||||
* Represents the particular notification icon.
|
||||
* @param hIcon
|
||||
* A handle to an icon for the notification object.
|
||||
* @param szTip
|
||||
* A string for the tooltip of the notification.
|
||||
* @param dwstate
|
||||
* Determines whether to show or hide the notification icon.
|
||||
*
|
||||
* @return The error code.
|
||||
*
|
||||
*--*/
|
||||
HRESULT CSysTray::NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip, DWORD dwstate)
|
||||
{
|
||||
NOTIFYICONDATA nim = { 0 };
|
||||
|
||||
@@ -107,8 +129,8 @@ HRESULT CSysTray::NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip)
|
||||
nim.hIcon = hIcon;
|
||||
nim.uID = uId;
|
||||
nim.uCallbackMessage = uId;
|
||||
nim.dwState = 0;
|
||||
nim.dwStateMask = 0;
|
||||
nim.dwState = dwstate;
|
||||
nim.dwStateMask = NIS_HIDDEN;
|
||||
nim.hWnd = m_hWnd;
|
||||
nim.uVersion = NOTIFYICON_VERSION;
|
||||
if (szTip)
|
||||
@@ -143,7 +165,7 @@ HRESULT CSysTray::SysTrayMessageLoop()
|
||||
}
|
||||
|
||||
HRESULT CSysTray::SysTrayThreadProc()
|
||||
{
|
||||
{
|
||||
WCHAR strFileName[MAX_PATH];
|
||||
GetModuleFileNameW(g_hInstance, strFileName, MAX_PATH);
|
||||
HMODULE hLib = LoadLibraryW(strFileName);
|
||||
|
@@ -5,6 +5,7 @@
|
||||
* PURPOSE: Systray shell service object
|
||||
* PROGRAMMERS: Robert Naumann
|
||||
* David Quintana <gigaherz@gmail.com>
|
||||
* Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com>
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -43,7 +44,7 @@ class CSysTray :
|
||||
HRESULT ShutdownNetShell();
|
||||
|
||||
public:
|
||||
HRESULT NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip);
|
||||
HRESULT NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip, DWORD dwstate = 0);
|
||||
|
||||
HWND GetHWnd() { return m_hWnd; }
|
||||
|
||||
|
356
reactos/dll/shellext/stobject/hotplug.cpp
Normal file
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* PROJECT: ReactOS system libraries
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: dll/shellext/stobject/hotplug.cpp
|
||||
* PURPOSE: Removable devices notification icon handler
|
||||
* PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com>
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include "precomp.h"
|
||||
#include <mmsystem.h>
|
||||
#include <mmddk.h>
|
||||
#include <atlstr.h>
|
||||
#include <atlsimpcoll.h>
|
||||
#include <dbt.h>
|
||||
#include <setupapi.h>
|
||||
#include <cfgmgr32.h>
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(stobject);
|
||||
#define DISPLAY_NAME_LEN 40
|
||||
|
||||
//BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY Handle);
|
||||
|
||||
CSimpleArray<DEVINST> g_devList;
|
||||
static HDEVNOTIFY g_hDevNotify = NULL;
|
||||
static HICON g_hIconHotplug = NULL;
|
||||
static LPWSTR g_strTooltip = L"Safely Remove Hardware and Eject Media";
|
||||
static WCHAR g_strMenuSel[DISPLAY_NAME_LEN];
|
||||
static BOOL g_IsRunning = FALSE;
|
||||
static BOOL g_IsRemoving = FALSE;
|
||||
|
||||
/*++
|
||||
* @name EnumHotpluggedDevices
|
||||
*
|
||||
* Enumerates the connected safely removable devices.
|
||||
*
|
||||
* @param devList
|
||||
* List of device instances, representing the currently attached devices.
|
||||
*
|
||||
* @return The error code.
|
||||
*
|
||||
*--*/
|
||||
HRESULT EnumHotpluggedDevices(CSimpleArray<DEVINST> &devList)
|
||||
{
|
||||
devList.RemoveAll(); // Clear current devList
|
||||
HDEVINFO hdev = SetupDiGetClassDevs(NULL, NULL, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT);
|
||||
if (INVALID_HANDLE_VALUE == hdev)
|
||||
return E_HANDLE;
|
||||
SP_DEVINFO_DATA did = { 0 };
|
||||
did.cbSize = sizeof(did);
|
||||
|
||||
// Enumerate all the attached devices.
|
||||
for (int idev = 0; SetupDiEnumDeviceInfo(hdev, idev, &did); idev++)
|
||||
{
|
||||
DWORD dwCapabilities = 0, dwSize = sizeof(dwCapabilities);
|
||||
WCHAR dispName[DISPLAY_NAME_LEN];
|
||||
ULONG ulStatus = 0, ulPnum = 0, ulLength = DISPLAY_NAME_LEN * sizeof(WCHAR);
|
||||
CONFIGRET cr = CM_Get_DevNode_Status(&ulStatus, &ulPnum, did.DevInst, 0);
|
||||
if (cr != CR_SUCCESS)
|
||||
continue;
|
||||
cr = CM_Get_DevNode_Registry_Property(did.DevInst, CM_DRP_DEVICEDESC, NULL, dispName, &ulLength, 0);
|
||||
if (cr != CR_SUCCESS)
|
||||
continue;
|
||||
cr = CM_Get_DevNode_Registry_Property(did.DevInst, CM_DRP_CAPABILITIES, NULL, &dwCapabilities, &dwSize, 0);
|
||||
if (cr != CR_SUCCESS)
|
||||
continue;
|
||||
|
||||
// Filter and make list of only the appropriate safely removable devices.
|
||||
if ( (dwCapabilities & CM_DEVCAP_REMOVABLE) &&
|
||||
!(dwCapabilities & CM_DEVCAP_DOCKDEVICE) &&
|
||||
!(dwCapabilities & CM_DEVCAP_SURPRISEREMOVALOK) &&
|
||||
((dwCapabilities & CM_DEVCAP_EJECTSUPPORTED) || (ulStatus & DN_DISABLEABLE)) &&
|
||||
!ulPnum)
|
||||
{
|
||||
devList.Add(did.DevInst);
|
||||
}
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(hdev);
|
||||
|
||||
if (NO_ERROR != GetLastError() && ERROR_NO_MORE_ITEMS != GetLastError())
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name NotifyBalloon
|
||||
*
|
||||
* Pops the balloon notification of the given notification icon.
|
||||
*
|
||||
* @param pSysTray
|
||||
* Provides interface for acquiring CSysTray information as required.
|
||||
* @param szTitle
|
||||
* Title for the balloon notification.
|
||||
* @param szInfo
|
||||
* Main content for the balloon notification.
|
||||
* @param uId
|
||||
* Represents the particular notification icon.
|
||||
*
|
||||
* @return The error code.
|
||||
*
|
||||
*--*/
|
||||
HRESULT NotifyBalloon(CSysTray* pSysTray, LPCWSTR szTitle = NULL, LPCWSTR szInfo = NULL, UINT uId = ID_ICON_HOTPLUG)
|
||||
{
|
||||
NOTIFYICONDATA nim = { 0 };
|
||||
nim.cbSize = sizeof(NOTIFYICONDATA);
|
||||
nim.uID = uId;
|
||||
nim.hWnd = pSysTray->GetHWnd();
|
||||
|
||||
nim.uFlags = NIF_INFO;
|
||||
nim.uTimeout = 10;
|
||||
nim.dwInfoFlags = NIIF_INFO;
|
||||
|
||||
StringCchCopy(nim.szInfoTitle, _countof(nim.szInfoTitle), szTitle);
|
||||
StringCchCopy(nim.szInfo, _countof(nim.szInfo), szInfo);
|
||||
BOOL ret = Shell_NotifyIcon(NIM_MODIFY, &nim);
|
||||
|
||||
Sleep(10000); /* As per windows, the balloon notification remains visible for atleast 10 sec.
|
||||
This timer maintains the same condition.
|
||||
Also it is required so that the icon doesn't hide instantly after last device is removed,
|
||||
as that will prevent popping of notification.
|
||||
*/
|
||||
StringCchCopy(nim.szInfoTitle, _countof(nim.szInfoTitle), L"");
|
||||
StringCchCopy(nim.szInfo, _countof(nim.szInfo), L"");
|
||||
ret = Shell_NotifyIcon(NIM_MODIFY, &nim);
|
||||
g_IsRemoving = FALSE; /* This flag is used to prevent instant icon hiding after last device is removed.
|
||||
The above timer maintains the required state for the same.
|
||||
*/
|
||||
return ret ? S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE Hotplug_Init(_In_ CSysTray * pSysTray)
|
||||
{
|
||||
TRACE("Hotplug_Init\n");
|
||||
g_hIconHotplug = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_HOTPLUG_OK));
|
||||
g_IsRunning = TRUE;
|
||||
EnumHotpluggedDevices(g_devList);
|
||||
|
||||
return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip, NIS_HIDDEN);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE Hotplug_Update(_In_ CSysTray * pSysTray)
|
||||
{
|
||||
TRACE("Hotplug_Update\n");
|
||||
|
||||
if(g_devList.GetSize() || g_IsRemoving)
|
||||
return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip);
|
||||
else
|
||||
return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip, NIS_HIDDEN);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE Hotplug_Shutdown(_In_ CSysTray * pSysTray)
|
||||
{
|
||||
TRACE("Hotplug_Shutdown\n");
|
||||
g_IsRunning = FALSE;
|
||||
|
||||
return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_HOTPLUG, NULL, NULL);
|
||||
}
|
||||
|
||||
static void _RunHotplug(CSysTray * pSysTray)
|
||||
{
|
||||
ShellExecuteW(pSysTray->GetHWnd(), L"open", L"rundll32.exe shell32.dll,Control_RunDLL hotplug.dll", NULL, NULL, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
static void _ShowContextMenu(CSysTray * pSysTray)
|
||||
{
|
||||
HMENU hPopup = CreatePopupMenu();
|
||||
ULONG ulLength = DISPLAY_NAME_LEN * sizeof(WCHAR);
|
||||
|
||||
for (UINT index = 0; index < g_devList.GetSize(); index++)
|
||||
{
|
||||
WCHAR dispName[DISPLAY_NAME_LEN], menuName[DISPLAY_NAME_LEN + 10];
|
||||
CONFIGRET cr = CM_Get_DevNode_Registry_Property(g_devList[index], CM_DRP_DEVICEDESC, NULL, dispName, &ulLength, 0);
|
||||
if (cr != CR_SUCCESS)
|
||||
StrCpyW(dispName, L"Unknown Device");
|
||||
|
||||
swprintf(menuName, L"Eject %wS", dispName);
|
||||
AppendMenuW(hPopup, MF_STRING, index+1, menuName);
|
||||
}
|
||||
|
||||
SetForegroundWindow(pSysTray->GetHWnd());
|
||||
DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN;
|
||||
POINT pt;
|
||||
GetCursorPos(&pt);
|
||||
|
||||
DWORD id = TrackPopupMenuEx(hPopup, flags,
|
||||
pt.x, pt.y,
|
||||
pSysTray->GetHWnd(), NULL);
|
||||
|
||||
if (id > 0)
|
||||
{
|
||||
id--; // since array indices starts from zero.
|
||||
CONFIGRET cr = CM_Get_DevNode_Registry_Property(g_devList[id], CM_DRP_DEVICEDESC, NULL, g_strMenuSel, &ulLength, 0);
|
||||
if (cr != CR_SUCCESS)
|
||||
StrCpyW(g_strMenuSel, L"Unknown Device");
|
||||
|
||||
cr = CM_Request_Device_Eject_Ex(g_devList[id], 0, 0, 0, 0, 0);
|
||||
if (cr != CR_SUCCESS)
|
||||
{
|
||||
WCHAR strInfo[128];
|
||||
swprintf(strInfo, L"Problem Ejecting %wS", g_strMenuSel);
|
||||
MessageBox(0, L"The device cannot be stopped right now! Try stopping it again later!", strInfo, MB_OKCANCEL | MB_ICONEXCLAMATION);
|
||||
}
|
||||
else
|
||||
{
|
||||
//MessageBox(0, L"Device ejected successfully!! You can safely remove the device now!", L"Safely Remove Hardware", MB_OKCANCEL | MB_ICONINFORMATION);
|
||||
g_IsRemoving = TRUE;
|
||||
g_devList.RemoveAt(id); /* thing is.. even after removing id at this point, the devnode_change occurs after some seconds of sucessful removal
|
||||
and since pendrive is still plugged in it gets enumerated, if problem number is not filtered.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
DestroyMenu(hPopup);
|
||||
}
|
||||
|
||||
static void _ShowContextMenuR(CSysTray * pSysTray)
|
||||
{
|
||||
CString strMenu((LPWSTR)IDS_HOTPLUG_REMOVE_2);
|
||||
HMENU hPopup = CreatePopupMenu();
|
||||
AppendMenuW(hPopup, MF_STRING, IDS_HOTPLUG_REMOVE_2, strMenu);
|
||||
|
||||
SetForegroundWindow(pSysTray->GetHWnd());
|
||||
DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN;
|
||||
POINT pt;
|
||||
GetCursorPos(&pt);
|
||||
|
||||
DWORD id = TrackPopupMenuEx(hPopup, flags,
|
||||
pt.x, pt.y,
|
||||
pSysTray->GetHWnd(), NULL);
|
||||
|
||||
if (id == IDS_HOTPLUG_REMOVE_2)
|
||||
{
|
||||
_RunHotplug(pSysTray);
|
||||
}
|
||||
|
||||
DestroyMenu(hPopup);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE Hotplug_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult)
|
||||
{
|
||||
HRESULT hr = E_FAIL;
|
||||
TRACE("Hotplug_Message uMsg=%d, wParam=%x, lParam=%x\n", uMsg, wParam, lParam);
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
/*case WM_CREATE:
|
||||
TRACE("Hotplug_Message: WM_CREATE\n");
|
||||
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
|
||||
|
||||
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
|
||||
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
|
||||
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
|
||||
g_hDevNotify = RegisterDeviceNotification(pSysTray->GetHWnd(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
|
||||
if (g_hDevNotify != NULL)
|
||||
{
|
||||
lResult = true;
|
||||
return S_OK;
|
||||
}
|
||||
return S_FALSE;*/
|
||||
|
||||
case WM_USER + 220:
|
||||
TRACE("Hotplug_Message: WM_USER+220\n");
|
||||
if (wParam == 1)
|
||||
{
|
||||
if (lParam == FALSE)
|
||||
return Hotplug_Init(pSysTray);
|
||||
else
|
||||
return Hotplug_Shutdown(pSysTray);
|
||||
}
|
||||
return S_FALSE;
|
||||
|
||||
case WM_USER + 221:
|
||||
TRACE("Hotplug_Message: WM_USER+221\n");
|
||||
if (wParam == 1)
|
||||
{
|
||||
lResult = (LRESULT)g_IsRunning;
|
||||
return S_OK;
|
||||
}
|
||||
return S_FALSE;
|
||||
|
||||
case ID_ICON_HOTPLUG:
|
||||
Hotplug_Update(pSysTray);
|
||||
|
||||
switch (lParam)
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
_ShowContextMenu(pSysTray);
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDBLCLK:
|
||||
_RunHotplug(pSysTray);
|
||||
break;
|
||||
|
||||
case WM_RBUTTONDOWN:
|
||||
break;
|
||||
|
||||
case WM_RBUTTONUP:
|
||||
_ShowContextMenuR(pSysTray);
|
||||
break;
|
||||
|
||||
case WM_RBUTTONDBLCLK:
|
||||
break;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
|
||||
case WM_DEVICECHANGE:
|
||||
switch (wParam)
|
||||
{
|
||||
case DBT_DEVNODES_CHANGED:
|
||||
hr = EnumHotpluggedDevices(g_devList);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
lResult = true;
|
||||
break;
|
||||
case DBT_DEVICEARRIVAL:
|
||||
break;
|
||||
case DBT_DEVICEQUERYREMOVE:
|
||||
break;
|
||||
case DBT_DEVICEQUERYREMOVEFAILED:
|
||||
break;
|
||||
case DBT_DEVICEREMOVECOMPLETE:
|
||||
WCHAR strInfo[128];
|
||||
swprintf(strInfo, L"The %wS can now be safely removed from the system.", g_strMenuSel);
|
||||
NotifyBalloon(pSysTray, L"Safe to Remove Hardware", strInfo);
|
||||
|
||||
lResult = true;
|
||||
break;
|
||||
case DBT_DEVICEREMOVEPENDING:
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
|
||||
/*case WM_CLOSE:
|
||||
if (!UnregisterDeviceNotification(hDeviceNotify))
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
return S_OK;*/
|
||||
|
||||
default:
|
||||
TRACE("Hotplug_Message received for unknown ID %d, ignoring.\n");
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
return S_FALSE;
|
||||
}
|
@@ -17,8 +17,8 @@ BEGIN
|
||||
//Power related strings
|
||||
IDS_PWR_PROPERTIES "&Adjust Power Properties"
|
||||
IDS_PWR_METER "&Open Power Meter"
|
||||
IDS_PWR_PERCENT_REMAINING "%1!u!%% remaining"
|
||||
IDS_PWR_CHARGING " (charging)"
|
||||
IDS_PWR_PERCENT_REMAINING "%.2f%% remaining"
|
||||
IDS_PWR_CHARGING "%.2f%% and charging"
|
||||
IDS_PWR_UNKNOWN_REMAINING "Unknown remaining"
|
||||
IDS_PWR_AC "On AC power"
|
||||
IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! hours (%3!u!%%) remaining"
|
||||
|
@@ -4,20 +4,30 @@
|
||||
* FILE: dll/shellext/stobject/power.cpp
|
||||
* PURPOSE: Power notification icon handler
|
||||
* PROGRAMMERS: Eric Kohl <eric.kohl@reactos.org>
|
||||
Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com>
|
||||
* David Quintana <gigaherz@gmail.com>
|
||||
*/
|
||||
|
||||
#include <Windows.h>
|
||||
#include <SetupAPI.h>
|
||||
#include <devguid.h>
|
||||
#include <BatClass.h>
|
||||
|
||||
#include "precomp.h"
|
||||
#include "powrprof.h"
|
||||
|
||||
#include <mmsystem.h>
|
||||
#include <mmddk.h>
|
||||
#include <atlstr.h>
|
||||
|
||||
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
|
||||
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
|
||||
#define GBS_HASBATTERY 0x1
|
||||
#define GBS_ONBATTERY 0x2
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(stobject);
|
||||
|
||||
int br_icons[5] = { IDI_BATTCAP0, IDI_BATTCAP1, IDI_BATTCAP2, IDI_BATTCAP3, IDI_BATTCAP4 }; // battery mode icons.
|
||||
int bc_icons[5] = { IDI_BATTCHA0, IDI_BATTCHA1, IDI_BATTCHA2, IDI_BATTCHA3, IDI_BATTCHA4 }; // charging mode icons.
|
||||
|
||||
typedef struct _PWRSCHEMECONTEXT
|
||||
{
|
||||
HMENU hPopup;
|
||||
@@ -25,72 +35,230 @@ typedef struct _PWRSCHEMECONTEXT
|
||||
UINT uiLast;
|
||||
} PWRSCHEMECONTEXT, *PPWRSCHEMECONTEXT;
|
||||
|
||||
//static HICON g_hIconBattery = NULL;
|
||||
static HICON g_hIconAC = NULL;
|
||||
|
||||
CString g_strTooltip;
|
||||
static float g_batCap = 0;
|
||||
static HICON g_hIconBattery = NULL;
|
||||
static BOOL g_IsRunning = FALSE;
|
||||
|
||||
/*++
|
||||
* @name GetBatteryState
|
||||
*
|
||||
* Enumerates the available battery devices and provides the remaining capacity.
|
||||
*
|
||||
* @param cap
|
||||
* If no error occurs, then this will contain average remaining capacity.
|
||||
* @param dwResult
|
||||
* Helps in making battery type checks.
|
||||
* {
|
||||
* Returned value includes GBS_HASBATTERY if the system has a non-UPS battery,
|
||||
* and GBS_ONBATTERY if the system is running on a battery.
|
||||
* dwResult & GBS_ONBATTERY means we have not yet found AC power.
|
||||
* dwResult & GBS_HASBATTERY means we have found a non-UPS battery.
|
||||
* }
|
||||
*
|
||||
* @return The error code.
|
||||
*
|
||||
*--*/
|
||||
static HRESULT GetBatteryState(float& cap, DWORD& dwResult)
|
||||
{
|
||||
cap = 0;
|
||||
dwResult = GBS_ONBATTERY;
|
||||
|
||||
HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
if (INVALID_HANDLE_VALUE == hdev)
|
||||
return E_HANDLE;
|
||||
|
||||
// Limit search to 100 batteries max
|
||||
for (int idev = 0, count = 0; idev < 100; idev++)
|
||||
{
|
||||
SP_DEVICE_INTERFACE_DATA did = { 0 };
|
||||
did.cbSize = sizeof(did);
|
||||
|
||||
if (SetupDiEnumDeviceInterfaces(hdev, 0, &GUID_DEVCLASS_BATTERY, idev, &did))
|
||||
{
|
||||
DWORD cbRequired = 0;
|
||||
|
||||
SetupDiGetDeviceInterfaceDetail(hdev, &did, 0, 0, &cbRequired, 0);
|
||||
if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
|
||||
{
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, cbRequired);
|
||||
if (pdidd)
|
||||
{
|
||||
pdidd->cbSize = sizeof(*pdidd);
|
||||
if (SetupDiGetDeviceInterfaceDetail(hdev, &did, pdidd, cbRequired, &cbRequired, 0))
|
||||
{
|
||||
// Enumerated a battery. Ask it for information.
|
||||
HANDLE hBattery = CreateFile(pdidd->DevicePath, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (INVALID_HANDLE_VALUE != hBattery)
|
||||
{
|
||||
// Ask the battery for its tag.
|
||||
BATTERY_QUERY_INFORMATION bqi = { 0 };
|
||||
|
||||
DWORD dwWait = 0;
|
||||
DWORD dwOut;
|
||||
|
||||
if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_TAG, &dwWait, sizeof(dwWait), &bqi.BatteryTag,
|
||||
sizeof(bqi.BatteryTag), &dwOut, NULL) && bqi.BatteryTag)
|
||||
{
|
||||
// With the tag, you can query the battery info.
|
||||
BATTERY_INFORMATION bi = { 0 };
|
||||
bqi.InformationLevel = BatteryInformation;
|
||||
|
||||
if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &bi,
|
||||
sizeof(bi), &dwOut, NULL))
|
||||
{
|
||||
// Only non-UPS system batteries count
|
||||
if (bi.Capabilities & BATTERY_SYSTEM_BATTERY)
|
||||
{
|
||||
if (!(bi.Capabilities & BATTERY_IS_SHORT_TERM))
|
||||
dwResult |= GBS_HASBATTERY;
|
||||
|
||||
// Query the battery status.
|
||||
BATTERY_WAIT_STATUS bws = { 0 };
|
||||
bws.BatteryTag = bqi.BatteryTag;
|
||||
|
||||
BATTERY_STATUS bs;
|
||||
if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_STATUS, &bws, sizeof(bws),
|
||||
&bs, sizeof(bs), &dwOut, NULL))
|
||||
{
|
||||
if (bs.PowerState & BATTERY_POWER_ON_LINE)
|
||||
dwResult &= ~GBS_ONBATTERY;
|
||||
|
||||
// Take average of total capacity of batteries detected!
|
||||
cap = cap*(count)+(float)bs.Capacity / bi.FullChargedCapacity * 100;
|
||||
cap /= count + 1;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(hBattery);
|
||||
}
|
||||
}
|
||||
LocalFree(pdidd);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ERROR_NO_MORE_ITEMS == GetLastError())
|
||||
{
|
||||
break; // Enumeration failed - perhaps we're out of items
|
||||
}
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(hdev);
|
||||
|
||||
// Final cleanup: If we didn't find a battery, then presume that we
|
||||
// are on AC power.
|
||||
|
||||
if (!(dwResult & GBS_HASBATTERY))
|
||||
dwResult &= ~GBS_ONBATTERY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name Quantize
|
||||
*
|
||||
* This function quantizes the mentioned quantity to nearest level.
|
||||
*
|
||||
* @param p
|
||||
* Should be a quantity in percentage.
|
||||
* @param lvl
|
||||
* Quantization level (this excludes base level 0, which will always be present), default is 10.
|
||||
*
|
||||
* @return Nearest quantized level, can be directly used as array index based on context.
|
||||
*
|
||||
*--*/
|
||||
static UINT Quantize(float p, UINT lvl = 10)
|
||||
{
|
||||
int i = 0;
|
||||
float f, q = (float)100 / lvl, d = q / 2;
|
||||
for (f = 0; f < p; f += q, i++);
|
||||
|
||||
if ((f - d) <= p)
|
||||
return i;
|
||||
else
|
||||
return i - 1;
|
||||
/*
|
||||
@remarks This function uses centred/symmetric logic for quantization.
|
||||
For the case of lvl = 4, You will get following integer levels if given (p) value falls in between the range partitions:
|
||||
0 <= p < 12.5 : returns 0; (corresponding to 0% centre)
|
||||
12.5 <= p < 37.5 : returns 1; (corresponding to 25% centre)
|
||||
37.5 <= p < 62.5 : returns 2; (corresponding to 50% centre)
|
||||
62.5 <= p < 87.5 : returns 3; (corresponding to 75% centre)
|
||||
87.5 <= p <= 100 : returns 4; (corresponding to 100% centre)
|
||||
*/
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name DynamicLoadIcon
|
||||
*
|
||||
* Returns the respective icon as per the current battery capacity.
|
||||
* It also does the work of setting global parameters of battery capacity and tooltips.
|
||||
*
|
||||
* @param hinst
|
||||
* A handle to a instance of the module.
|
||||
*
|
||||
* @return The handle to respective battery icon.
|
||||
*
|
||||
*--*/
|
||||
static HICON DynamicLoadIcon(HINSTANCE hinst)
|
||||
{
|
||||
HICON hBatIcon;
|
||||
float cap = 0;
|
||||
DWORD dw = 0;
|
||||
UINT index = -1;
|
||||
HRESULT hr = GetBatteryState(cap, dw);
|
||||
|
||||
if (!FAILED(hr) && (dw & GBS_HASBATTERY))
|
||||
{
|
||||
index = Quantize(cap, 4);
|
||||
g_batCap = cap;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_batCap = 0;
|
||||
hBatIcon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_BATTCAP_ERR));
|
||||
g_strTooltip.LoadStringW(IDS_PWR_UNKNOWN_REMAINING);
|
||||
return hBatIcon;
|
||||
}
|
||||
|
||||
if (dw & GBS_ONBATTERY)
|
||||
{
|
||||
hBatIcon = LoadIcon(hinst, MAKEINTRESOURCE(br_icons[index]));
|
||||
g_strTooltip.Format(IDS_PWR_PERCENT_REMAINING, cap);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
hBatIcon = LoadIcon(hinst, MAKEINTRESOURCE(bc_icons[index]));
|
||||
g_strTooltip.Format(IDS_PWR_CHARGING, cap);
|
||||
}
|
||||
|
||||
return hBatIcon;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE Power_Init(_In_ CSysTray * pSysTray)
|
||||
{
|
||||
WCHAR strTooltip[128];
|
||||
|
||||
{
|
||||
TRACE("Power_Init\n");
|
||||
|
||||
// g_hIconBattery = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_BATTERY));
|
||||
g_hIconAC = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_BATTERY));
|
||||
|
||||
|
||||
HICON icon;
|
||||
// if (g_IsMute)
|
||||
// icon = g_hIconBattery;
|
||||
// else
|
||||
icon = g_hIconAC;
|
||||
|
||||
LoadStringW(g_hInstance, IDS_PWR_AC, strTooltip, _countof(strTooltip));
|
||||
|
||||
g_hIconBattery = DynamicLoadIcon(g_hInstance);
|
||||
g_IsRunning = TRUE;
|
||||
|
||||
return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_POWER, icon, strTooltip);
|
||||
|
||||
return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_POWER, g_hIconBattery, g_strTooltip);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE Power_Update(_In_ CSysTray * pSysTray)
|
||||
{
|
||||
// BOOL PrevState;
|
||||
TRACE("Power_Update\n");
|
||||
g_hIconBattery = DynamicLoadIcon(g_hInstance);
|
||||
|
||||
TRACE("Power_Update\n");
|
||||
|
||||
#if 0
|
||||
PrevState = g_IsMute;
|
||||
Volume_IsMute();
|
||||
|
||||
if (PrevState != g_IsMute)
|
||||
{
|
||||
WCHAR strTooltip[128];
|
||||
HICON icon;
|
||||
if (g_IsMute) {
|
||||
icon = g_hIconMute;
|
||||
LoadStringW(g_hInstance, IDS_VOL_MUTED, strTooltip, _countof(strTooltip));
|
||||
}
|
||||
else {
|
||||
icon = g_hIconVolume;
|
||||
LoadStringW(g_hInstance, IDS_VOL_VOLUME, strTooltip, _countof(strTooltip));
|
||||
}
|
||||
|
||||
return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_POWER, icon, strTooltip);
|
||||
}
|
||||
else
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
return S_OK;
|
||||
return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_POWER, g_hIconBattery, g_strTooltip);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE Power_Shutdown(_In_ CSysTray * pSysTray)
|
||||
{
|
||||
TRACE("Power_Shutdown\n");
|
||||
|
||||
g_IsRunning = FALSE;
|
||||
|
||||
return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_POWER, NULL, NULL);
|
||||
@@ -103,22 +271,18 @@ static void _RunPower()
|
||||
|
||||
static void _ShowContextMenu(CSysTray * pSysTray)
|
||||
{
|
||||
WCHAR strOpen[128];
|
||||
|
||||
LoadStringW(g_hInstance, IDS_PWR_PROPERTIES, strOpen, _countof(strOpen));
|
||||
|
||||
HMENU hPopup = CreatePopupMenu();
|
||||
AppendMenuW(hPopup, MF_STRING, IDS_PWR_PROPERTIES, strOpen);
|
||||
|
||||
DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN;
|
||||
DWORD msgPos = GetMessagePos();
|
||||
|
||||
CString strOpen((LPCSTR)IDS_PWR_PROPERTIES);
|
||||
HMENU hPopup = CreatePopupMenu();
|
||||
AppendMenuW(hPopup, MF_STRING, IDS_PWR_PROPERTIES, strOpen);
|
||||
|
||||
SetForegroundWindow(pSysTray->GetHWnd());
|
||||
DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN;
|
||||
POINT pt;
|
||||
GetCursorPos(&pt);
|
||||
|
||||
DWORD id = TrackPopupMenuEx(hPopup, flags,
|
||||
GET_X_LPARAM(msgPos), GET_Y_LPARAM(msgPos),
|
||||
pSysTray->GetHWnd(), NULL);
|
||||
|
||||
DestroyMenu(hPopup);
|
||||
pt.x, pt.y,
|
||||
pSysTray->GetHWnd(), NULL);
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@@ -126,6 +290,7 @@ static void _ShowContextMenu(CSysTray * pSysTray)
|
||||
_RunPower();
|
||||
break;
|
||||
}
|
||||
DestroyMenu(hPopup);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -160,8 +325,8 @@ ShowPowerSchemesPopupMenu(
|
||||
{
|
||||
PWRSCHEMECONTEXT PowerSchemeContext = {NULL, 0, 0};
|
||||
UINT uiActiveScheme;
|
||||
DWORD id, msgPos;
|
||||
|
||||
DWORD id;
|
||||
POINT pt;
|
||||
PowerSchemeContext.hPopup = CreatePopupMenu();
|
||||
EnumPwrSchemes(PowerSchemesEnumProc, (LPARAM)&PowerSchemeContext);
|
||||
|
||||
@@ -174,13 +339,13 @@ ShowPowerSchemesPopupMenu(
|
||||
MF_BYCOMMAND);
|
||||
}
|
||||
|
||||
msgPos = GetMessagePos();
|
||||
|
||||
SetForegroundWindow(pSysTray->GetHWnd());
|
||||
GetCursorPos(&pt);
|
||||
|
||||
id = TrackPopupMenuEx(PowerSchemeContext.hPopup,
|
||||
TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN,
|
||||
GET_X_LPARAM(msgPos),
|
||||
GET_Y_LPARAM(msgPos),
|
||||
pt.x,
|
||||
pt.y,
|
||||
pSysTray->GetHWnd(),
|
||||
NULL);
|
||||
|
||||
@@ -236,7 +401,7 @@ HRESULT STDMETHODCALLTYPE Power_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPA
|
||||
break;
|
||||
|
||||
case WM_RBUTTONUP:
|
||||
_ShowContextMenu(pSysTray);
|
||||
_ShowContextMenu(pSysTray);
|
||||
break;
|
||||
|
||||
case WM_RBUTTONDBLCLK:
|
||||
|
@@ -40,6 +40,7 @@ extern HINSTANCE g_hInstance;
|
||||
|
||||
#define ID_ICON_VOLUME (WM_APP + 0x4CB)
|
||||
#define ID_ICON_POWER (WM_APP + 0x4CC)
|
||||
#define ID_ICON_HOTPLUG (WM_APP + 0x4CD)
|
||||
|
||||
#include "csystray.h"
|
||||
|
||||
@@ -70,3 +71,8 @@ extern HRESULT STDMETHODCALLTYPE Power_Init(_In_ CSysTray * pSysTray);
|
||||
extern HRESULT STDMETHODCALLTYPE Power_Shutdown(_In_ CSysTray * pSysTray);
|
||||
extern HRESULT STDMETHODCALLTYPE Power_Update(_In_ CSysTray * pSysTray);
|
||||
extern HRESULT STDMETHODCALLTYPE Power_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult);
|
||||
|
||||
extern HRESULT STDMETHODCALLTYPE Hotplug_Init(_In_ CSysTray * pSysTray);
|
||||
extern HRESULT STDMETHODCALLTYPE Hotplug_Shutdown(_In_ CSysTray * pSysTray);
|
||||
extern HRESULT STDMETHODCALLTYPE Hotplug_Update(_In_ CSysTray * pSysTray);
|
||||
extern HRESULT STDMETHODCALLTYPE Hotplug_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult);
|
||||
|
@@ -39,4 +39,20 @@
|
||||
#define IDS_KEYS_MOUSE 331
|
||||
#define IDS_KEYS_FILTER 332
|
||||
|
||||
#define IDI_BATTCAP0 400
|
||||
#define IDI_BATTCAP1 401
|
||||
#define IDI_BATTCAP2 402
|
||||
#define IDI_BATTCAP3 403
|
||||
#define IDI_BATTCAP4 404
|
||||
#define IDI_BATTCAP5 405
|
||||
#define IDI_BATTCHA0 406
|
||||
#define IDI_BATTCHA1 407
|
||||
#define IDI_BATTCHA2 408
|
||||
#define IDI_BATTCHA3 409
|
||||
#define IDI_BATTCHA4 410
|
||||
#define IDI_BATTCAP_ERR 412
|
||||
|
||||
#define IDI_HOTPLUG_ERR 420
|
||||
#define IDI_HOTPLUG_OK 421
|
||||
|
||||
#define IDR_SYSTRAY 11001
|
||||
|
BIN
reactos/dll/shellext/stobject/resources/battery/0.ico
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
reactos/dll/shellext/stobject/resources/battery/1.ico
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
reactos/dll/shellext/stobject/resources/battery/2.ico
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
reactos/dll/shellext/stobject/resources/battery/3.ico
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
reactos/dll/shellext/stobject/resources/battery/4.ico
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
reactos/dll/shellext/stobject/resources/battery/5.ico
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
reactos/dll/shellext/stobject/resources/battery/charging0.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
reactos/dll/shellext/stobject/resources/battery/charging1.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
reactos/dll/shellext/stobject/resources/battery/charging2.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
reactos/dll/shellext/stobject/resources/battery/charging3.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
reactos/dll/shellext/stobject/resources/battery/charging4.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
reactos/dll/shellext/stobject/resources/battery/error.ico
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
reactos/dll/shellext/stobject/resources/hotplug/0.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
reactos/dll/shellext/stobject/resources/hotplug/1.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
@@ -4,7 +4,7 @@
|
||||
* FILE: dll/shellext/stobject/stobject.cpp
|
||||
* PURPOSE: COM registration services for STobject.dll
|
||||
* PROGRAMMERS: Robert Naumann
|
||||
David Quintana <gigaherz@gmail.com>
|
||||
David Quintana <gigaherz@gmail.com>
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
@@ -11,12 +11,31 @@ IDI_EXTRACT ICON "resources/2.ico"
|
||||
IDI_VOLUME ICON "resources/3.ico"
|
||||
IDI_VOLMUTE ICON "resources/4.ico"
|
||||
|
||||
IDI_BATTCAP0 ICON "resources/battery/0.ico"
|
||||
IDI_BATTCAP1 ICON "resources/battery/1.ico"
|
||||
IDI_BATTCAP2 ICON "resources/battery/2.ico"
|
||||
IDI_BATTCAP3 ICON "resources/battery/3.ico"
|
||||
IDI_BATTCAP4 ICON "resources/battery/4.ico"
|
||||
IDI_BATTCAP5 ICON "resources/battery/5.ico"
|
||||
|
||||
IDI_BATTCHA0 ICON "resources/battery/charging0.ico"
|
||||
IDI_BATTCHA1 ICON "resources/battery/charging1.ico"
|
||||
IDI_BATTCHA2 ICON "resources/battery/charging2.ico"
|
||||
IDI_BATTCHA3 ICON "resources/battery/charging3.ico"
|
||||
IDI_BATTCHA4 ICON "resources/battery/charging4.ico"
|
||||
|
||||
IDI_BATTCAP_ERR ICON "resources/battery/error.ico"
|
||||
|
||||
IDI_HOTPLUG_ERR ICON "resources/hotplug/0.ico"
|
||||
IDI_HOTPLUG_OK ICON "resources/hotplug/1.ico"
|
||||
|
||||
|
||||
IDR_SYSTRAY REGISTRY "resources/rgs/systray.rgs"
|
||||
|
||||
#include <reactos/manifest_dll.rc>
|
||||
|
||||
// Strings common to all languages
|
||||
STRINGTABLE
|
||||
/*STRINGTABLE
|
||||
BEGIN
|
||||
// Power related strings
|
||||
IDS_PWR_RUN "shell32.dll,Control_RunDLL PowerCfg.cpl"
|
||||
@@ -26,7 +45,7 @@ BEGIN
|
||||
|
||||
// Volume related strings
|
||||
IDS_VOL_RUN "SNDVOL32.EXE"
|
||||
END
|
||||
END*/
|
||||
|
||||
/* UTF-8 */
|
||||
#pragma code_page(65001)
|
||||
|
@@ -243,11 +243,12 @@ static void _ShowContextMenu(CSysTray * pSysTray)
|
||||
AppendMenuW(hPopup, MF_STRING, IDS_VOL_ADJUST, strAdjust);
|
||||
|
||||
DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN;
|
||||
DWORD msgPos = GetMessagePos();
|
||||
|
||||
POINT pt;
|
||||
SetForegroundWindow(pSysTray->GetHWnd());
|
||||
GetCursorPos(&pt);
|
||||
|
||||
DWORD id = TrackPopupMenuEx(hPopup, flags,
|
||||
GET_X_LPARAM(msgPos), GET_Y_LPARAM(msgPos),
|
||||
pt.x, pt.y,
|
||||
pSysTray->GetHWnd(), NULL);
|
||||
|
||||
DestroyMenu(hPopup);
|
||||
|
@@ -85,6 +85,7 @@ AddReg=Classes
|
||||
11,,olepro32.dll,1
|
||||
11,,propsys.dll,1
|
||||
11,,pstorec.dll,1
|
||||
11,,qcklnch.dll,1
|
||||
11,,qedit.dll,1
|
||||
11,,qmgr.dll,1
|
||||
11,,qmgrprxy.dll,1
|
||||
|
@@ -263,4 +263,8 @@ DEFINE_GUID(BHID_ThumbnailHandler, 0x7B2E650A, 0x8E20, 0x4F4A, 0xB0,0x9E, 0x65,0
|
||||
DEFINE_GUID(BHID_AssociationArray, 0xBEA9EF17, 0x82F1, 0x4F60, 0x92,0x84, 0x4F,0x8D,0xB7,0x5C,0x3B,0xE9);
|
||||
DEFINE_GUID(BHID_EnumAssocHandlers,0xB8AB0B9C, 0xC2EC, 0x4F7A, 0x91,0x8D, 0x31,0x49,0x00,0xE6,0x28,0x0A);
|
||||
|
||||
DEFINE_GUID(CLSID_ISFBand, 0xD82BE2B0, 0x5764, 0x11D0, 0xA9, 0x6E, 0x00, 0xC0, 0x4F, 0xD7, 0x05, 0xA2);
|
||||
DEFINE_GUID(IID_IShellFolderBand, 0x7fe80cc8, 0xc247, 0x11d0, 0xb9, 0x3a, 0x00, 0xa0, 0xc9, 0x03, 0x12, 0xe1);
|
||||
DEFINE_GUID(IID_IFolderBandPriv, 0x47c01f95, 0xe185, 0x412c, 0xb5, 0xc5, 0x4f, 0x27, 0xdf, 0x96, 0x5a, 0xea);
|
||||
|
||||
#endif /* __WINE_SHLGUID_H */
|
||||
|
@@ -2386,6 +2386,39 @@ DECLARE_INTERFACE_(IDockingWindowSite, IOleWindow)
|
||||
|
||||
typedef void (CALLBACK *PFNASYNCICONTASKBALLBACK)(LPCITEMIDLIST pidl, LPVOID pvData, LPVOID pvHint, INT iIconIndex, INT iOpenIconIndex);
|
||||
|
||||
#include <pshpack8.h>
|
||||
|
||||
typedef struct {
|
||||
DWORD dwMask;
|
||||
DWORD dwStateMask;
|
||||
DWORD dwState;
|
||||
COLORREF crBkgnd;
|
||||
COLORREF crBtnLt;
|
||||
COLORREF crBtnDk;
|
||||
WORD wViewMode;
|
||||
WORD wAlign;
|
||||
IShellFolder * psf;
|
||||
PIDLIST_ABSOLUTE pidl;
|
||||
} BANDINFOSFB, *PBANDINFOSFB;
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IShellFolderBand
|
||||
|
||||
DECLARE_INTERFACE_(IShellFolderBand, IUnknown)
|
||||
{
|
||||
// *** IUnknown methods ***
|
||||
STDMETHOD(QueryInterface) (THIS_ REFIID riid, __out void **ppv) PURE;
|
||||
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release) (THIS) PURE;
|
||||
|
||||
// *** IShellFolderBand Methods ***
|
||||
STDMETHOD(InitializeSFB)(THIS_ IShellFolder *psf, PCIDLIST_ABSOLUTE pidl) PURE;
|
||||
STDMETHOD(SetBandInfoSFB)(THIS_ PBANDINFOSFB pbi) PURE;
|
||||
STDMETHOD(GetBandInfoSFB)(THIS_ PBANDINFOSFB pbi) PURE;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Control Panel functions
|
||||
*/
|
||||
|
@@ -4458,3 +4458,20 @@ interface IShellTaskScheduler : IUnknown
|
||||
[in] DWORD dwReleaseStatus,
|
||||
[in] DWORD dwThreadTimeout);
|
||||
}
|
||||
|
||||
|
||||
[
|
||||
uuid(47c01f95-e185-412c-b5c5-4f27df965aea),
|
||||
object,
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface IFolderBandPriv : IUnknown
|
||||
{
|
||||
HRESULT SetCascade([in] BOOL fCascade);
|
||||
|
||||
HRESULT SetAccelerators([in] BOOL fAccelerators);
|
||||
|
||||
HRESULT SetNoIcons([in] BOOL fNoIcons);
|
||||
|
||||
HRESULT SetNoText([in] BOOL fNoText);
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
add_subdirectory(appwiz)
|
||||
add_subdirectory(arping)
|
||||
add_subdirectory(cat)
|
||||
add_subdirectory(gflags)
|
||||
add_subdirectory(ntfsinfo)
|
||||
add_subdirectory(tee)
|
||||
add_subdirectory(touch)
|
||||
|
@@ -1,10 +0,0 @@
|
||||
|
||||
add_executable(gflags gflags.c gflags.rc)
|
||||
set_module_type(gflags win32cui UNICODE)
|
||||
add_importlibs(gflags advapi32 user32 msvcrt kernel32)
|
||||
|
||||
if(MSVC)
|
||||
add_importlibs(gflags ntdll)
|
||||
endif()
|
||||
|
||||
add_cd_file(TARGET gflags DESTINATION reactos/bin FOR all)
|
@@ -1,424 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS ping utility
|
||||
* FILE: applications/cmdutils/gflags/gflags.c
|
||||
* PURPOSE: Global Flags utility
|
||||
* PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
|
||||
*/
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#include <stdarg.h>
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <winuser.h>
|
||||
#include <winreg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static BOOL Set = FALSE;
|
||||
static BOOL Unset = FALSE;
|
||||
static BOOL Full = FALSE;
|
||||
static PWSTR Image = NULL;
|
||||
static WCHAR ImageExecOptionsString[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options";
|
||||
|
||||
static DWORD ReagFlagsFromRegistry(HKEY SubKey, PVOID Buffer, PWSTR Value, DWORD MaxLen)
|
||||
{
|
||||
DWORD Len, Flags, Type;
|
||||
|
||||
Len = MaxLen;
|
||||
Flags = 0;
|
||||
if (RegQueryValueEx(SubKey, Value, NULL, &Type, Buffer, &Len) == ERROR_SUCCESS && Type == REG_SZ)
|
||||
{
|
||||
Flags = wcstoul(Buffer, NULL, 16);
|
||||
}
|
||||
|
||||
return Flags;
|
||||
}
|
||||
|
||||
static VOID ModifyStatus(VOID)
|
||||
{
|
||||
LONG Ret;
|
||||
DWORD MaxLen, GlobalFlags;
|
||||
PVOID Buffer;
|
||||
HKEY HandleKey, HandleSubKey;
|
||||
|
||||
Ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ImageExecOptionsString, 0, KEY_WRITE | KEY_READ, &HandleKey);
|
||||
if (Ret != ERROR_SUCCESS)
|
||||
{
|
||||
wprintf(L"MS: RegOpenKeyEx failed (%d)\n", Ret);
|
||||
return;
|
||||
}
|
||||
|
||||
Ret = RegCreateKeyEx(HandleKey, Image, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_READ, NULL, &HandleSubKey, NULL);
|
||||
if (Ret != ERROR_SUCCESS)
|
||||
{
|
||||
wprintf(L"MS: RegCreateKeyEx failed (%d)\n", Ret);
|
||||
return;
|
||||
}
|
||||
|
||||
Ret = RegQueryInfoKey(HandleSubKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &MaxLen, NULL, NULL);
|
||||
if (Ret != ERROR_SUCCESS)
|
||||
{
|
||||
wprintf(L"MS: RegQueryInfoKey failed (%d)\n", Ret);
|
||||
RegCloseKey(HandleSubKey);
|
||||
RegCloseKey(HandleKey);
|
||||
return;
|
||||
}
|
||||
|
||||
MaxLen = max(MaxLen, 11 * sizeof(WCHAR));
|
||||
Buffer = HeapAlloc(GetProcessHeap(), 0, MaxLen);
|
||||
if (Buffer == NULL)
|
||||
{
|
||||
wprintf(L"MS: HeapAlloc failed\n");
|
||||
RegCloseKey(HandleSubKey);
|
||||
RegCloseKey(HandleKey);
|
||||
return;
|
||||
}
|
||||
|
||||
GlobalFlags = ReagFlagsFromRegistry(HandleSubKey, Buffer, L"GlobalFlag", MaxLen);
|
||||
if (Set)
|
||||
{
|
||||
GlobalFlags |= 0x02000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalFlags &= ~0x02000000;
|
||||
}
|
||||
|
||||
if (GlobalFlags != 0)
|
||||
{
|
||||
wsprintf(Buffer, L"0x%08x", GlobalFlags);
|
||||
Ret = RegSetValueEx(HandleSubKey, L"GlobalFlag", 0, REG_SZ, Buffer, 11 * sizeof(WCHAR));
|
||||
if (Ret != ERROR_SUCCESS)
|
||||
{
|
||||
wprintf(L"MS: RegSetValueEx failed (%d)\n", Ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Ret = RegDeleteValue(HandleSubKey, L"GlobalFlag");
|
||||
if (Ret != ERROR_SUCCESS)
|
||||
{
|
||||
wprintf(L"MS: RegDeleteValue failed (%d)\n", Ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (Unset)
|
||||
{
|
||||
Ret = RegDeleteValue(HandleSubKey, L"PageHeapFlags");
|
||||
if (Ret != ERROR_SUCCESS)
|
||||
{
|
||||
wprintf(L"MS: RegDeleteValue failed (%d)\n", Ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD PageHeapFlags;
|
||||
|
||||
PageHeapFlags = ReagFlagsFromRegistry(HandleSubKey, Buffer, L"PageHeapFlags", MaxLen);
|
||||
PageHeapFlags &= ~3;
|
||||
|
||||
if (Full)
|
||||
{
|
||||
PageHeapFlags |= 1;
|
||||
}
|
||||
PageHeapFlags |= 2;
|
||||
|
||||
wsprintf(Buffer, L"0x%x", PageHeapFlags);
|
||||
Ret = RegSetValueEx(HandleSubKey, L"PageHeapFlags", 0, REG_SZ, Buffer, 11 * sizeof(WCHAR));
|
||||
if (Ret != ERROR_SUCCESS)
|
||||
{
|
||||
wprintf(L"MS: RegSetValueEx failed (%d)\n", Ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (Set)
|
||||
{
|
||||
DWORD Type, VerifierFlags, Len;
|
||||
|
||||
VerifierFlags = 0;
|
||||
Len = MaxLen;
|
||||
if (RegQueryValueEx(HandleSubKey, L"VerifierFlags", NULL, &Type, Buffer, &Len) == ERROR_SUCCESS &&
|
||||
Type == REG_DWORD && Len == sizeof(DWORD))
|
||||
{
|
||||
VerifierFlags = ((DWORD *)Buffer)[0];
|
||||
VerifierFlags &= ~0x8001;
|
||||
}
|
||||
|
||||
if (Full)
|
||||
{
|
||||
VerifierFlags |= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifierFlags |= 0x8000;
|
||||
}
|
||||
|
||||
Ret = RegSetValueEx(HandleSubKey, L"VerifierFlags", 0, REG_DWORD, (const BYTE *)&VerifierFlags, sizeof(DWORD));
|
||||
if (Ret != ERROR_SUCCESS)
|
||||
{
|
||||
wprintf(L"MS: RegSetValueEx failed (%d)\n", Ret);
|
||||
}
|
||||
}
|
||||
|
||||
wprintf(L"path: %s\n", ImageExecOptionsString);
|
||||
wprintf(L"\t%s: page heap %s\n", Image, (Set ? L"enabled" : L"disabled"));
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, Buffer);
|
||||
RegCloseKey(HandleSubKey);
|
||||
RegCloseKey(HandleKey);
|
||||
}
|
||||
|
||||
static BOOL DisplayImageInfo(HKEY HandleKey, PWSTR SubKey, PBOOL Header)
|
||||
{
|
||||
LONG Ret;
|
||||
BOOL Handled;
|
||||
DWORD MaxLen, GlobalFlags;
|
||||
HKEY HandleSubKey;
|
||||
PVOID Buffer;
|
||||
|
||||
Ret = RegOpenKeyEx(HandleKey, SubKey, 0, KEY_READ, &HandleSubKey);
|
||||
if (Ret != ERROR_SUCCESS)
|
||||
{
|
||||
wprintf(L"DII: RegOpenKeyEx failed (%d)\n", Ret);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ret = RegQueryInfoKey(HandleSubKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &MaxLen, NULL, NULL);
|
||||
if (Ret != ERROR_SUCCESS)
|
||||
{
|
||||
wprintf(L"DII: RegQueryInfoKey failed (%d)\n", Ret);
|
||||
RegCloseKey(HandleSubKey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Buffer = HeapAlloc(GetProcessHeap(), 0, MaxLen);
|
||||
if (Buffer == NULL)
|
||||
{
|
||||
wprintf(L"DII: HeapAlloc failed\n");
|
||||
RegCloseKey(HandleSubKey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Handled = FALSE;
|
||||
GlobalFlags = ReagFlagsFromRegistry(HandleSubKey, Buffer, L"GlobalFlag", MaxLen);
|
||||
if (GlobalFlags & 0x02000000)
|
||||
{
|
||||
DWORD PageHeapFlags;
|
||||
|
||||
if (Image == NULL)
|
||||
{
|
||||
if (!*Header)
|
||||
{
|
||||
wprintf(L"path: %s\n", ImageExecOptionsString);
|
||||
*Header = TRUE;
|
||||
}
|
||||
wprintf(L"\t%s: page heap enabled with flags (", SubKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
wprintf(L"Page heap is enabled for %s with flags (", SubKey);
|
||||
}
|
||||
|
||||
PageHeapFlags = ReagFlagsFromRegistry(HandleSubKey, Buffer, L"PageHeapFlags", MaxLen);
|
||||
if (PageHeapFlags & 0x1)
|
||||
{
|
||||
wprintf(L"full ");
|
||||
}
|
||||
|
||||
if (PageHeapFlags & 0x2)
|
||||
{
|
||||
wprintf(L"traces");
|
||||
}
|
||||
|
||||
wprintf(L")\n");
|
||||
|
||||
Handled = TRUE;
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, Buffer);
|
||||
RegCloseKey(HandleSubKey);
|
||||
|
||||
return Handled;
|
||||
}
|
||||
|
||||
static VOID DisplayStatus(VOID)
|
||||
{
|
||||
LONG Ret;
|
||||
HKEY HandleKey;
|
||||
DWORD Index, MaxLen, Handled;
|
||||
TCHAR * SubKey;
|
||||
BOOL Header;
|
||||
|
||||
Ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ImageExecOptionsString, 0, KEY_READ, &HandleKey);
|
||||
if (Ret != ERROR_SUCCESS)
|
||||
{
|
||||
wprintf(L"DS: RegOpenKeyEx failed (%d)\n", Ret);
|
||||
return;
|
||||
}
|
||||
|
||||
Ret = RegQueryInfoKey(HandleKey, NULL, NULL, NULL, NULL, &MaxLen, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (Ret != ERROR_SUCCESS)
|
||||
{
|
||||
wprintf(L"DS: RegQueryInfoKey failed (%d)\n", Ret);
|
||||
RegCloseKey(HandleKey);
|
||||
return;
|
||||
}
|
||||
|
||||
++MaxLen; // NULL-char
|
||||
SubKey = HeapAlloc(GetProcessHeap(), 0, MaxLen * sizeof(TCHAR));
|
||||
if (SubKey == NULL)
|
||||
{
|
||||
wprintf(L"DS: HeapAlloc failed\n");
|
||||
RegCloseKey(HandleKey);
|
||||
return;
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
Handled = 0;
|
||||
Header = FALSE;
|
||||
do
|
||||
{
|
||||
Ret = RegEnumKey(HandleKey, Index, SubKey, MaxLen);
|
||||
if (Ret != ERROR_NO_MORE_ITEMS)
|
||||
{
|
||||
if (Image == NULL || wcscmp(SubKey, Image) == 0)
|
||||
{
|
||||
if (DisplayImageInfo(HandleKey, SubKey, &Header))
|
||||
{
|
||||
++Handled;
|
||||
}
|
||||
}
|
||||
|
||||
++Index;
|
||||
}
|
||||
} while (Ret != ERROR_NO_MORE_ITEMS);
|
||||
|
||||
if (Handled == 0)
|
||||
{
|
||||
if (Image == NULL)
|
||||
{
|
||||
wprintf(L"No application has page heap enabled.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
wprintf(L"Page heap is not enabled for %s\n", Image);
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, SubKey);
|
||||
RegCloseKey(HandleKey);
|
||||
}
|
||||
|
||||
static VOID Usage(VOID)
|
||||
{
|
||||
wprintf(L"Usage: gflags /p [image.exe] [/enable|/disable [/full]]\n"
|
||||
L"\timage.exe:\tImage you want to deal with\n"
|
||||
L"\t/enable:\tenable page heap for the image\n"
|
||||
L"\t/disable:\tdisable page heap for the image\n"
|
||||
L"\t/full:\t\tactivate full debug page heap\n");
|
||||
}
|
||||
|
||||
static BOOL ParseCmdline(int argc, LPWSTR argv[])
|
||||
{
|
||||
INT i;
|
||||
BOOL UsePageHeap = FALSE;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
wprintf(L"Not enough args!\n", argc);
|
||||
Usage();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] == L'/')
|
||||
{
|
||||
if (argv[i][1] == L'p' && argv[i][2] == UNICODE_NULL)
|
||||
{
|
||||
UsePageHeap = TRUE;
|
||||
}
|
||||
else if (argv[i][1] == L'p' && argv[i][2] != UNICODE_NULL)
|
||||
{
|
||||
wprintf(L"Invalid option: %s\n", argv[i]);
|
||||
Usage();
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wcscmp(argv[i], L"/enable") == 0)
|
||||
{
|
||||
Set = TRUE;
|
||||
}
|
||||
else if (wcscmp(argv[i], L"/disable") == 0)
|
||||
{
|
||||
Unset = TRUE;
|
||||
}
|
||||
else if (wcscmp(argv[i], L"/full") == 0)
|
||||
{
|
||||
Full = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Image == NULL)
|
||||
{
|
||||
Image = argv[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
wprintf(L"Invalid option: %s\n", argv[i]);
|
||||
Usage();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!UsePageHeap)
|
||||
{
|
||||
wprintf(L"Only page heap flags are supported\n");
|
||||
Usage();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Set && Unset)
|
||||
{
|
||||
wprintf(L"ENABLE and DISABLED cannot be set together\n");
|
||||
Usage();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Image == NULL && (Set || Unset || Full))
|
||||
{
|
||||
wprintf(L"Can't ENABLE or DISABLE with no image\n");
|
||||
Usage();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Set && !Unset && Full)
|
||||
{
|
||||
wprintf(L"Cannot deal with full traces with no other indication\n");
|
||||
Usage();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int wmain(int argc, LPWSTR argv[])
|
||||
{
|
||||
if (!ParseCmdline(argc, argv))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!Set && !Unset)
|
||||
{
|
||||
DisplayStatus();
|
||||
}
|
||||
else
|
||||
{
|
||||
ModifyStatus();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,6 +0,0 @@
|
||||
#include <windef.h>
|
||||
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "Global Flags utility"
|
||||
#define REACTOS_STR_INTERNAL_NAME "gflags"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "gflags.exe"
|
||||
#include <reactos/version.rc>
|
@@ -66,7 +66,7 @@ void CallApphelpWithImage(char* filename, int MapIt,
|
||||
int IsOpt(char* argv, const char* check)
|
||||
{
|
||||
if( argv && (argv[0] == '-' || argv[0] == '/') ) {
|
||||
return !_strnicmp(argv + 1, check, strlen(check));
|
||||
return !stricmp(argv + 1, check);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -86,129 +86,6 @@ int HandleImageArg(int argc, char* argv[], int* pn, char MapItChar,
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef WORD TAG;
|
||||
typedef UINT64 QWORD;
|
||||
|
||||
#define TAG_TYPE_MASK 0xF000
|
||||
#define TAG_TYPE_DWORD 0x4000
|
||||
#define TAG_TYPE_QWORD 0x5000
|
||||
#define TAG_TYPE_STRINGREF 0x6000
|
||||
|
||||
#define ATTRIBUTE_AVAILABLE 0x1
|
||||
#define ATTRIBUTE_FAILED 0x2
|
||||
|
||||
typedef struct tagATTRINFO
|
||||
{
|
||||
TAG type;
|
||||
DWORD flags; /* ATTRIBUTE_AVAILABLE, ATTRIBUTE_FAILED */
|
||||
union
|
||||
{
|
||||
QWORD qwattr;
|
||||
DWORD dwattr;
|
||||
WCHAR *lpattr;
|
||||
};
|
||||
} ATTRINFO, *PATTRINFO;
|
||||
|
||||
static PVOID hdll;
|
||||
static LPCWSTR (WINAPI *pSdbTagToString)(TAG);
|
||||
static BOOL (WINAPI *pSdbGetFileAttributes)(LPCWSTR, PATTRINFO *, LPDWORD);
|
||||
static BOOL (WINAPI *pSdbFreeFileAttributes)(PATTRINFO);
|
||||
|
||||
static BOOL InitApphelp()
|
||||
{
|
||||
if (!hdll)
|
||||
{
|
||||
static UNICODE_STRING DllName = RTL_CONSTANT_STRING(L"apphelp.dll");
|
||||
static ANSI_STRING SdbTagToString = RTL_CONSTANT_STRING("SdbTagToString");
|
||||
static ANSI_STRING SdbGetFileAttributes = RTL_CONSTANT_STRING("SdbGetFileAttributes");
|
||||
static ANSI_STRING SdbFreeFileAttributes = RTL_CONSTANT_STRING("SdbFreeFileAttributes");
|
||||
if (!NT_SUCCESS(LdrLoadDll(NULL, NULL, &DllName, &hdll)))
|
||||
{
|
||||
printf("Unable to load apphelp.dll\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (!NT_SUCCESS(LdrGetProcedureAddress(hdll, &SdbTagToString, 0, (PVOID)&pSdbTagToString)) ||
|
||||
!NT_SUCCESS(LdrGetProcedureAddress(hdll, &SdbGetFileAttributes, 0, (PVOID)&pSdbGetFileAttributes)) ||
|
||||
!NT_SUCCESS(LdrGetProcedureAddress(hdll, &SdbFreeFileAttributes, 0, (PVOID)&pSdbFreeFileAttributes)))
|
||||
{
|
||||
LdrUnloadDll(hdll);
|
||||
hdll = NULL;
|
||||
printf("Unable to resolve functions\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int HandleDumpAttributes(int argc, char* argv[], int* pn, const char* opt)
|
||||
{
|
||||
UNICODE_STRING FileName;
|
||||
PATTRINFO attr;
|
||||
DWORD num_attr, n;
|
||||
int argn = *pn;
|
||||
const char* arg;
|
||||
|
||||
if (!InitApphelp())
|
||||
return 1;
|
||||
|
||||
if (strlen(argv[argn]) > (strlen(opt)+1))
|
||||
{
|
||||
arg = argv[argn] + strlen(opt);
|
||||
}
|
||||
else if (argn+1 >= argc)
|
||||
{
|
||||
printf("Error: no image name specified\n");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
arg = argv[argn+1];
|
||||
(*pn) += 1;
|
||||
}
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz(&FileName, arg);
|
||||
|
||||
if (pSdbGetFileAttributes(FileName.Buffer, &attr, &num_attr))
|
||||
{
|
||||
printf("Dumping attributes for %s\n", arg);
|
||||
for (n = 0; n < num_attr; ++n)
|
||||
{
|
||||
TAG tagType;
|
||||
LPCWSTR tagName;
|
||||
if (attr[n].flags != ATTRIBUTE_AVAILABLE)
|
||||
continue;
|
||||
|
||||
tagName = pSdbTagToString(attr[n].type);
|
||||
|
||||
tagType = attr[n].type & TAG_TYPE_MASK;
|
||||
switch (tagType)
|
||||
{
|
||||
case TAG_TYPE_DWORD:
|
||||
printf("<%ls>0x%lx</%ls><!-- %ld -->\n", tagName, attr[n].dwattr, tagName, attr[n].dwattr);
|
||||
break;
|
||||
case TAG_TYPE_STRINGREF:
|
||||
printf("<%ls>0x%ls</%ls>\n", tagName, attr[n].lpattr, tagName);
|
||||
break;
|
||||
case TAG_TYPE_QWORD:
|
||||
printf("<%ls>0x%I64x</%ls><!-- %I64d -->\n", tagName, attr[n].qwattr, tagName, attr[n].qwattr);
|
||||
break;
|
||||
default:
|
||||
printf("<!-- Unknown tag type: 0x%x (from 0x%x)\n", tagType, attr[n].type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("Done\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unable to get attributes from %s\n", arg);
|
||||
}
|
||||
|
||||
|
||||
RtlFreeUnicodeString(&FileName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
UNICODE_STRING AppCompatCacheKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\AppCompatCache");
|
||||
OBJECT_ATTRIBUTES AppCompatKeyAttributes = RTL_CONSTANT_OBJECT_ATTRIBUTES(&AppCompatCacheKey, OBJ_CASE_INSENSITIVE);
|
||||
@@ -345,10 +222,6 @@ int main(int argc, char* argv[])
|
||||
unhandled |= HandleImageArg(argc, argv, &n, 'r',
|
||||
ApphelpCacheServiceRemove, "ApphelpCacheServiceRemove");
|
||||
}
|
||||
else if (IsOpt(arg, "a"))
|
||||
{
|
||||
unhandled |= HandleDumpAttributes(argc, argv, &n, "a");
|
||||
}
|
||||
else if (IsOpt(arg, "k"))
|
||||
{
|
||||
keepopen = 1;
|
||||
@@ -373,7 +246,6 @@ int main(int argc, char* argv[])
|
||||
printf(" -U: Update (insert) <image> in the shim cache without mapping it\n");
|
||||
printf(" -r: Remove <image> from the shim cache\n");
|
||||
printf(" -R: Remove <image> from the shim cache without mapping it\n");
|
||||
printf(" -a: Dump file attributes as used in the appcompat database\n");
|
||||
printf(" -k: Keep the console open\n");
|
||||
}
|
||||
if (keepopen)
|
||||
|
@@ -20,7 +20,6 @@ endif()
|
||||
add_subdirectory(localspl)
|
||||
add_subdirectory(msgina)
|
||||
add_subdirectory(msvcrt)
|
||||
add_subdirectory(netapi32)
|
||||
add_subdirectory(netshell)
|
||||
add_subdirectory(ntdll)
|
||||
add_subdirectory(ole32)
|
||||
|
@@ -253,7 +253,7 @@ START_TEST(RegQueryValueExW)
|
||||
ret = RegQueryValueExW(hkey_main, L"LONGSTRING", NULL, &type, (LPBYTE)data22, &size);
|
||||
ok(ret == ERROR_MORE_DATA, "RegQueryValueExW returned: %lx\n", ret);
|
||||
ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
|
||||
ok(type == REG_SZ, "Expected REG_SZ, Type is: %ld\n", type);
|
||||
ok(type == REG_SZ, "Expected REG_NONE, Type is: %ld\n", type);
|
||||
ok(size == 46, "Expected size = 46, size is: %ld\n", size);
|
||||
ok(wcscmp(data22, string22W), "Expected being different!");
|
||||
|
||||
@@ -264,7 +264,7 @@ START_TEST(RegQueryValueExW)
|
||||
ret = RegQueryValueExW(hkey_main, L"LONGSTRING", NULL, &type, (LPBYTE)data23, &size);
|
||||
ok(ret == ERROR_SUCCESS, "RegQueryValueExW returned: %lx\n", ret);
|
||||
ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
|
||||
ok(type == REG_SZ, "Expected REG_SZ, Type is: %ld\n", type);
|
||||
ok(type == REG_SZ, "Expected REG_NONE, Type is: %ld\n", type);
|
||||
ok(size == 46, "Expected size = 46, size is: %ld", size);
|
||||
ok(!wcscmp(data23,string22W), "Expected same string! data23: %S, string22W: %S", data23, string22W);
|
||||
|
||||
@@ -275,7 +275,7 @@ START_TEST(RegQueryValueExW)
|
||||
ret = RegQueryValueExW(hkey_main, L"LONGSTRING", NULL, &type, (LPBYTE)data24, &size);
|
||||
ok(ret == ERROR_SUCCESS, "RegQueryValueExW returned: %lx\n", ret);
|
||||
ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
|
||||
ok(type == REG_SZ, "Expected REG_SZ, Type is: %ld\n", type);
|
||||
ok(type == REG_SZ, "Expected REG_NONE, Type is: %ld\n", type);
|
||||
ok(size == 46, "Expected size = 46, size is: %ld\n", size);
|
||||
ok(!wcscmp(data24, string22W), "Expected same string! data24: %S, string22W: %S\n", data24, string22W);
|
||||
|
||||
@@ -287,7 +287,7 @@ START_TEST(RegQueryValueExW)
|
||||
ret = RegQueryValueExW(hkey_main, L"LONGSTRING", NULL, &type, (LPBYTE)data23, &size);
|
||||
ok(ret == ERROR_MORE_DATA, "RegQueryValueExW returned: %lx\n", ret);
|
||||
ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
|
||||
ok(type == REG_SZ, "Expected REG_SZ, Type is: %ld\n", type);
|
||||
ok(type == REG_SZ, "Expected REG_NONE, Type is: %ld\n", type);
|
||||
ok(size == 46, "Expected size = 46, size is: %ld", size);
|
||||
ok(wcscmp(data23, string22W), "Expected different string!\n");
|
||||
|
||||
@@ -299,7 +299,7 @@ START_TEST(RegQueryValueExW)
|
||||
ret = RegQueryValueExW(hkey_main, L"LONGSTRING", NULL, &type, (LPBYTE)data23, &size);
|
||||
ok(ret == ERROR_SUCCESS, "RegQueryValueExW returned: %lx\n", ret);
|
||||
ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
|
||||
ok(type == REG_SZ, "Expected REG_SZ, Type is: %ld\n", type);
|
||||
ok(type == REG_SZ, "Expected REG_NONE, Type is: %ld\n", type);
|
||||
ok(size == 46, "Expected size = 46, size is: %ld", size);
|
||||
ok(!wcscmp(data23, string22W), "Expected same string! data23: %S, string22W: %S", data23, string22W);
|
||||
|
||||
|
@@ -1,26 +1,14 @@
|
||||
project(appcompat)
|
||||
add_definitions(-D__ROS_LONG64__ -DWINETEST_USE_DBGSTR_LONGLONG)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
list(APPEND SOURCE
|
||||
apphelp.c
|
||||
data.c
|
||||
db.cpp
|
||||
env.c
|
||||
layerapi.c
|
||||
testlist.c
|
||||
testdata.rc
|
||||
testdb.xml)
|
||||
testlist.c)
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/testdb.sdb
|
||||
COMMAND native-xml2sdb -i ${CMAKE_CURRENT_SOURCE_DIR}/testdb.xml -o ${CMAKE_CURRENT_BINARY_DIR}/testdb.sdb
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/testdb.xml native-xml2sdb)
|
||||
|
||||
add_custom_target(testdb DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/testdb.sdb)
|
||||
add_rc_deps(testdata.rc testdb)
|
||||
add_executable(apphelp_apitest ${SOURCE})
|
||||
set_module_type(apphelp_apitest win32cui)
|
||||
target_link_libraries(apphelp_apitest ${PSEH_LIB})
|
||||
add_importlibs(apphelp_apitest advapi32 userenv version shlwapi msvcrt kernel32 ntdll)
|
||||
add_rostests_file(TARGET apphelp_apitest)
|
||||
|
@@ -41,6 +41,11 @@
|
||||
#include "apphelp_apitest.h"
|
||||
|
||||
|
||||
typedef WORD TAG;
|
||||
typedef DWORD TAGID;
|
||||
typedef DWORD TAGREF;
|
||||
typedef UINT64 QWORD;
|
||||
|
||||
#define TAG_TYPE_MASK 0xF000
|
||||
|
||||
#define TAG_TYPE_NULL 0x1000
|
||||
@@ -603,7 +608,7 @@ static void test_crc_imp(size_t len, DWORD expected)
|
||||
DWORD num = 333;
|
||||
BOOL ret;
|
||||
|
||||
test_create_file_imp(L"testxx.exe", crc_test, len);
|
||||
test_create_file_imp("testxx.exe", crc_test, len);
|
||||
ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
|
||||
winetest_ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
|
||||
winetest_ok(pattrinfo != (PATTRINFO)0xdead, "expected a valid pointer.\n");
|
||||
@@ -629,7 +634,7 @@ static void test_crc2_imp(size_t len, int fill, DWORD expected)
|
||||
for (n = 0; n < len; ++n)
|
||||
crc_test[n] = (char)(fill ? fill : n);
|
||||
|
||||
test_create_file_imp(L"testxx.exe", crc_test, len);
|
||||
test_create_file_imp("testxx.exe", crc_test, len);
|
||||
free(crc_test);
|
||||
ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
|
||||
winetest_ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
|
||||
@@ -678,7 +683,7 @@ static void test_ApplicationAttributes(void)
|
||||
pSdbFreeFileAttributes(pattrinfo);
|
||||
|
||||
/* Test a file with as much features as possible */
|
||||
test_create_exe(L"testxx.exe", 0);
|
||||
test_create_exe("testxx.exe", 0);
|
||||
|
||||
ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
|
||||
ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
|
||||
@@ -721,7 +726,7 @@ static void test_ApplicationAttributes(void)
|
||||
|
||||
|
||||
/* Disable resource and exports */
|
||||
test_create_exe(L"testxx.exe", 1);
|
||||
test_create_exe("testxx.exe", 1);
|
||||
|
||||
ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
|
||||
ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
|
||||
@@ -747,7 +752,7 @@ static void test_ApplicationAttributes(void)
|
||||
pSdbFreeFileAttributes(pattrinfo);
|
||||
|
||||
/* A file with just 'MZ' */
|
||||
test_create_file(L"testxx.exe", "MZ", 2);
|
||||
test_create_file("testxx.exe", "MZ", 2);
|
||||
|
||||
ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
|
||||
ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
|
||||
@@ -768,7 +773,7 @@ static void test_ApplicationAttributes(void)
|
||||
pSdbFreeFileAttributes(pattrinfo);
|
||||
|
||||
/* Empty file */
|
||||
test_create_file(L"testxx.exe", NULL, 0);
|
||||
test_create_file("testxx.exe", NULL, 0);
|
||||
|
||||
ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
|
||||
ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
|
||||
@@ -786,7 +791,7 @@ static void test_ApplicationAttributes(void)
|
||||
pSdbFreeFileAttributes(pattrinfo);
|
||||
|
||||
/* minimal NE executable */
|
||||
test_create_ne(L"testxx.exe", 0);
|
||||
test_create_ne("testxx.exe", 0);
|
||||
|
||||
ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
|
||||
ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
|
||||
@@ -811,7 +816,7 @@ static void test_ApplicationAttributes(void)
|
||||
pSdbFreeFileAttributes(pattrinfo);
|
||||
|
||||
/* NE executable with description / module name pointers zero, to show they are always used */
|
||||
test_create_ne(L"testxx.exe", 1);
|
||||
test_create_ne("testxx.exe", 1);
|
||||
|
||||
ret = pSdbGetFileAttributes(path, &pattrinfo, &num);
|
||||
ok(ret != FALSE, "expected SdbGetFileAttributes to succeed.\n");
|
||||
|
@@ -7,11 +7,11 @@ extern "C" {
|
||||
|
||||
|
||||
/* data.c */
|
||||
void test_create_db_imp(const WCHAR* name, int win10);
|
||||
void test_create_db_imp(const char* name, int win10);
|
||||
DWORD test_get_db_size();
|
||||
void test_create_exe_imp(const WCHAR* name, int skip_rsrc_exports);
|
||||
void test_create_file_imp(const WCHAR* name, const char* contents, size_t len);
|
||||
void test_create_ne_imp(const WCHAR* name, int skip_names);
|
||||
void test_create_exe_imp(const char* name, int skip_rsrc_exports);
|
||||
void test_create_file_imp(const char* name, const char* contents, size_t len);
|
||||
void test_create_ne_imp(const char* name, int skip_names);
|
||||
DWORD get_host_winver(void);
|
||||
DWORD get_module_version(HMODULE mod);
|
||||
void silence_debug_output(void); // Silence output if the environment variable is not set.
|
||||
@@ -32,70 +32,6 @@ static DWORD g_WinVersion;
|
||||
#define WINVER_WIN8 0x0602
|
||||
#define WINVER_WIN10 0x0a00
|
||||
|
||||
|
||||
typedef WORD TAG;
|
||||
typedef DWORD TAGID;
|
||||
typedef DWORD TAGREF;
|
||||
typedef UINT64 QWORD;
|
||||
typedef VOID* PDB;
|
||||
typedef VOID* HSDB;
|
||||
typedef INT PATH_TYPE;
|
||||
|
||||
|
||||
|
||||
#define SDB_MAX_SDBS 16
|
||||
#define SDB_MAX_EXES_VISTA 16
|
||||
#define SDB_MAX_LAYERS 8
|
||||
#define SHIMREG_DISABLE_LAYER (0x00000020)
|
||||
|
||||
#define SDBQUERYRESULT_EXPECTED_SIZE_VISTA 456
|
||||
|
||||
|
||||
|
||||
typedef struct tagSDBQUERYRESULT_VISTA
|
||||
{
|
||||
TAGREF atrExes[SDB_MAX_EXES_VISTA];
|
||||
DWORD adwExeFlags[SDB_MAX_EXES_VISTA];
|
||||
TAGREF atrLayers[SDB_MAX_LAYERS];
|
||||
DWORD dwLayerFlags;
|
||||
TAGREF trApphelp;
|
||||
DWORD dwExeCount;
|
||||
DWORD dwLayerCount;
|
||||
GUID guidID;
|
||||
DWORD dwFlags;
|
||||
DWORD dwCustomSDBMap;
|
||||
GUID rgGuidDB[SDB_MAX_SDBS];
|
||||
} SDBQUERYRESULT_VISTA, *PSDBQUERYRESULT_VISTA;
|
||||
|
||||
|
||||
#define SDBQUERYRESULT_EXPECTED_SIZE_2k3 344
|
||||
|
||||
#define SDB_MAX_EXES_2k3 4
|
||||
|
||||
typedef struct tagSDBQUERYRESULT_2k3
|
||||
{
|
||||
TAGREF atrExes[SDB_MAX_EXES_2k3];
|
||||
TAGREF atrLayers[SDB_MAX_LAYERS];
|
||||
DWORD dwLayerFlags;
|
||||
TAGREF trApphelp; // probably?
|
||||
DWORD dwExeCount;
|
||||
DWORD dwLayerCount;
|
||||
GUID guidID; // probably?
|
||||
DWORD dwFlags; // probably?
|
||||
DWORD dwCustomSDBMap;
|
||||
GUID rgGuidDB[SDB_MAX_SDBS];
|
||||
} SDBQUERYRESULT_2k3, *PSDBQUERYRESULT_2k3;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
C_ASSERT(sizeof(SDBQUERYRESULT_VISTA) == SDBQUERYRESULT_EXPECTED_SIZE_VISTA);
|
||||
C_ASSERT(sizeof(SDBQUERYRESULT_2k3) == SDBQUERYRESULT_EXPECTED_SIZE_2k3);
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@@ -474,14 +474,14 @@ static export_section_t export_dir =
|
||||
};
|
||||
|
||||
|
||||
void test_create_exe_imp(const WCHAR* name, int skip_rsrc_exports)
|
||||
void test_create_exe_imp(const char* name, int skip_rsrc_exports)
|
||||
{
|
||||
HANDLE file;
|
||||
char *buf, *cur;
|
||||
DWORD size = 0x800;
|
||||
buf = malloc(size);
|
||||
|
||||
file = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
winetest_ok(file != INVALID_HANDLE_VALUE, "can't create file\n");
|
||||
if(file == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
@@ -522,7 +522,7 @@ void test_create_exe_imp(const WCHAR* name, int skip_rsrc_exports)
|
||||
|
||||
|
||||
/* Almost everything in this filetype is ignored, only e_lfanew, ne_restab and ne_nrestab are relevant */
|
||||
void test_create_ne_imp(const WCHAR* name, int skip_names)
|
||||
void test_create_ne_imp(const char* name, int skip_names)
|
||||
{
|
||||
HANDLE file;
|
||||
DWORD size;
|
||||
@@ -535,7 +535,7 @@ void test_create_ne_imp(const WCHAR* name, int skip_names)
|
||||
20,'M','O','D',' ','D','E','S','C','R','I','P','T','I','O','N',' ','H','E','R','E',0,0,0
|
||||
};
|
||||
|
||||
file = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
winetest_ok(file != INVALID_HANDLE_VALUE, "can't create file\n");
|
||||
if(file == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
@@ -554,9 +554,9 @@ void test_create_ne_imp(const WCHAR* name, int skip_names)
|
||||
CloseHandle(file);
|
||||
}
|
||||
|
||||
void test_create_file_imp(const WCHAR* name, const char* contents, size_t len)
|
||||
void test_create_file_imp(const char* name, const char* contents, size_t len)
|
||||
{
|
||||
HANDLE file = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
HANDLE file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
winetest_ok(file != INVALID_HANDLE_VALUE, "can't create file\n");
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
@@ -777,10 +777,10 @@ DWORD test_get_db_size()
|
||||
return sizeof(rawData);
|
||||
}
|
||||
|
||||
void test_create_db_imp(const WCHAR* name, int win10)
|
||||
void test_create_db_imp(const char* name, int win10)
|
||||
{
|
||||
HANDLE file = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
winetest_ok(file != INVALID_HANDLE_VALUE, "can't create file '%s'\n", wine_dbgstr_w(name));
|
||||
HANDLE file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
winetest_ok(file != INVALID_HANDLE_VALUE, "can't create file '%s'\n", name);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD size;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright 2012 Detlef Riekenberg
|
||||
* Copyright 2013 Mislav Blažević
|
||||
* Copyright 2015-2017 Mark Jansen
|
||||
* Copyright 2015,2016 Mark Jansen
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -39,6 +39,15 @@
|
||||
#include "apphelp_apitest.h"
|
||||
|
||||
|
||||
|
||||
typedef WORD TAG;
|
||||
typedef DWORD TAGID;
|
||||
typedef DWORD TAGREF;
|
||||
typedef UINT64 QWORD;
|
||||
typedef VOID* PDB;
|
||||
typedef VOID* HSDB;
|
||||
typedef INT PATH_TYPE;
|
||||
|
||||
#define DOS_PATH 0
|
||||
#define HID_DATABASE_FULLPATH 2
|
||||
|
||||
@@ -130,6 +139,54 @@
|
||||
#define TAG_DATABASE_ID (0x7 | TAG_TYPE_BINARY)
|
||||
|
||||
|
||||
#define SDB_MAX_SDBS_VISTA 16
|
||||
#define SDB_MAX_EXES_VISTA 16
|
||||
#define SDB_MAX_LAYERS_VISTA 8
|
||||
|
||||
#define SDBQUERYRESULT_EXPECTED_SIZE_VISTA 456
|
||||
|
||||
typedef struct tagSDBQUERYRESULT
|
||||
{
|
||||
TAGREF atrExes[SDB_MAX_EXES_VISTA];
|
||||
DWORD adwExeFlags[SDB_MAX_EXES_VISTA];
|
||||
TAGREF atrLayers[SDB_MAX_LAYERS_VISTA];
|
||||
DWORD dwLayerFlags;
|
||||
TAGREF trApphelp;
|
||||
DWORD dwExeCount;
|
||||
DWORD dwLayerCount;
|
||||
GUID guidID;
|
||||
DWORD dwFlags;
|
||||
DWORD dwCustomSDBMap;
|
||||
GUID rgGuidDB[SDB_MAX_SDBS_VISTA];
|
||||
} SDBQUERYRESULT, *PSDBQUERYRESULT;
|
||||
|
||||
|
||||
#define SDBQUERYRESULT_EXPECTED_SIZE_2k3 344
|
||||
|
||||
#define SDB_MAX_EXES_2k3 4
|
||||
#define SDB_MAX_LAYERS_2k3 8
|
||||
|
||||
typedef struct tagSDBQUERYRESULT_2k3
|
||||
{
|
||||
TAGREF atrExes[SDB_MAX_EXES_2k3];
|
||||
TAGREF atrLayers[SDB_MAX_LAYERS_2k3];
|
||||
DWORD dwLayerFlags;
|
||||
TAGREF trApphelp; // probably?
|
||||
DWORD dwExeCount;
|
||||
DWORD dwLayerCount;
|
||||
GUID guidID; // probably?
|
||||
DWORD dwFlags; // probably?
|
||||
DWORD dwCustomSDBMap;
|
||||
GUID rgGuidDB[SDB_MAX_SDBS_VISTA];
|
||||
} SDBQUERYRESULT_2k3, *PSDBQUERYRESULT_2k3;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
C_ASSERT(sizeof(SDBQUERYRESULT) == SDBQUERYRESULT_EXPECTED_SIZE_VISTA);
|
||||
C_ASSERT(sizeof(SDBQUERYRESULT_2k3) == SDBQUERYRESULT_EXPECTED_SIZE_2k3);
|
||||
|
||||
|
||||
static HMODULE hdll;
|
||||
static LPCWSTR (WINAPI *pSdbTagToString)(TAG);
|
||||
@@ -165,7 +222,7 @@ static BOOL (WINAPI *pSdbGetDatabaseID)(PDB, GUID*);
|
||||
static BOOL (WINAPI *pSdbGUIDToString)(CONST GUID *, PCWSTR, SIZE_T);
|
||||
static HSDB (WINAPI *pSdbInitDatabase)(DWORD, LPCWSTR);
|
||||
static void (WINAPI *pSdbReleaseDatabase)(HSDB);
|
||||
static BOOL (WINAPI *pSdbGetMatchingExe)(HSDB hsdb, LPCWSTR path, LPCWSTR module_name, LPCWSTR env, DWORD flags, PSDBQUERYRESULT_VISTA result);
|
||||
static BOOL (WINAPI *pSdbGetMatchingExe)(HSDB hsdb, LPCWSTR path, LPCWSTR module_name, LPCWSTR env, DWORD flags, PSDBQUERYRESULT result);
|
||||
static BOOL (WINAPI *pSdbTagRefToTagID)(HSDB hSDB, TAGREF trWhich, PDB *ppdb, TAGID *ptiWhich);
|
||||
static BOOL (WINAPI *pSdbTagIDToTagRef)(HSDB hSDB, PDB pdb, TAGID tiWhich, TAGREF *ptrWhich);
|
||||
static TAGREF (WINAPI *pSdbGetLayerTagRef)(HSDB hsdb, LPCWSTR layerName);
|
||||
@@ -318,11 +375,7 @@ static void test_Sdb(void)
|
||||
|
||||
/* FIXME: doesnt work on win10?! */
|
||||
pdb = pSdbOpenDatabase(path1, DOS_PATH);
|
||||
if (g_WinVersion < WINVER_WIN10)
|
||||
{
|
||||
/* ERROR,SdbOpenDatabaseEx,845,Failed to open SDB - File size too large or small. */
|
||||
ok(pdb != NULL, "unexpected NULL handle\n");
|
||||
}
|
||||
ok(pdb != NULL, "unexpected NULL handle\n");
|
||||
if (pdb)
|
||||
{
|
||||
binary = (PBYTE)pSdbGetBinaryTagData(pdb, _TAGID_ROOT);
|
||||
@@ -549,7 +602,7 @@ static void test_stringtable()
|
||||
}
|
||||
}
|
||||
|
||||
static void match_strw_attr_imp(PDB pdb, TAGID parent, TAG find, const WCHAR* compare)
|
||||
static void match_str_attr_imp(PDB pdb, TAGID parent, TAG find, const char* compare)
|
||||
{
|
||||
TAGID attr = pSdbFindFirstTag(pdb, parent, find);
|
||||
winetest_ok(attr != TAG_NULL, "Could not find: %x\n", find);
|
||||
@@ -559,7 +612,9 @@ static void match_strw_attr_imp(PDB pdb, TAGID parent, TAG find, const WCHAR* co
|
||||
winetest_ok(name != NULL, "Could not convert attr to str.\n");
|
||||
if (name)
|
||||
{
|
||||
winetest_ok(wcscmp(name, compare) == 0, "Expected tagid %x to be %s, was %s\n", attr, wine_dbgstr_w(compare), wine_dbgstr_w(name));
|
||||
char name_a[100];
|
||||
WideCharToMultiByte(CP_ACP, 0, name, -1, name_a, sizeof(name_a), NULL, NULL);
|
||||
winetest_ok(strcmp(name_a, compare) == 0, "Expected tagid %x to be %s, was %s\n", attr, compare, name_a);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -599,7 +654,7 @@ static void match_guid_attr_imp(PDB pdb, TAGID parent, TAG find, const GUID* com
|
||||
}
|
||||
}
|
||||
|
||||
#define match_strw_attr (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : match_strw_attr_imp
|
||||
#define match_str_attr (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : match_str_attr_imp
|
||||
#define match_dw_attr (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : match_dw_attr_imp
|
||||
#define match_qw_attr (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : match_qw_attr_imp
|
||||
#define match_guid_attr (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : match_guid_attr_imp
|
||||
@@ -633,8 +688,8 @@ static void check_db_properties(PDB pdb, TAGID root)
|
||||
}
|
||||
}
|
||||
match_qw_attr(pdb, root, TAG_TIME, 0x1d1b91a02c0d63e);
|
||||
match_strw_attr(pdb, root, TAG_COMPILER_VERSION, L"2.1.0.3");
|
||||
match_strw_attr(pdb, root, TAG_NAME, L"apphelp_test1");
|
||||
match_str_attr(pdb, root, TAG_COMPILER_VERSION, "2.1.0.3");
|
||||
match_str_attr(pdb, root, TAG_NAME, "apphelp_test1");
|
||||
match_dw_attr(pdb, root, TAG_OS_PLATFORM, 1);
|
||||
}
|
||||
|
||||
@@ -645,14 +700,14 @@ static void check_db_layer(PDB pdb, TAGID layer)
|
||||
if (!layer)
|
||||
return;
|
||||
|
||||
match_strw_attr(pdb, layer, TAG_NAME, L"TestNewMode");
|
||||
match_str_attr(pdb, layer, TAG_NAME, "TestNewMode");
|
||||
shimref = pSdbFindFirstTag(pdb, layer, TAG_SHIM_REF);
|
||||
ok(shimref != TAGID_NULL, "Expected a valid shim ref, got NULL\n");
|
||||
if (!shimref)
|
||||
return;
|
||||
|
||||
match_strw_attr(pdb, shimref, TAG_NAME, L"VirtualRegistry");
|
||||
match_strw_attr(pdb, shimref, TAG_COMMAND_LINE, L"ThemeActive");
|
||||
match_str_attr(pdb, shimref, TAG_NAME, "VirtualRegistry");
|
||||
match_str_attr(pdb, shimref, TAG_COMMAND_LINE, "ThemeActive");
|
||||
inexclude = pSdbFindFirstTag(pdb, shimref, TAG_INEXCLUD);
|
||||
ok(inexclude != TAGID_NULL, "Expected a valid in/exclude ref, got NULL\n");
|
||||
if (!inexclude)
|
||||
@@ -660,7 +715,7 @@ static void check_db_layer(PDB pdb, TAGID layer)
|
||||
|
||||
is_include = pSdbFindFirstTag(pdb, inexclude, TAG_INCLUDE);
|
||||
ok(is_include == TAGID_NULL, "Expected a NULL include ref, but got one anyway.\n");
|
||||
match_strw_attr(pdb, inexclude, TAG_MODULE, L"exclude.dll");
|
||||
match_str_attr(pdb, inexclude, TAG_MODULE, "exclude.dll");
|
||||
|
||||
inexclude = pSdbFindNextTag(pdb, shimref, inexclude);
|
||||
ok(inexclude != TAGID_NULL, "Expected a valid in/exclude ref, got NULL\n");
|
||||
@@ -669,7 +724,7 @@ static void check_db_layer(PDB pdb, TAGID layer)
|
||||
|
||||
is_include = pSdbFindFirstTag(pdb, inexclude, TAG_INCLUDE);
|
||||
ok(is_include != TAGID_NULL, "Expected a valid include ref, got NULL\n");
|
||||
match_strw_attr(pdb, inexclude, TAG_MODULE, L"include.dll");
|
||||
match_str_attr(pdb, inexclude, TAG_MODULE, "include.dll");
|
||||
}
|
||||
|
||||
static void check_matching_file(PDB pdb, TAGID exe, TAGID matching_file, int num)
|
||||
@@ -683,11 +738,11 @@ static void check_matching_file(PDB pdb, TAGID exe, TAGID matching_file, int num
|
||||
return;
|
||||
|
||||
|
||||
match_strw_attr(pdb, matching_file, TAG_NAME, L"*");
|
||||
match_strw_attr(pdb, matching_file, TAG_COMPANY_NAME, L"CompanyName");
|
||||
match_strw_attr(pdb, matching_file, TAG_PRODUCT_NAME, L"ProductName");
|
||||
match_strw_attr(pdb, matching_file, TAG_PRODUCT_VERSION, L"1.0.0.1");
|
||||
match_strw_attr(pdb, matching_file, TAG_FILE_VERSION, L"1.0.0.0");
|
||||
match_str_attr(pdb, matching_file, TAG_NAME, "*");
|
||||
match_str_attr(pdb, matching_file, TAG_COMPANY_NAME, "CompanyName");
|
||||
match_str_attr(pdb, matching_file, TAG_PRODUCT_NAME, "ProductName");
|
||||
match_str_attr(pdb, matching_file, TAG_PRODUCT_VERSION, "1.0.0.1");
|
||||
match_str_attr(pdb, matching_file, TAG_FILE_VERSION, "1.0.0.0");
|
||||
|
||||
if (num == 0 || num == 3)
|
||||
{
|
||||
@@ -707,14 +762,14 @@ static void check_matching_file(PDB pdb, TAGID exe, TAGID matching_file, int num
|
||||
{
|
||||
match_dw_attr(pdb, matching_file, TAG_SIZE, 0x800);
|
||||
match_dw_attr(pdb, matching_file, TAG_CHECKSUM, 0x178bd629);
|
||||
match_strw_attr(pdb, matching_file, TAG_FILE_DESCRIPTION, L"FileDescription");
|
||||
match_str_attr(pdb, matching_file, TAG_FILE_DESCRIPTION, "FileDescription");
|
||||
match_dw_attr(pdb, matching_file, TAG_MODULE_TYPE, 3);
|
||||
match_dw_attr(pdb, matching_file, TAG_VERFILEOS, 4);
|
||||
match_dw_attr(pdb, matching_file, TAG_VERFILETYPE, 1);
|
||||
match_dw_attr(pdb, matching_file, TAG_LINKER_VERSION, 0x40002);
|
||||
match_strw_attr(pdb, matching_file, TAG_ORIGINAL_FILENAME, L"OriginalFilename");
|
||||
match_strw_attr(pdb, matching_file, TAG_INTERNAL_NAME, L"InternalName");
|
||||
match_strw_attr(pdb, matching_file, TAG_LEGAL_COPYRIGHT, L"LegalCopyright");
|
||||
match_str_attr(pdb, matching_file, TAG_ORIGINAL_FILENAME, "OriginalFilename");
|
||||
match_str_attr(pdb, matching_file, TAG_INTERNAL_NAME, "InternalName");
|
||||
match_str_attr(pdb, matching_file, TAG_LEGAL_COPYRIGHT, "LegalCopyright");
|
||||
match_dw_attr(pdb, matching_file, TAG_LINK_DATE, 0x12345);
|
||||
match_dw_attr(pdb, matching_file, TAG_UPTO_LINK_DATE, 0x12345);
|
||||
}
|
||||
@@ -726,7 +781,7 @@ static void check_matching_file(PDB pdb, TAGID exe, TAGID matching_file, int num
|
||||
if (num == 2)
|
||||
{
|
||||
ok(matching_file != TAGID_NULL, "Did expect a secondary match on %d\n", num);
|
||||
match_strw_attr(pdb, matching_file, TAG_NAME, L"test_checkfile.txt");
|
||||
match_str_attr(pdb, matching_file, TAG_NAME, "test_checkfile.txt");
|
||||
match_dw_attr(pdb, matching_file, TAG_SIZE, 0x4);
|
||||
match_dw_attr(pdb, matching_file, TAG_CHECKSUM, 0xb0b0b0b0);
|
||||
}
|
||||
@@ -792,23 +847,23 @@ static void check_matching_layer(PDB pdb, TAGID layer, int num)
|
||||
if (num == 2)
|
||||
{
|
||||
match_dw_attr(pdb, layer, TAG_LAYER_TAGID, 0x18e);
|
||||
match_strw_attr(pdb, layer, TAG_NAME, L"TestNewMode");
|
||||
match_str_attr(pdb, layer, TAG_NAME, "TestNewMode");
|
||||
}
|
||||
else
|
||||
{
|
||||
TAGID layer_tagid = pSdbFindFirstTag(pdb, layer, TAG_LAYER_TAGID);
|
||||
ok(layer_tagid == TAGID_NULL, "expected not to find a layer tagid, got %x\n", layer_tagid);
|
||||
match_strw_attr(pdb, layer, TAG_NAME, L"WinSrv03");
|
||||
match_str_attr(pdb, layer, TAG_NAME, "WinSrv03");
|
||||
}
|
||||
}
|
||||
|
||||
static struct
|
||||
{
|
||||
const WCHAR* name;
|
||||
const WCHAR* app_name;
|
||||
const WCHAR* vendor;
|
||||
const char* name;
|
||||
const char* app_name;
|
||||
const char* vendor;
|
||||
GUID exe_id;
|
||||
const WCHAR* extra_file;
|
||||
const char* extra_file;
|
||||
DWORD dwLayerCount;
|
||||
TAGREF atrExes_0;
|
||||
DWORD adwExeFlags_0;
|
||||
@@ -817,9 +872,9 @@ static struct
|
||||
const char* env_var;
|
||||
} test_exedata[5] = {
|
||||
{
|
||||
L"test_allow.exe",
|
||||
L"apphelp_name_allow",
|
||||
L"apphelp_vendor_allow",
|
||||
"test_allow.exe",
|
||||
"apphelp_name_allow",
|
||||
"apphelp_vendor_allow",
|
||||
{ 0x4e50c93f, 0xb863, 0x4dfa, { 0xba, 0xe2, 0xd8, 0x0e, 0xf4, 0xce, 0x5c, 0x89 } },
|
||||
NULL,
|
||||
0,
|
||||
@@ -830,9 +885,9 @@ static struct
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
L"test_disallow.exe",
|
||||
L"apphelp_name_disallow",
|
||||
L"apphelp_vendor_disallow",
|
||||
"test_disallow.exe",
|
||||
"apphelp_name_disallow",
|
||||
"apphelp_vendor_disallow",
|
||||
{ 0x156720e1, 0xef98, 0x4d04, { 0x96, 0x5a, 0xd8, 0x5d, 0xe0, 0x5e, 0x6d, 0x9f } },
|
||||
NULL,
|
||||
0,
|
||||
@@ -843,11 +898,11 @@ static struct
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
L"test_new.exe",
|
||||
L"fixnew_name",
|
||||
L"fixnew_vendor",
|
||||
"test_new.exe",
|
||||
"fixnew_name",
|
||||
"fixnew_vendor",
|
||||
{ 0xce70ef69, 0xa21d, 0x408b, { 0x84, 0x5b, 0xf9, 0x9e, 0xac, 0x06, 0x09, 0xe7 } },
|
||||
L"test_checkfile.txt",
|
||||
"test_checkfile.txt",
|
||||
1,
|
||||
0x2ec,
|
||||
0,
|
||||
@@ -856,9 +911,9 @@ static struct
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
L"test_w2k3.exe",
|
||||
L"fix_name",
|
||||
L"fix_vendor",
|
||||
"test_w2k3.exe",
|
||||
"fix_name",
|
||||
"fix_vendor",
|
||||
{ 0xb4ead144, 0xf640, 0x4e4b, { 0x94, 0xc4, 0x0c, 0x7f, 0xa8, 0x66, 0x23, 0xb0 } },
|
||||
NULL,
|
||||
0,
|
||||
@@ -869,9 +924,9 @@ static struct
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
L"test_unknown_file.exe",
|
||||
L"apphelp_name_allow",
|
||||
L"apphelp_vendor_allow",
|
||||
"test_unknown_file.exe",
|
||||
"apphelp_name_allow",
|
||||
"apphelp_vendor_allow",
|
||||
{ 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
NULL,
|
||||
1,
|
||||
@@ -895,9 +950,9 @@ static void check_db_exes(PDB pdb, TAGID root)
|
||||
ok(num < 4, "Too many matches, expected only 4!\n");
|
||||
if (num >= 4)
|
||||
break;
|
||||
match_strw_attr(pdb, exe, TAG_NAME, test_exedata[num].name);
|
||||
match_strw_attr(pdb, exe, TAG_APP_NAME, test_exedata[num].app_name);
|
||||
match_strw_attr(pdb, exe, TAG_VENDOR, test_exedata[num].vendor);
|
||||
match_str_attr(pdb, exe, TAG_NAME, test_exedata[num].name);
|
||||
match_str_attr(pdb, exe, TAG_APP_NAME, test_exedata[num].app_name);
|
||||
match_str_attr(pdb, exe, TAG_VENDOR, test_exedata[num].vendor);
|
||||
match_guid_attr(pdb, exe, TAG_EXE_ID, &test_exedata[num].exe_id);
|
||||
check_matching_file(pdb, exe, pSdbFindFirstTag(pdb, exe, TAG_MATCHING_FILE), num);
|
||||
apphelp = pSdbFindFirstTag(pdb, exe, TAG_APPHELP);
|
||||
@@ -931,21 +986,21 @@ static void check_db_exes(PDB pdb, TAGID root)
|
||||
static struct
|
||||
{
|
||||
DWORD htmlhelpid;
|
||||
const WCHAR* link;
|
||||
const WCHAR* apphelp_title;
|
||||
const WCHAR* apphelp_details;
|
||||
const char* link;
|
||||
const char* apphelp_title;
|
||||
const char* apphelp_details;
|
||||
} test_layerdata[2] = {
|
||||
{
|
||||
2,
|
||||
L"http://reactos.org/disallow",
|
||||
L"apphelp_name_disallow",
|
||||
L"Not allowed!",
|
||||
"http://reactos.org/disallow",
|
||||
"apphelp_name_disallow",
|
||||
"Not allowed!",
|
||||
},
|
||||
{
|
||||
1,
|
||||
L"http://reactos.org/allow",
|
||||
L"apphelp_name_allow",
|
||||
L"Allow it!",
|
||||
"http://reactos.org/allow",
|
||||
"apphelp_name_allow",
|
||||
"Allow it!",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -964,10 +1019,10 @@ static void check_db_apphelp(PDB pdb, TAGID root)
|
||||
ok(link != TAGID_NULL, "expected to find a link tag\n");
|
||||
if (link != TAGID_NULL)
|
||||
{
|
||||
match_strw_attr(pdb, link, TAG_LINK_URL, test_layerdata[num].link);
|
||||
match_str_attr(pdb, link, TAG_LINK_URL, test_layerdata[num].link);
|
||||
}
|
||||
match_strw_attr(pdb, apphelp, TAG_APPHELP_TITLE, test_layerdata[num].apphelp_title);
|
||||
match_strw_attr(pdb, apphelp, TAG_APPHELP_DETAILS, test_layerdata[num].apphelp_details);
|
||||
match_str_attr(pdb, apphelp, TAG_APPHELP_TITLE, test_layerdata[num].apphelp_title);
|
||||
match_str_attr(pdb, apphelp, TAG_APPHELP_DETAILS, test_layerdata[num].apphelp_details);
|
||||
apphelp = pSdbFindNextTag(pdb, root, apphelp);
|
||||
num++;
|
||||
}
|
||||
@@ -982,7 +1037,7 @@ static void test_CheckDatabaseManually(void)
|
||||
BOOL ret;
|
||||
DWORD ver_hi, ver_lo;
|
||||
|
||||
test_create_db(L"test_db.sdb", g_WinVersion >= WINVER_WIN10);
|
||||
test_create_db("test_db.sdb", g_WinVersion >= WINVER_WIN10);
|
||||
|
||||
/* both ver_hi and ver_lo cannot be null, it'll crash. */
|
||||
ver_hi = ver_lo = 0x12345678;
|
||||
@@ -1068,29 +1123,6 @@ static void test_is_testdb(PDB pdb)
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL IsUserAdmin()
|
||||
{
|
||||
BOOL Result;
|
||||
SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY };
|
||||
PSID AdministratorsGroup;
|
||||
|
||||
Result = AllocateAndInitializeSid(&NtAuthority, 2,
|
||||
SECURITY_BUILTIN_DOMAIN_RID,
|
||||
DOMAIN_ALIAS_RID_ADMINS,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
&AdministratorsGroup);
|
||||
if (Result)
|
||||
{
|
||||
if (!CheckTokenMembership( NULL, AdministratorsGroup, &Result))
|
||||
Result = FALSE;
|
||||
FreeSid(AdministratorsGroup);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename SDBQUERYRESULT_T>
|
||||
static void check_adwExeFlags(DWORD adwExeFlags_0, SDBQUERYRESULT_T& query, const char* file, int line, int cur)
|
||||
{
|
||||
@@ -1106,9 +1138,10 @@ void check_adwExeFlags(DWORD, SDBQUERYRESULT_2k3&, const char*, int, int)
|
||||
|
||||
|
||||
template<typename SDBQUERYRESULT_T>
|
||||
static void test_mode_generic(const WCHAR* workdir, HSDB hsdb, int cur)
|
||||
static void test_mode_generic(const char* workdir, HSDB hsdb, int cur)
|
||||
{
|
||||
WCHAR exename[MAX_PATH], testfile[MAX_PATH];
|
||||
char exename[MAX_PATH], testfile[MAX_PATH];
|
||||
WCHAR exenameW[MAX_PATH];
|
||||
BOOL ret;
|
||||
SDBQUERYRESULT_T query;
|
||||
PDB pdb;
|
||||
@@ -1119,16 +1152,17 @@ static void test_mode_generic(const WCHAR* workdir, HSDB hsdb, int cur)
|
||||
|
||||
memset(&query, 0xab, sizeof(query));
|
||||
|
||||
swprintf(exename, L"%s\\%s", workdir, test_exedata[cur].name);
|
||||
sprintf(exename, "%s\\%s", workdir, test_exedata[cur].name);
|
||||
if (test_exedata[cur].extra_file)
|
||||
swprintf(testfile, L"%s\\%s", workdir, test_exedata[cur].extra_file);
|
||||
sprintf(testfile, "%s\\%s", workdir, test_exedata[cur].extra_file);
|
||||
test_create_exe(exename, 0);
|
||||
MultiByteToWideChar(CP_ACP, 0, exename, -1, exenameW, MAX_PATH);
|
||||
|
||||
if (test_exedata[cur].extra_file)
|
||||
{
|
||||
/* First we try without the file at all. */
|
||||
DeleteFileW(testfile);
|
||||
ret = pSdbGetMatchingExe(hsdb, exename, NULL, NULL, 0, (SDBQUERYRESULT_VISTA*)&query);
|
||||
DeleteFileA(testfile);
|
||||
ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0, (SDBQUERYRESULT*)&query);
|
||||
ok(ret == 0, "SdbGetMatchingExe should have failed for %d.\n", cur);
|
||||
/* Now re-try with the correct file */
|
||||
test_create_file(testfile, "aaaa", 4);
|
||||
@@ -1136,13 +1170,13 @@ static void test_mode_generic(const WCHAR* workdir, HSDB hsdb, int cur)
|
||||
|
||||
#if 0
|
||||
// Results seem to be cached based on filename, until we can invalidate this, do not test the same filename twice!
|
||||
DeleteFileW(exename);
|
||||
DeleteFileA(exename);
|
||||
// skip exports
|
||||
test_create_exe(exename, 1);
|
||||
ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0, &query);
|
||||
ok(ret == 0, "SdbGetMatchingExe should have failed for %d.\n", cur);
|
||||
|
||||
DeleteFileW(exename);
|
||||
DeleteFileA(exename);
|
||||
test_create_exe(exename, 0);
|
||||
#endif
|
||||
|
||||
@@ -1151,7 +1185,7 @@ static void test_mode_generic(const WCHAR* workdir, HSDB hsdb, int cur)
|
||||
SetEnvironmentVariableA("__COMPAT_LAYER", test_exedata[cur].env_var);
|
||||
}
|
||||
|
||||
ret = pSdbGetMatchingExe(hsdb, exename, NULL, NULL, 0, (SDBQUERYRESULT_VISTA*)&query);
|
||||
ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0, (SDBQUERYRESULT*)&query);
|
||||
ok(ret, "SdbGetMatchingExe should not fail for %d.\n", cur);
|
||||
|
||||
exe_count = (test_exedata[cur].env_var == NULL) ? 1 : 0;
|
||||
@@ -1170,11 +1204,7 @@ static void test_mode_generic(const WCHAR* workdir, HSDB hsdb, int cur)
|
||||
else if (g_WinVersion < WINVER_WIN10)
|
||||
expect_flags = 0x101;
|
||||
else
|
||||
{
|
||||
expect_flags = 0x121; /* for 2 and 3, this becomes 101 when not elevated. */
|
||||
if ((cur == 2 || cur == 3) && !IsUserAdmin())
|
||||
expect_flags &= ~0x20;
|
||||
}
|
||||
|
||||
if (test_exedata[cur].env_var)
|
||||
expect_flags &= ~0x100;
|
||||
@@ -1214,7 +1244,7 @@ static void test_mode_generic(const WCHAR* workdir, HSDB hsdb, int cur)
|
||||
TAG tag = pSdbGetTagFromTagID(pdb, tagid);
|
||||
test_is_testdb(pdb);
|
||||
ok(tag == TAG_EXE, "Expected tag to be TAG_EXE, was 0x%x for %d.\n", tag, cur);
|
||||
match_strw_attr(pdb, tagid, TAG_NAME, test_exedata[cur].name);
|
||||
match_str_attr(pdb, tagid, TAG_NAME, test_exedata[cur].name);
|
||||
|
||||
/* And back again */
|
||||
ret = pSdbTagIDToTagRef(hsdb, pdb, tagid, &tr);
|
||||
@@ -1242,7 +1272,7 @@ static void test_mode_generic(const WCHAR* workdir, HSDB hsdb, int cur)
|
||||
TAG tag = pSdbGetTagFromTagID(pdb, tagid);
|
||||
test_is_testdb(pdb);
|
||||
ok(tag == TAG_LAYER, "Expected tag to be TAG_LAYER, was 0x%x for %d.\n", tag, cur);
|
||||
match_strw_attr(pdb, tagid, TAG_NAME, L"TestNewMode");
|
||||
match_str_attr(pdb, tagid, TAG_NAME, "TestNewMode");
|
||||
|
||||
/* And back again */
|
||||
ret = pSdbTagIDToTagRef(hsdb, pdb, tagid, &tr);
|
||||
@@ -1263,26 +1293,17 @@ static void test_mode_generic(const WCHAR* workdir, HSDB hsdb, int cur)
|
||||
|
||||
|
||||
|
||||
if (RtlDosPathNameToNtPathName_U(exename, &exenameNT, NULL, NULL))
|
||||
if (RtlDosPathNameToNtPathName_U(exenameW, &exenameNT, NULL, NULL))
|
||||
{
|
||||
ret = pSdbGetMatchingExe(hsdb, exenameNT.Buffer, NULL, NULL, 0, (SDBQUERYRESULT_VISTA*)&query);
|
||||
if (!ret && g_WinVersion >= WINVER_WIN10)
|
||||
{
|
||||
/*
|
||||
ERROR,AslPathGetLongFileNameLongpath,110,Long path conversion failed 123 [c0000001]
|
||||
ERROR,AslPathBuildSignatureLongpath,1086,AslPathGetLongFileNameLongpath failed for \??\C:\Users\MARK~1.DEV\AppData\Local\Temp\apphelp_test\test_allow.exe [c0000001]
|
||||
*/
|
||||
trace("Using DOS path for Win10\n");
|
||||
ret = pSdbGetMatchingExe(hsdb, exename, NULL, NULL, 0, (SDBQUERYRESULT_VISTA*)&query);
|
||||
}
|
||||
ret = pSdbGetMatchingExe(hsdb, exenameNT.Buffer, NULL, NULL, 0, (SDBQUERYRESULT*)&query);
|
||||
ok(ret, "SdbGetMatchingExe should not fail for %d.\n", cur);
|
||||
|
||||
RtlFreeUnicodeString(&exenameNT);
|
||||
}
|
||||
|
||||
if (test_exedata[cur].extra_file)
|
||||
DeleteFileW(testfile);
|
||||
DeleteFileW(exename);
|
||||
DeleteFileA(testfile);
|
||||
DeleteFileA(exename);
|
||||
|
||||
if (test_exedata[cur].env_var)
|
||||
{
|
||||
@@ -1293,23 +1314,25 @@ static void test_mode_generic(const WCHAR* workdir, HSDB hsdb, int cur)
|
||||
template<typename SDBQUERYRESULT_T>
|
||||
static void test_MatchApplications(void)
|
||||
{
|
||||
WCHAR workdir[MAX_PATH], dbpath[MAX_PATH];
|
||||
char workdir[MAX_PATH], dbpath[MAX_PATH];
|
||||
WCHAR dbpathW[MAX_PATH];
|
||||
BOOL ret;
|
||||
HSDB hsdb;
|
||||
|
||||
ret = GetTempPathW(_countof(workdir), workdir);
|
||||
ok(ret, "GetTempPathW error: %d\n", GetLastError());
|
||||
wcscat(workdir, L"apphelp_test");
|
||||
ret = GetTempPathA(MAX_PATH, workdir);
|
||||
ok(ret, "GetTempPathA error: %d\n", GetLastError());
|
||||
lstrcatA(workdir, "apphelp_test");
|
||||
|
||||
ret = CreateDirectoryW(workdir, NULL);
|
||||
ok(ret, "CreateDirectoryW error: %d\n", GetLastError());
|
||||
ret = CreateDirectoryA(workdir, NULL);
|
||||
ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
|
||||
|
||||
/* SdbInitDatabase needs an nt-path */
|
||||
swprintf(dbpath, L"\\??\\%s\\test.sdb", workdir);
|
||||
sprintf(dbpath, "\\??\\%s\\test.sdb", workdir);
|
||||
|
||||
test_create_db(dbpath + 4, g_WinVersion >= WINVER_WIN10);
|
||||
|
||||
hsdb = pSdbInitDatabase(HID_DATABASE_FULLPATH, dbpath);
|
||||
MultiByteToWideChar(CP_ACP, 0, dbpath, -1, dbpathW, MAX_PATH);
|
||||
hsdb = pSdbInitDatabase(HID_DATABASE_FULLPATH, dbpathW);
|
||||
|
||||
ok(hsdb != NULL, "Expected a valid database handle\n");
|
||||
|
||||
@@ -1326,156 +1349,16 @@ static void test_MatchApplications(void)
|
||||
pSdbReleaseDatabase(hsdb);
|
||||
}
|
||||
|
||||
DeleteFileW(dbpath + 4);
|
||||
DeleteFileA(dbpath + 4);
|
||||
|
||||
ret = RemoveDirectoryW(workdir);
|
||||
ok(ret, "RemoveDirectoryW error: %d\n", GetLastError());
|
||||
ret = RemoveDirectoryA(workdir);
|
||||
ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
|
||||
}
|
||||
|
||||
static BOOL write_raw_file(const WCHAR* FileName, const void* Data, DWORD Size)
|
||||
{
|
||||
BOOL Success;
|
||||
DWORD dwWritten;
|
||||
HANDLE Handle = CreateFileW(FileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (Handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
skip("Failed to create temp file %ls, error %u\n", FileName, GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
Success = WriteFile(Handle, Data, Size, &dwWritten, NULL);
|
||||
ok(Success == TRUE, "WriteFile failed with %u\n", GetLastError());
|
||||
ok(dwWritten == Size, "WriteFile wrote %u bytes instead of %u\n", dwWritten, Size);
|
||||
CloseHandle(Handle);
|
||||
return Success && (dwWritten == Size);
|
||||
}
|
||||
|
||||
static bool extract_resource(const WCHAR* Filename, LPCWSTR ResourceName)
|
||||
{
|
||||
HMODULE hMod = GetModuleHandleW(NULL);
|
||||
HRSRC hRsrc = FindResourceW(hMod, ResourceName, MAKEINTRESOURCEW(RT_RCDATA));
|
||||
ok(!!hRsrc, "Unable to find %s\n", wine_dbgstr_w(ResourceName));
|
||||
if (!hRsrc)
|
||||
return false;
|
||||
|
||||
HGLOBAL hGlobal = LoadResource(hMod, hRsrc);
|
||||
DWORD Size = SizeofResource(hMod, hRsrc);
|
||||
LPVOID pData = LockResource(hGlobal);
|
||||
|
||||
ok(Size && !!pData, "Unable to load %s\n", wine_dbgstr_w(ResourceName));
|
||||
if (!Size || !pData)
|
||||
return false;
|
||||
|
||||
BOOL Written = write_raw_file(Filename, pData, Size);
|
||||
UnlockResource(pData);
|
||||
return Written;
|
||||
}
|
||||
|
||||
template<typename SDBQUERYRESULT_T>
|
||||
static BOOL test_match_ex(const WCHAR* workdir, HSDB hsdb, int cur)
|
||||
{
|
||||
WCHAR exename[MAX_PATH];
|
||||
WCHAR* Vendor;
|
||||
SDBQUERYRESULT_T query;
|
||||
TAGID tagid, exetag;
|
||||
BOOL ret, Succeed;
|
||||
PDB pdb;
|
||||
|
||||
memset(&query, 0xab, sizeof(query));
|
||||
|
||||
swprintf(exename, L"%s\\test_match%d.exe", workdir, cur);
|
||||
|
||||
ret = pSdbTagRefToTagID(hsdb, 0, &pdb, &tagid);
|
||||
ok(pdb != NULL && pdb != (PDB)0x12345678, "Expected pdb to be set to a valid pdb, was: %p\n", pdb);
|
||||
|
||||
tagid = pSdbFindFirstTag(pdb, TAGID_ROOT, TAG_DATABASE);
|
||||
ok(tagid != TAGID_NULL, "Expected to get a valid TAG_DATABASE\n");
|
||||
|
||||
exetag = pSdbFindFirstNamedTag(pdb, tagid, TAG_EXE, TAG_NAME, exename + wcslen(workdir) + 1);
|
||||
|
||||
if (!exetag)
|
||||
{
|
||||
/* Test done */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tagid = pSdbFindFirstTag(pdb, exetag, TAG_VENDOR);
|
||||
Vendor = pSdbGetStringTagPtr(pdb, tagid);
|
||||
Succeed = tagid != TAGID_NULL && Vendor && !wcsicmp(Vendor, L"Succeed");
|
||||
|
||||
test_create_exe(exename, 0);
|
||||
|
||||
ret = pSdbGetMatchingExe(hsdb, exename, NULL, NULL, 0, (SDBQUERYRESULT_VISTA*)&query);
|
||||
DWORD exe_count = Succeed ? 1 : 0;
|
||||
|
||||
if (Succeed)
|
||||
ok(ret, "SdbGetMatchingExe should not fail for %d.\n", cur);
|
||||
else
|
||||
ok(!ret, "SdbGetMatchingExe should not succeed for %d.\n", cur);
|
||||
|
||||
ok(query.dwExeCount == exe_count, "Expected dwExeCount to be %d, was %d for %d\n", exe_count, query.dwExeCount, cur);
|
||||
DeleteFileW(exename);
|
||||
/* Try the next file */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
template<typename SDBQUERYRESULT_T>
|
||||
static void test_MatchApplicationsEx(void)
|
||||
{
|
||||
WCHAR workdir[MAX_PATH], dbpath[MAX_PATH];
|
||||
BOOL ret;
|
||||
HSDB hsdb;
|
||||
|
||||
ret = GetTempPathW(_countof(workdir), workdir);
|
||||
ok(ret, "GetTempPathW error: %d\n", GetLastError());
|
||||
lstrcatW(workdir, L"apphelp_test");
|
||||
|
||||
ret = CreateDirectoryW(workdir, NULL);
|
||||
ok(ret, "CreateDirectoryW error: %d\n", GetLastError());
|
||||
|
||||
/* SdbInitDatabase needs an nt-path */
|
||||
swprintf(dbpath, L"\\??\\%s\\test.sdb", workdir);
|
||||
|
||||
if (extract_resource(dbpath + 4, MAKEINTRESOURCEW(101)))
|
||||
{
|
||||
hsdb = pSdbInitDatabase(HID_DATABASE_FULLPATH, dbpath);
|
||||
|
||||
ok(hsdb != NULL, "Expected a valid database handle\n");
|
||||
|
||||
if (!hsdb)
|
||||
{
|
||||
skip("SdbInitDatabase not implemented?\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t n;
|
||||
/* now that our enviroment is setup, let's go ahead and run the actual tests.. */
|
||||
for (n = 0;; ++n)
|
||||
{
|
||||
if (!test_match_ex<SDBQUERYRESULT_T>(workdir, hsdb, n))
|
||||
break;
|
||||
}
|
||||
pSdbReleaseDatabase(hsdb);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(0, "Unable to extract database\n");
|
||||
}
|
||||
|
||||
DeleteFileW(dbpath + 4);
|
||||
|
||||
ret = RemoveDirectoryW(workdir);
|
||||
ok(ret, "RemoveDirectoryW error: %d\n", GetLastError());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void test_TagRef(void)
|
||||
{
|
||||
WCHAR tmpdir[MAX_PATH], dbpath[MAX_PATH];
|
||||
char tmpdir[MAX_PATH], dbpath[MAX_PATH];
|
||||
WCHAR dbpathW[MAX_PATH];
|
||||
BOOL ret;
|
||||
HSDB hsdb;
|
||||
PDB pdb;
|
||||
@@ -1483,15 +1366,16 @@ static void test_TagRef(void)
|
||||
DWORD size;
|
||||
TAGREF tr;
|
||||
|
||||
ret = GetTempPathW(_countof(tmpdir), tmpdir);
|
||||
ret = GetTempPathA(MAX_PATH, tmpdir);
|
||||
ok(ret, "GetTempPathA error: %d\n", GetLastError());
|
||||
|
||||
/* SdbInitDatabase needs an nt-path */
|
||||
swprintf(dbpath, L"\\??\\%stest.sdb", tmpdir);
|
||||
sprintf(dbpath, "\\??\\%stest.sdb", tmpdir);
|
||||
|
||||
test_create_db(dbpath + 4, g_WinVersion >= WINVER_WIN10);
|
||||
|
||||
hsdb = pSdbInitDatabase(HID_DATABASE_FULLPATH, dbpath);
|
||||
MultiByteToWideChar(CP_ACP, 0, dbpath, -1, dbpathW, MAX_PATH);
|
||||
hsdb = pSdbInitDatabase(HID_DATABASE_FULLPATH, dbpathW);
|
||||
|
||||
/* HSDB is the only arg that can't be null */
|
||||
ret = pSdbTagRefToTagID(hsdb, 0, NULL, NULL);
|
||||
@@ -1610,7 +1494,7 @@ static void test_TagRef(void)
|
||||
|
||||
pSdbReleaseDatabase(hsdb);
|
||||
|
||||
DeleteFileW(dbpath + 4);
|
||||
DeleteFileA(dbpath + 4);
|
||||
}
|
||||
|
||||
|
||||
@@ -1710,7 +1594,7 @@ static int validate_SDBQUERYRESULT_size()
|
||||
memset(buffer, 0xab, sizeof(buffer));
|
||||
|
||||
GetModuleFileNameW(NULL, path, MAX_PATH);
|
||||
pSdbGetMatchingExe(NULL, path, NULL, NULL, 0, (SDBQUERYRESULT_VISTA*)buffer);
|
||||
pSdbGetMatchingExe(NULL, path, NULL, NULL, 0, (SDBQUERYRESULT*)buffer);
|
||||
if (buffer[0] == 0xab)
|
||||
{
|
||||
trace("SdbGetMatchingExe didnt do anything, cannot determine SDBQUERYRESULT size\n");
|
||||
@@ -1801,11 +1685,9 @@ START_TEST(db)
|
||||
{
|
||||
case 1:
|
||||
test_MatchApplications<SDBQUERYRESULT_2k3>();
|
||||
test_MatchApplicationsEx<SDBQUERYRESULT_2k3>();
|
||||
break;
|
||||
case 2:
|
||||
test_MatchApplications<SDBQUERYRESULT_VISTA>();
|
||||
test_MatchApplicationsEx<SDBQUERYRESULT_VISTA>();
|
||||
test_MatchApplications<SDBQUERYRESULT>();
|
||||
break;
|
||||
default:
|
||||
skip("Skipping tests with SDBQUERYRESULT due to a wrong size reported\n");
|
||||
|
@@ -30,7 +30,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "apitest_iathook.h"
|
||||
|
||||
#include "apphelp_apitest.h"
|
||||
|
||||
#define GPLK_USER 1
|
||||
@@ -612,6 +612,73 @@ UINT WINAPI mGetDriveTypeW(LPCWSTR target)
|
||||
return uRet;
|
||||
}
|
||||
|
||||
|
||||
static PIMAGE_IMPORT_DESCRIPTOR FindImportDescriptor(PBYTE DllBase, PCSTR DllName)
|
||||
{
|
||||
ULONG Size;
|
||||
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = RtlImageDirectoryEntryToData((HMODULE)DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size);
|
||||
while (ImportDescriptor->Name && ImportDescriptor->OriginalFirstThunk)
|
||||
{
|
||||
PCHAR Name = (PCHAR)(DllBase + ImportDescriptor->Name);
|
||||
if (!lstrcmpiA(Name, DllName))
|
||||
{
|
||||
return ImportDescriptor;
|
||||
}
|
||||
ImportDescriptor++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL RedirectIat(PCSTR TargetDllName, PCSTR DllName, PCSTR FunctionName, ULONG_PTR NewFunction, ULONG_PTR* OriginalFunction)
|
||||
{
|
||||
PBYTE DllBase = (PBYTE)GetModuleHandleA(TargetDllName);
|
||||
if (DllBase)
|
||||
{
|
||||
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = FindImportDescriptor(DllBase, DllName);
|
||||
if (ImportDescriptor)
|
||||
{
|
||||
// On loaded images, OriginalFirstThunk points to the name / ordinal of the function
|
||||
PIMAGE_THUNK_DATA OriginalThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->OriginalFirstThunk);
|
||||
// FirstThunk points to the resolved address.
|
||||
PIMAGE_THUNK_DATA FirstThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->FirstThunk);
|
||||
while (OriginalThunk->u1.AddressOfData && FirstThunk->u1.Function)
|
||||
{
|
||||
if (!IMAGE_SNAP_BY_ORDINAL32(OriginalThunk->u1.AddressOfData))
|
||||
{
|
||||
PIMAGE_IMPORT_BY_NAME ImportName = (PIMAGE_IMPORT_BY_NAME)(DllBase + OriginalThunk->u1.AddressOfData);
|
||||
if (!lstrcmpiA((PCSTR)ImportName->Name, FunctionName))
|
||||
{
|
||||
DWORD dwOld;
|
||||
VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR), PAGE_EXECUTE_READWRITE, &dwOld);
|
||||
*OriginalFunction = FirstThunk->u1.Function;
|
||||
FirstThunk->u1.Function = NewFunction;
|
||||
VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR), dwOld, &dwOld);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
OriginalThunk++;
|
||||
FirstThunk++;
|
||||
}
|
||||
skip("Unable to find the Import '%s' from '%s' in %s'\n", FunctionName, DllName, TargetDllName);
|
||||
}
|
||||
else
|
||||
{
|
||||
skip("Unable to find the ImportDescriptor for '%s' in '%s'\n", DllName, TargetDllName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
skip("Unable to find the loaded module '%s'\n", TargetDllName);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL RestoreIat(PCSTR target, PCSTR DllName, PCSTR FunctionName, ULONG_PTR OriginalFunction)
|
||||
{
|
||||
ULONG_PTR old = 0;
|
||||
return RedirectIat(target, DllName, FunctionName, OriginalFunction, &old);
|
||||
}
|
||||
|
||||
static BOOL wrapSdbSetPermLayerKeys2(LPCSTR dir, LPCSTR name, PCSTR szLayers, BOOL bMachine)
|
||||
{
|
||||
char szPath[MAX_PATH];
|
||||
@@ -692,8 +759,7 @@ static void test_Sign_Media(void)
|
||||
ok(ret, "DefineDosDeviceA error: %d\n", GetLastError());
|
||||
if(ret)
|
||||
{
|
||||
ret = RedirectIat(GetModuleHandleA("apphelp.dll"), "kernel32.dll", "GetDriveTypeW",
|
||||
(ULONG_PTR)mGetDriveTypeW, (ULONG_PTR*)&pGetDriveTypeW);
|
||||
ret = RedirectIat("apphelp.dll", "kernel32.dll", "GetDriveTypeW", (ULONG_PTR)mGetDriveTypeW, (ULONG_PTR*)&pGetDriveTypeW);
|
||||
if (g_WinVersion < WINVER_WIN8)
|
||||
ok(ret, "Expected redirect_iat to succeed\n");
|
||||
if(ret)
|
||||
@@ -796,7 +862,7 @@ static void test_Sign_Media(void)
|
||||
ok(wrapSdbSetPermLayerKeys2(drive, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
|
||||
}
|
||||
|
||||
ret = RestoreIat(GetModuleHandleA("apphelp.dll"), "kernel32.dll", "GetDriveTypeW", (ULONG_PTR)pGetDriveTypeW);
|
||||
ret = RestoreIat("apphelp.dll", "kernel32.dll", "GetDriveTypeW", (ULONG_PTR)pGetDriveTypeW);
|
||||
ok(ret, "Expected restore_iat to succeed\n");
|
||||
|
||||
ok(delete_file(subdir, "test.bbb"), "delete_file error: %d\n", GetLastError());
|
||||
|
@@ -1,2 +0,0 @@
|
||||
|
||||
101 RCDATA "testdb.sdb"
|
@@ -1,235 +0,0 @@
|
||||
<SDB>
|
||||
<DATABASE>
|
||||
<NAME>ReactOS test database</NAME>
|
||||
<OS_PLATFORM >1</OS_PLATFORM>
|
||||
<DATABASE_ID>{551F8E78-A9DA-44AC-A24C-5A8145317BC7}</DATABASE_ID>
|
||||
<LIBRARY>
|
||||
</LIBRARY>
|
||||
|
||||
<!-- Verify that we are able to match this -->
|
||||
<EXE>
|
||||
<NAME>test_match0.exe</NAME>
|
||||
<APP_NAME>Generic name</APP_NAME>
|
||||
<VENDOR>Succeed</VENDOR>
|
||||
<MATCHING_FILE>
|
||||
<NAME>*</NAME>
|
||||
<SIZE>2048</SIZE>
|
||||
<CHECKSUM>0x178BD629</CHECKSUM>
|
||||
<PRODUCT_VERSION>1.0.0.1</PRODUCT_VERSION>
|
||||
<!-- BIN_PRODUCT_VERSION? -->
|
||||
<FILE_VERSION>1.0.0.0</FILE_VERSION>
|
||||
<!-- BIN_FILE_VERSION? -->
|
||||
<FILE_DESCRIPTION>FileDescription</FILE_DESCRIPTION>
|
||||
<COMPANY_NAME>CompanyName</COMPANY_NAME>
|
||||
<ORIGINAL_FILENAME>OriginalFilename</ORIGINAL_FILENAME>
|
||||
<INTERNAL_NAME>InternalName</INTERNAL_NAME>
|
||||
</MATCHING_FILE>
|
||||
</EXE>
|
||||
<!-- Verify that we are able to match this -->
|
||||
<EXE>
|
||||
<NAME>test_match1.exe</NAME>
|
||||
<APP_NAME>Generic name</APP_NAME>
|
||||
<VENDOR>Succeed</VENDOR>
|
||||
<MATCHING_FILE>
|
||||
<NAME>*</NAME>
|
||||
<SIZE>2048</SIZE>
|
||||
<CHECKSUM>0x178BD629</CHECKSUM>
|
||||
<PRODUCT_VERSION>1.0.0.1</PRODUCT_VERSION>
|
||||
<!-- BIN_PRODUCT_VERSION? -->
|
||||
<FILE_VERSION>1.0.0.0</FILE_VERSION>
|
||||
<!-- BIN_FILE_VERSION? -->
|
||||
<FILE_DESCRIPTION>FILEDESCRIPTION</FILE_DESCRIPTION>
|
||||
<COMPANY_NAME>companyname</COMPANY_NAME>
|
||||
<ORIGINAL_FILENAME>ORIGINALFILENAME</ORIGINAL_FILENAME>
|
||||
<INTERNAL_NAME>internalname</INTERNAL_NAME>
|
||||
</MATCHING_FILE>
|
||||
</EXE>
|
||||
<!-- SIZE wrong -->
|
||||
<EXE>
|
||||
<NAME>test_match2.exe</NAME>
|
||||
<APP_NAME>Generic name</APP_NAME>
|
||||
<VENDOR>Generic Description</VENDOR>
|
||||
<MATCHING_FILE>
|
||||
<NAME>*</NAME>
|
||||
<SIZE>2047</SIZE>
|
||||
<CHECKSUM>0x178BD629</CHECKSUM>
|
||||
<PRODUCT_VERSION>1.0.0.1</PRODUCT_VERSION>
|
||||
<FILE_VERSION>1.0.0.0</FILE_VERSION>
|
||||
<FILE_DESCRIPTION>FileDescription</FILE_DESCRIPTION>
|
||||
<COMPANY_NAME>CompanyName</COMPANY_NAME>
|
||||
<ORIGINAL_FILENAME>OriginalFilename</ORIGINAL_FILENAME>
|
||||
<INTERNAL_NAME>InternalName</INTERNAL_NAME>
|
||||
</MATCHING_FILE>
|
||||
</EXE>
|
||||
<!-- CHECKSUM wrong -->
|
||||
<EXE>
|
||||
<NAME>test_match3.exe</NAME>
|
||||
<APP_NAME>Generic name</APP_NAME>
|
||||
<VENDOR>Generic Description</VENDOR>
|
||||
<MATCHING_FILE>
|
||||
<NAME>*</NAME>
|
||||
<SIZE>2048</SIZE>
|
||||
<CHECKSUM>0x111111</CHECKSUM>
|
||||
<PRODUCT_VERSION>1.0.0.1</PRODUCT_VERSION>
|
||||
<FILE_VERSION>1.0.0.0</FILE_VERSION>
|
||||
<FILE_DESCRIPTION>FileDescription</FILE_DESCRIPTION>
|
||||
<COMPANY_NAME>CompanyName</COMPANY_NAME>
|
||||
<ORIGINAL_FILENAME>OriginalFilename</ORIGINAL_FILENAME>
|
||||
<INTERNAL_NAME>InternalName</INTERNAL_NAME>
|
||||
</MATCHING_FILE>
|
||||
</EXE>
|
||||
<!-- PRODUCT_VERSION too high -->
|
||||
<EXE>
|
||||
<NAME>test_match4.exe</NAME>
|
||||
<APP_NAME>Generic name</APP_NAME>
|
||||
<VENDOR>Generic Description</VENDOR>
|
||||
<MATCHING_FILE>
|
||||
<NAME>*</NAME>
|
||||
<SIZE>2048</SIZE>
|
||||
<CHECKSUM>0x178BD629</CHECKSUM>
|
||||
<PRODUCT_VERSION>1.1.1.1</PRODUCT_VERSION>
|
||||
<FILE_VERSION>1.0.0.0</FILE_VERSION>
|
||||
<FILE_DESCRIPTION>FileDescription</FILE_DESCRIPTION>
|
||||
<COMPANY_NAME>CompanyName</COMPANY_NAME>
|
||||
<ORIGINAL_FILENAME>OriginalFilename</ORIGINAL_FILENAME>
|
||||
<INTERNAL_NAME>InternalName</INTERNAL_NAME>
|
||||
</MATCHING_FILE>
|
||||
</EXE>
|
||||
<!-- PRODUCT_VERSION too low -->
|
||||
<EXE>
|
||||
<NAME>test_match5.exe</NAME>
|
||||
<APP_NAME>Generic name</APP_NAME>
|
||||
<VENDOR>Generic Description</VENDOR>
|
||||
<MATCHING_FILE>
|
||||
<NAME>*</NAME>
|
||||
<SIZE>2048</SIZE>
|
||||
<CHECKSUM>0x178BD629</CHECKSUM>
|
||||
<PRODUCT_VERSION>1.0.0.0</PRODUCT_VERSION>
|
||||
<FILE_VERSION>1.0.0.0</FILE_VERSION>
|
||||
<FILE_DESCRIPTION>FileDescription</FILE_DESCRIPTION>
|
||||
<COMPANY_NAME>CompanyName</COMPANY_NAME>
|
||||
<ORIGINAL_FILENAME>OriginalFilename</ORIGINAL_FILENAME>
|
||||
<INTERNAL_NAME>InternalName</INTERNAL_NAME>
|
||||
</MATCHING_FILE>
|
||||
</EXE>
|
||||
<!-- FILE_VERSION wrong -->
|
||||
<EXE>
|
||||
<NAME>test_match6.exe</NAME>
|
||||
<APP_NAME>Generic name</APP_NAME>
|
||||
<VENDOR>Generic Description</VENDOR>
|
||||
<MATCHING_FILE>
|
||||
<NAME>*</NAME>
|
||||
<SIZE>2048</SIZE>
|
||||
<CHECKSUM>0x178BD629</CHECKSUM>
|
||||
<PRODUCT_VERSION>1.0.0.1</PRODUCT_VERSION>
|
||||
<FILE_VERSION>1.1.1.1</FILE_VERSION>
|
||||
<FILE_DESCRIPTION>FileDescription</FILE_DESCRIPTION>
|
||||
<COMPANY_NAME>CompanyName</COMPANY_NAME>
|
||||
<ORIGINAL_FILENAME>OriginalFilename</ORIGINAL_FILENAME>
|
||||
<INTERNAL_NAME>InternalName</INTERNAL_NAME>
|
||||
</MATCHING_FILE>
|
||||
</EXE>
|
||||
<!-- FILE_DESCRIPTION wrong -->
|
||||
<EXE>
|
||||
<NAME>test_match7.exe</NAME>
|
||||
<APP_NAME>Generic name</APP_NAME>
|
||||
<VENDOR>Generic Description</VENDOR>
|
||||
<MATCHING_FILE>
|
||||
<NAME>*</NAME>
|
||||
<SIZE>2048</SIZE>
|
||||
<CHECKSUM>0x178BD629</CHECKSUM>
|
||||
<PRODUCT_VERSION>1.0.0.1</PRODUCT_VERSION>
|
||||
<FILE_VERSION>1.0.0.0</FILE_VERSION>
|
||||
<FILE_DESCRIPTION>Wrong Description</FILE_DESCRIPTION>
|
||||
<COMPANY_NAME>CompanyName</COMPANY_NAME>
|
||||
<ORIGINAL_FILENAME>OriginalFilename</ORIGINAL_FILENAME>
|
||||
<INTERNAL_NAME>InternalName</INTERNAL_NAME>
|
||||
</MATCHING_FILE>
|
||||
</EXE>
|
||||
<!-- COMPANY_NAME wrong -->
|
||||
<EXE>
|
||||
<NAME>test_match8.exe</NAME>
|
||||
<APP_NAME>Generic name</APP_NAME>
|
||||
<VENDOR>Generic Description</VENDOR>
|
||||
<MATCHING_FILE>
|
||||
<NAME>*</NAME>
|
||||
<SIZE>2048</SIZE>
|
||||
<CHECKSUM>0x178BD629</CHECKSUM>
|
||||
<PRODUCT_VERSION>1.0.0.1</PRODUCT_VERSION>
|
||||
<FILE_VERSION>1.0.0.0</FILE_VERSION>
|
||||
<FILE_DESCRIPTION>FileDescription</FILE_DESCRIPTION>
|
||||
<COMPANY_NAME>Wrong CompanyName</COMPANY_NAME>
|
||||
<ORIGINAL_FILENAME>OriginalFilename</ORIGINAL_FILENAME>
|
||||
<INTERNAL_NAME>InternalName</INTERNAL_NAME>
|
||||
</MATCHING_FILE>
|
||||
</EXE>
|
||||
<!-- ORIGINAL_FILENAME wrong -->
|
||||
<EXE>
|
||||
<NAME>test_match9.exe</NAME>
|
||||
<APP_NAME>Generic name</APP_NAME>
|
||||
<VENDOR>Generic Description</VENDOR>
|
||||
<MATCHING_FILE>
|
||||
<NAME>*</NAME>
|
||||
<SIZE>2048</SIZE>
|
||||
<CHECKSUM>0x178BD629</CHECKSUM>
|
||||
<PRODUCT_VERSION>1.0.0.1</PRODUCT_VERSION>
|
||||
<FILE_VERSION>1.0.0.0</FILE_VERSION>
|
||||
<FILE_DESCRIPTION>FileDescription</FILE_DESCRIPTION>
|
||||
<COMPANY_NAME>CompanyName</COMPANY_NAME>
|
||||
<ORIGINAL_FILENAME>Wrong OriginalFilename</ORIGINAL_FILENAME>
|
||||
<INTERNAL_NAME>InternalName</INTERNAL_NAME>
|
||||
</MATCHING_FILE>
|
||||
</EXE>
|
||||
<!-- INTERNAL_NAME wrong -->
|
||||
<EXE>
|
||||
<NAME>test_match10.exe</NAME>
|
||||
<APP_NAME>Generic name</APP_NAME>
|
||||
<VENDOR>Generic Description</VENDOR>
|
||||
<MATCHING_FILE>
|
||||
<NAME>*</NAME>
|
||||
<SIZE>2048</SIZE>
|
||||
<CHECKSUM>0x178BD629</CHECKSUM>
|
||||
<PRODUCT_VERSION>1.0.0.1</PRODUCT_VERSION>
|
||||
<FILE_VERSION>1.0.0.0</FILE_VERSION>
|
||||
<FILE_DESCRIPTION>FileDescription</FILE_DESCRIPTION>
|
||||
<COMPANY_NAME>CompanyName</COMPANY_NAME>
|
||||
<ORIGINAL_FILENAME>OriginalFilename</ORIGINAL_FILENAME>
|
||||
<INTERNAL_NAME>wrong InternalName</INTERNAL_NAME>
|
||||
</MATCHING_FILE>
|
||||
</EXE>
|
||||
<!-- Show that strings are checked for the full length(1) -->
|
||||
<EXE>
|
||||
<NAME>test_match11.exe</NAME>
|
||||
<APP_NAME>Generic name</APP_NAME>
|
||||
<VENDOR>Generic Description</VENDOR>
|
||||
<MATCHING_FILE>
|
||||
<NAME>*</NAME>
|
||||
<SIZE>2048</SIZE>
|
||||
<CHECKSUM>0x178BD629</CHECKSUM>
|
||||
<PRODUCT_VERSION>1.0.0.1</PRODUCT_VERSION>
|
||||
<FILE_VERSION>1.0.0.0</FILE_VERSION>
|
||||
<FILE_DESCRIPTION>FileDescription</FILE_DESCRIPTION>
|
||||
<COMPANY_NAME>CompanyName</COMPANY_NAME>
|
||||
<ORIGINAL_FILENAME>OriginalFilename</ORIGINAL_FILENAME>
|
||||
<INTERNAL_NAME>InternalName wrong</INTERNAL_NAME>
|
||||
</MATCHING_FILE>
|
||||
</EXE>
|
||||
<!-- Show that strings are checked for the full length(2) -->
|
||||
<EXE>
|
||||
<NAME>test_match12.exe</NAME>
|
||||
<APP_NAME>Generic name</APP_NAME>
|
||||
<VENDOR>Generic Description</VENDOR>
|
||||
<MATCHING_FILE>
|
||||
<NAME>*</NAME>
|
||||
<SIZE>2048</SIZE>
|
||||
<CHECKSUM>0x178BD629</CHECKSUM>
|
||||
<PRODUCT_VERSION>1.0.0.1</PRODUCT_VERSION>
|
||||
<FILE_VERSION>1.0.0.0</FILE_VERSION>
|
||||
<FILE_DESCRIPTION>FileDescription</FILE_DESCRIPTION>
|
||||
<COMPANY_NAME>CompanyName</COMPANY_NAME>
|
||||
<ORIGINAL_FILENAME>OriginalFilename</ORIGINAL_FILENAME>
|
||||
<INTERNAL_NAME>Internal</INTERNAL_NAME>
|
||||
</MATCHING_FILE>
|
||||
</EXE>
|
||||
</DATABASE>
|
||||
</SDB>
|
@@ -5,14 +5,12 @@
|
||||
|
||||
extern void func_apphelp(void);
|
||||
extern void func_db(void);
|
||||
extern void func_env(void);
|
||||
extern void func_layerapi(void);
|
||||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "apphelp", func_apphelp },
|
||||
{ "db", func_db },
|
||||
{ "env", func_env },
|
||||
{ "layerapi", func_layerapi },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
@@ -27,7 +27,6 @@
|
||||
#include <stdio.h>
|
||||
#include <strsafe.h>
|
||||
#include "wine/test.h"
|
||||
#include "apitest_iathook.h"
|
||||
|
||||
static DWORD g_Version;
|
||||
#define WINVER_ANY 0
|
||||
@@ -312,6 +311,58 @@ static void post_theme_no(void)
|
||||
}
|
||||
}
|
||||
|
||||
static PIMAGE_IMPORT_DESCRIPTOR FindImportDescriptor(PBYTE DllBase, PCSTR DllName)
|
||||
{
|
||||
ULONG Size;
|
||||
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = RtlImageDirectoryEntryToData((HMODULE)DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size);
|
||||
while (ImportDescriptor->Name && ImportDescriptor->OriginalFirstThunk)
|
||||
{
|
||||
PCHAR Name = (PCHAR)(DllBase + ImportDescriptor->Name);
|
||||
if (!lstrcmpiA(Name, DllName))
|
||||
{
|
||||
return ImportDescriptor;
|
||||
}
|
||||
ImportDescriptor++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL RedirectIat(HMODULE TargetDll, PCSTR DllName, PCSTR FunctionName, ULONG_PTR NewFunction, ULONG_PTR* OriginalFunction)
|
||||
{
|
||||
PBYTE DllBase = (PBYTE)TargetDll;
|
||||
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = FindImportDescriptor(DllBase, DllName);
|
||||
if (ImportDescriptor)
|
||||
{
|
||||
// On loaded images, OriginalFirstThunk points to the name / ordinal of the function
|
||||
PIMAGE_THUNK_DATA OriginalThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->OriginalFirstThunk);
|
||||
// FirstThunk points to the resolved address.
|
||||
PIMAGE_THUNK_DATA FirstThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->FirstThunk);
|
||||
while (OriginalThunk->u1.AddressOfData && FirstThunk->u1.Function)
|
||||
{
|
||||
if (!IMAGE_SNAP_BY_ORDINAL32(OriginalThunk->u1.AddressOfData))
|
||||
{
|
||||
PIMAGE_IMPORT_BY_NAME ImportName = (PIMAGE_IMPORT_BY_NAME)(DllBase + OriginalThunk->u1.AddressOfData);
|
||||
if (!lstrcmpiA((PCSTR)ImportName->Name, FunctionName))
|
||||
{
|
||||
DWORD dwOld;
|
||||
VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR), PAGE_EXECUTE_READWRITE, &dwOld);
|
||||
*OriginalFunction = FirstThunk->u1.Function;
|
||||
FirstThunk->u1.Function = NewFunction;
|
||||
VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR), dwOld, &dwOld);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
OriginalThunk++;
|
||||
FirstThunk++;
|
||||
}
|
||||
skip("Unable to find the Import %s!%s\n", DllName, FunctionName);
|
||||
}
|
||||
else
|
||||
{
|
||||
skip("Unable to find the ImportDescriptor for %s\n", DllName);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL hook_disp(HMODULE dll)
|
||||
{
|
||||
@@ -319,21 +370,11 @@ static BOOL hook_disp(HMODULE dll)
|
||||
RedirectIat(dll, "user32.dll", "EnumDisplaySettingsA", (ULONG_PTR)mEnumDisplaySettingsA, (ULONG_PTR*)&pEnumDisplaySettingsA);
|
||||
}
|
||||
|
||||
static VOID unhook_disp(HMODULE dll)
|
||||
{
|
||||
RestoreIat(dll, "user32.dll", "ChangeDisplaySettingsA", (ULONG_PTR)pChangeDisplaySettingsA);
|
||||
RestoreIat(dll, "user32.dll", "EnumDisplaySettingsA", (ULONG_PTR)pEnumDisplaySettingsA);
|
||||
}
|
||||
|
||||
static BOOL hook_theme(HMODULE dll)
|
||||
{
|
||||
return RedirectIat(dll, "uxtheme.dll", "SetThemeAppProperties", (ULONG_PTR)mSetThemeAppProperties, (ULONG_PTR*)&pSetThemeAppProperties);
|
||||
}
|
||||
|
||||
static VOID unhook_theme(HMODULE dll)
|
||||
{
|
||||
RestoreIat(dll, "uxtheme.dll", "SetThemeAppProperties", (ULONG_PTR)pSetThemeAppProperties);
|
||||
}
|
||||
|
||||
static void test_one(LPCSTR shim, DWORD dwReason, void(*pre)(), void(*post)(), void(*second)(void))
|
||||
{
|
||||
@@ -383,25 +424,24 @@ static struct test_info
|
||||
DWORD winver;
|
||||
DWORD reason;
|
||||
BOOL(*hook)(HMODULE);
|
||||
void(*unhook)(HMODULE);
|
||||
void(*pre)(void);
|
||||
void(*post)(void);
|
||||
void(*second)(void);
|
||||
} tests[] =
|
||||
{
|
||||
/* Success */
|
||||
{ "Force8BitColor", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_8bit, post_8bit, post_8bit_no },
|
||||
{ "Force8BitColor", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp,pre_8bit, post_8bit, post_8bit_no },
|
||||
{ "Force640x480", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_640, post_640, post_640_no },
|
||||
{ "Force640x480", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_640, post_640, post_640_no },
|
||||
{ "DisableThemes", L"\\acgenral.dll", WINVER_ANY, 1, hook_theme, unhook_theme, pre_theme, post_theme, post_theme_no },
|
||||
{ "DisableThemes", L"\\acgenral.dll", _WIN32_WINNT_VISTA, 100, hook_theme, unhook_theme, pre_theme, post_theme, post_theme_no },
|
||||
{ "Force8BitColor", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, pre_8bit, post_8bit, post_8bit_no },
|
||||
{ "Force8BitColor", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, pre_8bit, post_8bit, post_8bit_no },
|
||||
{ "Force640x480", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, pre_640, post_640, post_640_no },
|
||||
{ "Force640x480", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, pre_640, post_640, post_640_no },
|
||||
{ "DisableThemes", L"\\acgenral.dll", WINVER_ANY, 1, hook_theme, pre_theme, post_theme, post_theme_no },
|
||||
{ "DisableThemes", L"\\acgenral.dll", _WIN32_WINNT_VISTA, 100, hook_theme, pre_theme, post_theme, post_theme_no },
|
||||
|
||||
/* No need to change anything */
|
||||
{ "Force8BitColor", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no },
|
||||
{ "Force8BitColor", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no },
|
||||
{ "Force640x480", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_640_2, post_640_2, post_640_2_no },
|
||||
{ "Force640x480", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_640_2, post_640_2, post_640_2_no },
|
||||
{ "Force8BitColor", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no },
|
||||
{ "Force8BitColor", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no },
|
||||
{ "Force640x480", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, pre_640_2, post_640_2, post_640_2_no },
|
||||
{ "Force640x480", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, pre_640_2, post_640_2, post_640_2_no },
|
||||
};
|
||||
|
||||
|
||||
@@ -436,7 +476,6 @@ static void run_test(size_t n, BOOL unload)
|
||||
if (ret)
|
||||
{
|
||||
test_one(tests[n].name, tests[n].reason, tests[n].pre, tests[n].post, tests[n].second);
|
||||
tests[n].unhook(dll);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -1,7 +1,6 @@
|
||||
|
||||
add_executable(comctl32_apitest button.c toolbar.c testlist.c ../include/msgtrace.c comctl32_apitest.rc)
|
||||
add_executable(comctl32_apitest button.c testlist.c ../include/msgtrace.c comctl32_apitest.rc)
|
||||
target_link_libraries(comctl32_apitest wine)
|
||||
set_module_type(comctl32_apitest win32cui)
|
||||
add_importlibs(comctl32_apitest uxtheme comctl32 user32 gdi32 msvcrt kernel32 ntdll)
|
||||
add_rostests_file(TARGET comctl32_apitest)
|
||||
add_rostests_file(FILE "${CMAKE_CURRENT_SOURCE_DIR}/comctl32v5.manifest")
|
||||
|
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="5.82.0.0"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
processorArchitecture="*"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
</assembly>
|
@@ -2,11 +2,9 @@
|
||||
#include <apitest.h>
|
||||
|
||||
extern void func_button(void);
|
||||
extern void func_toolbar(void);
|
||||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "buttonv6", func_button },
|
||||
{ "toolbarv6", func_toolbar },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* PROJECT: ReactOS api tests
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* PURPOSE: Test for toolbar window class v6
|
||||
* PROGRAMMERS: Giannis Adamopoulos
|
||||
*/
|
||||
|
||||
#include "wine/test.h"
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <uxtheme.h>
|
||||
#include <undocuser.h>
|
||||
#include <msgtrace.h>
|
||||
#include <user32testhelpers.h>
|
||||
|
||||
HANDLE _CreateV5ActCtx()
|
||||
{
|
||||
ACTCTXW ActCtx = {sizeof(ACTCTX)};
|
||||
WCHAR buffer[MAX_PATH] , *separator;
|
||||
|
||||
ok (GetModuleFileNameW(NULL, buffer, MAX_PATH), "GetModuleFileName failed\n");
|
||||
separator = wcsrchr(buffer, L'\\');
|
||||
if (separator)
|
||||
wcscpy(separator + 1, L"comctl32v5.manifest");
|
||||
|
||||
ActCtx.lpSource = buffer;
|
||||
|
||||
return CreateActCtxW(&ActCtx);;
|
||||
}
|
||||
|
||||
|
||||
void TestVersionMessage()
|
||||
{
|
||||
HWND hwnd;
|
||||
int version;
|
||||
|
||||
hwnd = CreateWindowExW(0, TOOLBARCLASSNAMEW, L"Test", 0, 0, 0, 0, 0, 0, 0, 0, NULL);
|
||||
ok(hwnd != NULL, "CreateWindowEx failed\n");
|
||||
|
||||
version = SendMessageW(hwnd, CCM_GETVERSION, 0, 0);
|
||||
ok(version == 6, "Got %d, expected 6\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_SETVERSION, 5, 0);
|
||||
ok(version == 6, "Got %d, expected 6\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_GETVERSION, 0, 0);
|
||||
ok(version == 6, "Got %d, expected 6\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_SETVERSION, 7, 0);
|
||||
ok(version == 6, "Got %d, expected 6\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_GETVERSION, 0, 0);
|
||||
ok(version == 6, "Got %d, expected 6\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_SETVERSION, 4, 0);
|
||||
ok(version == 6, "Got %d, expected 6\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_GETVERSION, 0, 0);
|
||||
ok(version == 6, "Got %d, expected 6\n", version);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
void TestV5VersionMessage()
|
||||
{
|
||||
HWND hwnd;
|
||||
int version;
|
||||
|
||||
hwnd = CreateWindowExW(0, TOOLBARCLASSNAMEW, L"Test", 0, 0, 0, 0, 0, 0, 0, 0, NULL);
|
||||
ok(hwnd != NULL, "CreateWindowEx failed\n");
|
||||
|
||||
version = SendMessageW(hwnd, CCM_GETVERSION, 0, 0);
|
||||
ok(version == 0, "Got %d, expected 0\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_SETVERSION, 6, 0);
|
||||
ok(version == -1, "Got %d, expected -1\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_SETVERSION, 7, 0);
|
||||
ok(version == -1, "Got %d, expected -1\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_SETVERSION, 5, 0);
|
||||
ok(version == 0, "Got %d, expected -1\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_GETVERSION, 0, 0);
|
||||
ok(version == 5, "Got %d, expected 5\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_SETVERSION, 4, 0);
|
||||
ok(version == 5, "Got %d, expected -1\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_GETVERSION, 0, 0);
|
||||
ok(version == 4, "Got %d, expected 5\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_SETVERSION, 3, 0);
|
||||
ok(version == 4, "Got %d, expected -1\n", version);
|
||||
|
||||
version = SendMessageW(hwnd, CCM_GETVERSION, 0, 0);
|
||||
ok(version == 3, "Got %d, expected 5\n", version);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
START_TEST(toolbar)
|
||||
{
|
||||
HANDLE hV5ActCtx;
|
||||
|
||||
LoadLibraryW(L"comctl32.dll");
|
||||
|
||||
TestVersionMessage();
|
||||
|
||||
hV5ActCtx = _CreateV5ActCtx();
|
||||
ok (hV5ActCtx != INVALID_HANDLE_VALUE, "CreateActCtxW failed\n");
|
||||
if (hV5ActCtx)
|
||||
{
|
||||
ULONG_PTR cookie;
|
||||
BOOL bActivated = ActivateActCtx(hV5ActCtx, &cookie);
|
||||
if (bActivated)
|
||||
{
|
||||
TestV5VersionMessage();
|
||||
DeactivateActCtx(0, cookie);
|
||||
}
|
||||
}
|
||||
}
|
@@ -32,173 +32,161 @@ typedef struct _fnt_test
|
||||
static fnt_test test_data[] =
|
||||
{
|
||||
{
|
||||
/* .ResourceName = */ "PanosePitchTest.ttf",
|
||||
/* .NumFaces = */ 2,
|
||||
/* .res = */
|
||||
.ResourceName = "PanosePitchTest.ttf",
|
||||
.NumFaces = 2,
|
||||
.res =
|
||||
{
|
||||
{
|
||||
/* .FontName = */ "PanosePitchTest",
|
||||
{
|
||||
/* .tm.tmHeight = */ 11,
|
||||
/* .tm.tmAscent = */ 11,
|
||||
/* .tm.tmDescent = */ 0,
|
||||
/* .tm.tmInternalLeading = */ -5,
|
||||
/* .tm.tmExternalLeading = */ 1,
|
||||
/* .tm.tmAveCharWidth = */ 8,
|
||||
/* .tm.tmMaxCharWidth = */ 11,
|
||||
/* .tm.tmWeight = */ FW_NORMAL,
|
||||
/* .tm.tmOverhang = */ 0,
|
||||
/* .tm.tmDigitizedAspectX = */ 96,
|
||||
/* .tm.tmDigitizedAspectY = */ 96,
|
||||
/* .tm.tmFirstChar = */ 63,
|
||||
/* .tm.tmLastChar = */ 65,
|
||||
/* .tm.tmDefaultChar = */ 165,
|
||||
/* .tm.tmBreakChar = */ 65,
|
||||
/* .tm.tmItalic = */ 0,
|
||||
/* .tm.tmUnderlined = */ 0,
|
||||
/* .tm.tmStruckOut = */ 0,
|
||||
/* .tm.tmPitchAndFamily = */ TMPF_TRUETYPE | TMPF_VECTOR,
|
||||
/* .tm.tmCharSet = */ SHIFTJIS_CHARSET,
|
||||
}
|
||||
.FontName = "PanosePitchTest",
|
||||
.tm.tmHeight = 11,
|
||||
.tm.tmAscent = 11,
|
||||
.tm.tmDescent = 0,
|
||||
.tm.tmInternalLeading = -5,
|
||||
.tm.tmExternalLeading = 1,
|
||||
.tm.tmAveCharWidth = 8,
|
||||
.tm.tmMaxCharWidth = 11,
|
||||
.tm.tmWeight = FW_NORMAL,
|
||||
.tm.tmOverhang = 0,
|
||||
.tm.tmDigitizedAspectX = 96,
|
||||
.tm.tmDigitizedAspectY = 96,
|
||||
.tm.tmFirstChar = 63,
|
||||
.tm.tmLastChar = 65,
|
||||
.tm.tmDefaultChar = 165,
|
||||
.tm.tmBreakChar = 65,
|
||||
.tm.tmItalic = 0,
|
||||
.tm.tmUnderlined = 0,
|
||||
.tm.tmStruckOut = 0,
|
||||
.tm.tmPitchAndFamily = TMPF_TRUETYPE | TMPF_VECTOR,
|
||||
.tm.tmCharSet = SHIFTJIS_CHARSET,
|
||||
},
|
||||
{
|
||||
/* .FontName = */ "@PanosePitchTest",
|
||||
{
|
||||
/* .tm.tmHeight = */ 11,
|
||||
/* .tm.tmAscent = */ 11,
|
||||
/* .tm.tmDescent = */ 0,
|
||||
/* .tm.tmInternalLeading = */ -5,
|
||||
/* .tm.tmExternalLeading = */ 1,
|
||||
/* .tm.tmAveCharWidth = */ 8,
|
||||
/* .tm.tmMaxCharWidth = */ 11,
|
||||
/* .tm.tmWeight = */ FW_NORMAL,
|
||||
/* .tm.tmOverhang = */ 0,
|
||||
/* .tm.tmDigitizedAspectX = */ 96,
|
||||
/* .tm.tmDigitizedAspectY = */ 96,
|
||||
/* .tm.tmFirstChar = */ 63,
|
||||
/* .tm.tmLastChar = */ 65,
|
||||
/* .tm.tmDefaultChar = */ 165,
|
||||
/* .tm.tmBreakChar = */ 65,
|
||||
/* .tm.tmItalic = */ 0,
|
||||
/* .tm.tmUnderlined = */ 0,
|
||||
/* .tm.tmStruckOut = */ 0,
|
||||
/* .tm.tmPitchAndFamily = */ TMPF_TRUETYPE | TMPF_VECTOR,
|
||||
/* .tm.tmCharSet = */ SHIFTJIS_CHARSET,
|
||||
}
|
||||
.FontName = "@PanosePitchTest",
|
||||
.tm.tmHeight = 11,
|
||||
.tm.tmAscent = 11,
|
||||
.tm.tmDescent = 0,
|
||||
.tm.tmInternalLeading = -5,
|
||||
.tm.tmExternalLeading = 1,
|
||||
.tm.tmAveCharWidth = 8,
|
||||
.tm.tmMaxCharWidth = 11,
|
||||
.tm.tmWeight = FW_NORMAL,
|
||||
.tm.tmOverhang = 0,
|
||||
.tm.tmDigitizedAspectX = 96,
|
||||
.tm.tmDigitizedAspectY = 96,
|
||||
.tm.tmFirstChar = 63,
|
||||
.tm.tmLastChar = 65,
|
||||
.tm.tmDefaultChar = 165,
|
||||
.tm.tmBreakChar = 65,
|
||||
.tm.tmItalic = 0,
|
||||
.tm.tmUnderlined = 0,
|
||||
.tm.tmStruckOut = 0,
|
||||
.tm.tmPitchAndFamily = TMPF_TRUETYPE | TMPF_VECTOR,
|
||||
.tm.tmCharSet = SHIFTJIS_CHARSET,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
/* .ResourceName = */ "TTCTestV.ttc",
|
||||
/* .NumFaces = */ 3,
|
||||
/* .res = */
|
||||
.ResourceName = "TTCTestV.ttc",
|
||||
.NumFaces = 3,
|
||||
.res =
|
||||
{
|
||||
{
|
||||
/* .FontName = */ "No1Of3in1",
|
||||
{
|
||||
/* .tm.tmHeight = */ 12,
|
||||
/* .tm.tmAscent = */ 12,
|
||||
/* .tm.tmDescent = */ 0,
|
||||
/* .tm.tmInternalLeading = */ -4,
|
||||
/* .tm.tmExternalLeading = */ 1,
|
||||
/* .tm.tmAveCharWidth = */ -525,
|
||||
/* .tm.tmMaxCharWidth = */ 6,
|
||||
/* .tm.tmWeight = */ FW_NORMAL,
|
||||
/* .tm.tmOverhang = */ 0,
|
||||
/* .tm.tmDigitizedAspectX = */ 96,
|
||||
/* .tm.tmDigitizedAspectY = */ 96,
|
||||
/* .tm.tmFirstChar = */ 63,
|
||||
/* .tm.tmLastChar = */ 65,
|
||||
/* .tm.tmDefaultChar = */ 64,
|
||||
/* .tm.tmBreakChar = */ 65,
|
||||
/* .tm.tmItalic = */ 0,
|
||||
/* .tm.tmUnderlined = */ 0,
|
||||
/* .tm.tmStruckOut = */ 0,
|
||||
/* .tm.tmPitchAndFamily = */ TMPF_TRUETYPE | TMPF_VECTOR | TMPF_FIXED_PITCH,
|
||||
/* .tm.tmCharSet = */ ANSI_CHARSET,
|
||||
}
|
||||
.FontName = "No1Of3in1",
|
||||
.tm.tmHeight = 12,
|
||||
.tm.tmAscent = 12,
|
||||
.tm.tmDescent = 0,
|
||||
.tm.tmInternalLeading = -4,
|
||||
.tm.tmExternalLeading = 1,
|
||||
.tm.tmAveCharWidth = -525,
|
||||
.tm.tmMaxCharWidth = 6,
|
||||
.tm.tmWeight = FW_NORMAL,
|
||||
.tm.tmOverhang = 0,
|
||||
.tm.tmDigitizedAspectX = 96,
|
||||
.tm.tmDigitizedAspectY = 96,
|
||||
.tm.tmFirstChar = 63,
|
||||
.tm.tmLastChar = 65,
|
||||
.tm.tmDefaultChar = 64,
|
||||
.tm.tmBreakChar = 65,
|
||||
.tm.tmItalic = 0,
|
||||
.tm.tmUnderlined = 0,
|
||||
.tm.tmStruckOut = 0,
|
||||
.tm.tmPitchAndFamily = TMPF_TRUETYPE | TMPF_VECTOR | TMPF_FIXED_PITCH,
|
||||
.tm.tmCharSet = ANSI_CHARSET,
|
||||
},
|
||||
{
|
||||
/* .FontName = */ "No2Of3in1",
|
||||
{
|
||||
/* .tm.tmHeight = */ 12,
|
||||
/* .tm.tmAscent = */ 12,
|
||||
/* .tm.tmDescent = */ 0,
|
||||
/* .tm.tmInternalLeading = */ -4,
|
||||
/* .tm.tmExternalLeading = */ 1,
|
||||
/* .tm.tmAveCharWidth = */ 8,
|
||||
/* .tm.tmMaxCharWidth = */ 7,
|
||||
/* .tm.tmWeight = */ FW_NORMAL,
|
||||
/* .tm.tmOverhang = */ 0,
|
||||
/* .tm.tmDigitizedAspectX = */ 96,
|
||||
/* .tm.tmDigitizedAspectY = */ 96,
|
||||
/* .tm.tmFirstChar = */ 63,
|
||||
/* .tm.tmLastChar = */ 65,
|
||||
/* .tm.tmDefaultChar = */ 64,
|
||||
/* .tm.tmBreakChar = */ 65,
|
||||
/* .tm.tmItalic = */ 0,
|
||||
/* .tm.tmUnderlined = */ 0,
|
||||
/* .tm.tmStruckOut = */ 0,
|
||||
/* .tm.tmPitchAndFamily = */ TMPF_TRUETYPE | TMPF_VECTOR | TMPF_FIXED_PITCH,
|
||||
/* .tm.tmCharSet = */ ANSI_CHARSET,
|
||||
}
|
||||
.FontName = "No2Of3in1",
|
||||
.tm.tmHeight = 12,
|
||||
.tm.tmAscent = 12,
|
||||
.tm.tmDescent = 0,
|
||||
.tm.tmInternalLeading = -4,
|
||||
.tm.tmExternalLeading = 1,
|
||||
.tm.tmAveCharWidth = 8,
|
||||
.tm.tmMaxCharWidth = 7,
|
||||
.tm.tmWeight = FW_NORMAL,
|
||||
.tm.tmOverhang = 0,
|
||||
.tm.tmDigitizedAspectX = 96,
|
||||
.tm.tmDigitizedAspectY = 96,
|
||||
.tm.tmFirstChar = 63,
|
||||
.tm.tmLastChar = 65,
|
||||
.tm.tmDefaultChar = 64,
|
||||
.tm.tmBreakChar = 65,
|
||||
.tm.tmItalic = 0,
|
||||
.tm.tmUnderlined = 0,
|
||||
.tm.tmStruckOut = 0,
|
||||
.tm.tmPitchAndFamily = TMPF_TRUETYPE | TMPF_VECTOR | TMPF_FIXED_PITCH,
|
||||
.tm.tmCharSet = ANSI_CHARSET,
|
||||
},
|
||||
{
|
||||
/* .FontName = */ "No3Of3in1V",
|
||||
{
|
||||
/* .tm.tmHeight = */ 12,
|
||||
/* .tm.tmAscent = */ 12,
|
||||
/* .tm.tmDescent = */ 0,
|
||||
/* .tm.tmInternalLeading = */ -4,
|
||||
/* .tm.tmExternalLeading = */ 1,
|
||||
/* .tm.tmAveCharWidth = */ 8,
|
||||
/* .tm.tmMaxCharWidth = */ 13,
|
||||
/* .tm.tmWeight = */ FW_NORMAL,
|
||||
/* .tm.tmOverhang = */ 0,
|
||||
/* .tm.tmDigitizedAspectX = */ 96,
|
||||
/* .tm.tmDigitizedAspectY = */ 96,
|
||||
/* .tm.tmFirstChar = */ 63,
|
||||
/* .tm.tmLastChar = */ 65,
|
||||
/* .tm.tmDefaultChar = */ 64,
|
||||
/* .tm.tmBreakChar = */ 65,
|
||||
/* .tm.tmItalic = */ 0,
|
||||
/* .tm.tmUnderlined = */ 0,
|
||||
/* .tm.tmStruckOut = */ 0,
|
||||
/* .tm.tmPitchAndFamily = */ FF_MODERN | TMPF_TRUETYPE | TMPF_VECTOR,
|
||||
/* .tm.tmCharSet = */ ANSI_CHARSET,
|
||||
}
|
||||
.FontName = "No3Of3in1V",
|
||||
.tm.tmHeight = 12,
|
||||
.tm.tmAscent = 12,
|
||||
.tm.tmDescent = 0,
|
||||
.tm.tmInternalLeading = -4,
|
||||
.tm.tmExternalLeading = 1,
|
||||
.tm.tmAveCharWidth = 8,
|
||||
.tm.tmMaxCharWidth = 13,
|
||||
.tm.tmWeight = FW_NORMAL,
|
||||
.tm.tmOverhang = 0,
|
||||
.tm.tmDigitizedAspectX = 96,
|
||||
.tm.tmDigitizedAspectY = 96,
|
||||
.tm.tmFirstChar = 63,
|
||||
.tm.tmLastChar = 65,
|
||||
.tm.tmDefaultChar = 64,
|
||||
.tm.tmBreakChar = 65,
|
||||
.tm.tmItalic = 0,
|
||||
.tm.tmUnderlined = 0,
|
||||
.tm.tmStruckOut = 0,
|
||||
.tm.tmPitchAndFamily = FF_MODERN | TMPF_TRUETYPE | TMPF_VECTOR,
|
||||
.tm.tmCharSet = ANSI_CHARSET,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
/* .ResourceName = */ "Shadows_Into_Light.ttf",
|
||||
/* .NumFaces = */ 1,
|
||||
/* .res = */
|
||||
.ResourceName = "Shadows_Into_Light.ttf",
|
||||
.NumFaces = 1,
|
||||
.res =
|
||||
{
|
||||
{
|
||||
/* .FontName = */ "ufaXaAlLOxCUGYJ7KN51UP2Q==",
|
||||
{
|
||||
/* .tm.tmHeight = */ 26,
|
||||
/* .tm.tmAscent = */ 19,
|
||||
/* .tm.tmDescent = */ 7,
|
||||
/* .tm.tmInternalLeading = */ 10,
|
||||
/* .tm.tmExternalLeading = */ 0,
|
||||
/* .tm.tmAveCharWidth = */ 7,
|
||||
/* .tm.tmMaxCharWidth = */ 23,
|
||||
/* .tm.tmWeight = */ FW_NORMAL,
|
||||
/* .tm.tmOverhang = */ 0,
|
||||
/* .tm.tmDigitizedAspectX = */ 96,
|
||||
/* .tm.tmDigitizedAspectY = */ 96,
|
||||
/* .tm.tmFirstChar = */ 30,
|
||||
/* .tm.tmLastChar = */ 255,
|
||||
/* .tm.tmDefaultChar = */ 31,
|
||||
/* .tm.tmBreakChar = */ 32,
|
||||
/* .tm.tmItalic = */ 0,
|
||||
/* .tm.tmUnderlined = */ 0,
|
||||
/* .tm.tmStruckOut = */ 0,
|
||||
/* .tm.tmPitchAndFamily = */ TMPF_TRUETYPE | TMPF_VECTOR | TMPF_FIXED_PITCH,
|
||||
/* .tm.tmCharSet = */ ANSI_CHARSET,
|
||||
}
|
||||
.FontName = "ufaXaAlLOxCUGYJ7KN51UP2Q==",
|
||||
.tm.tmHeight = 26,
|
||||
.tm.tmAscent = 19,
|
||||
.tm.tmDescent = 7,
|
||||
.tm.tmInternalLeading = 10,
|
||||
.tm.tmExternalLeading = 0,
|
||||
.tm.tmAveCharWidth = 7,
|
||||
.tm.tmMaxCharWidth = 23,
|
||||
.tm.tmWeight = FW_NORMAL,
|
||||
.tm.tmOverhang = 0,
|
||||
.tm.tmDigitizedAspectX = 96,
|
||||
.tm.tmDigitizedAspectY = 96,
|
||||
.tm.tmFirstChar = 30,
|
||||
.tm.tmLastChar = 255,
|
||||
.tm.tmDefaultChar = 31,
|
||||
.tm.tmBreakChar = 32,
|
||||
.tm.tmItalic = 0,
|
||||
.tm.tmUnderlined = 0,
|
||||
.tm.tmStruckOut = 0,
|
||||
.tm.tmPitchAndFamily = TMPF_TRUETYPE | TMPF_VECTOR | TMPF_FIXED_PITCH,
|
||||
.tm.tmCharSet = ANSI_CHARSET,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@@ -1,64 +0,0 @@
|
||||
#ifndef _APITEST_IATHOOK_H
|
||||
#define _APITEST_IATHOOK_H
|
||||
|
||||
static PIMAGE_IMPORT_DESCRIPTOR FindImportDescriptor(PBYTE DllBase, PCSTR DllName)
|
||||
{
|
||||
ULONG Size;
|
||||
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = RtlImageDirectoryEntryToData((HMODULE)DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size);
|
||||
while (ImportDescriptor->Name && ImportDescriptor->OriginalFirstThunk)
|
||||
{
|
||||
PCHAR Name = (PCHAR)(DllBase + ImportDescriptor->Name);
|
||||
if (!lstrcmpiA(Name, DllName))
|
||||
{
|
||||
return ImportDescriptor;
|
||||
}
|
||||
ImportDescriptor++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL RedirectIat(HMODULE TargetDll, PCSTR DllName, PCSTR FunctionName, ULONG_PTR NewFunction, ULONG_PTR* OriginalFunction)
|
||||
{
|
||||
PBYTE DllBase = (PBYTE)TargetDll;
|
||||
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = FindImportDescriptor(DllBase, DllName);
|
||||
if (ImportDescriptor)
|
||||
{
|
||||
// On loaded images, OriginalFirstThunk points to the name / ordinal of the function
|
||||
PIMAGE_THUNK_DATA OriginalThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->OriginalFirstThunk);
|
||||
// FirstThunk points to the resolved address.
|
||||
PIMAGE_THUNK_DATA FirstThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->FirstThunk);
|
||||
while (OriginalThunk->u1.AddressOfData && FirstThunk->u1.Function)
|
||||
{
|
||||
if (!IMAGE_SNAP_BY_ORDINAL32(OriginalThunk->u1.AddressOfData))
|
||||
{
|
||||
PIMAGE_IMPORT_BY_NAME ImportName = (PIMAGE_IMPORT_BY_NAME)(DllBase + OriginalThunk->u1.AddressOfData);
|
||||
if (!lstrcmpiA((PCSTR)ImportName->Name, FunctionName))
|
||||
{
|
||||
DWORD dwOld;
|
||||
VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR), PAGE_EXECUTE_READWRITE, &dwOld);
|
||||
*OriginalFunction = FirstThunk->u1.Function;
|
||||
FirstThunk->u1.Function = NewFunction;
|
||||
VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR), dwOld, &dwOld);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
OriginalThunk++;
|
||||
FirstThunk++;
|
||||
}
|
||||
skip("Unable to find the Import %s!%s\n", DllName, FunctionName);
|
||||
}
|
||||
else
|
||||
{
|
||||
skip("Unable to find the ImportDescriptor for %s\n", DllName);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL RestoreIat(HMODULE TargetDll, PCSTR DllName, PCSTR FunctionName, ULONG_PTR OriginalFunction)
|
||||
{
|
||||
ULONG_PTR old = 0;
|
||||
return RedirectIat(TargetDll, DllName, FunctionName, OriginalFunction, &old);
|
||||
}
|
||||
|
||||
#endif // _APITEST_IATHOOK_H
|
||||
|
@@ -62,8 +62,6 @@ static char* get_msg_name(UINT msg)
|
||||
case WM_COMMAND: return "WM_COMMAND";
|
||||
case WM_PRINTCLIENT: return "WM_PRINTCLIENT";
|
||||
case WM_CTLCOLORSTATIC: return "WM_CTLCOLORSTATIC";
|
||||
case WM_STYLECHANGING: return "WM_STYLECHANGING";
|
||||
case WM_STYLECHANGED: return "WM_STYLECHANGED";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
@@ -99,14 +97,12 @@ void sprintf_msg_entry(char* buffer, MSG_ENTRY* msg)
|
||||
switch (msg->type)
|
||||
{
|
||||
case POST:
|
||||
case MARKER:
|
||||
msgName = get_msg_name(msg->msg);
|
||||
msgType = msg->type == POST ? "post msg" : "marker";
|
||||
msgType = "post msg";
|
||||
break;
|
||||
case SENT:
|
||||
case SENT_RET:
|
||||
msgName = get_msg_name(msg->msg);
|
||||
msgType = msg->type == SENT ? "sent msg" : "sent_ret msg";
|
||||
msgType = "sent msg";
|
||||
break;
|
||||
case HOOK:
|
||||
msgName = get_hook_name(msg->msg);
|
||||
|
@@ -6,9 +6,7 @@ typedef enum _MSG_TYPE
|
||||
SENT,
|
||||
POST,
|
||||
HOOK,
|
||||
EVENT,
|
||||
SENT_RET,
|
||||
MARKER
|
||||
EVENT
|
||||
} MSG_TYPE;
|
||||
|
||||
typedef struct _MSG_ENTRY
|
||||
|
@@ -3,7 +3,6 @@ add_subdirectory(redirptest)
|
||||
|
||||
list(APPEND SOURCE
|
||||
Console.c
|
||||
CreateProcess.c
|
||||
DefaultActCtx.c
|
||||
DeviceIoControl.c
|
||||
dosdev.c
|
||||
@@ -14,7 +13,6 @@ list(APPEND SOURCE
|
||||
GetDriveType.c
|
||||
GetModuleFileName.c
|
||||
interlck.c
|
||||
IsDBCSLeadByteEx.c
|
||||
LoadLibraryExW.c
|
||||
lstrcpynW.c
|
||||
lstrlen.c
|
||||
|
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* PROJECT: ReactOS api tests
|
||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||
* PURPOSE: Test spoiling of StaticUnicodeString by CreateProcessA
|
||||
* PROGRAMMERS: Mark Jansen
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
#include <ndk/rtltypes.h>
|
||||
#include <ndk/rtlfuncs.h>
|
||||
|
||||
|
||||
START_TEST(CreateProcess)
|
||||
{
|
||||
PUNICODE_STRING StaticString;
|
||||
UNICODE_STRING CompareString;
|
||||
BOOL Process;
|
||||
STARTUPINFO si = {0};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
LONG Result;
|
||||
|
||||
StaticString = &NtCurrentTeb()->StaticUnicodeString;
|
||||
RtlInitUnicodeString(&CompareString, L"--sentinel--");
|
||||
RtlCopyUnicodeString(StaticString, &CompareString);
|
||||
|
||||
si.cb = sizeof(si);
|
||||
Process = CreateProcessA("ApplicationName", "CommandLine", NULL, NULL, FALSE, 0, NULL, "CurrentDir", &si, &pi);
|
||||
ok_int(Process, 0);
|
||||
|
||||
Result = RtlCompareUnicodeString(StaticString, &CompareString, TRUE);
|
||||
ok(!Result, "Expected %s to equal %s\n",
|
||||
wine_dbgstr_wn(StaticString->Buffer, StaticString->Length / sizeof(WCHAR)),
|
||||
wine_dbgstr_wn(CompareString.Buffer, CompareString.Length / sizeof(WCHAR)));
|
||||
}
|
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* PROJECT: ReactOS api tests
|
||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||
* PURPOSE: Tests for IsDBCSLeadByteEx
|
||||
* PROGRAMMER: Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#define _INC_WINDOWS
|
||||
#define COM_NO_WINDOWS_H
|
||||
#include <stdio.h>
|
||||
#include <winnls.h>
|
||||
|
||||
#define MAX_RANGE 4
|
||||
|
||||
typedef struct RANGE
|
||||
{
|
||||
int StartIndex;
|
||||
int EndIndex;
|
||||
} RANGE;
|
||||
|
||||
typedef struct ENTRY
|
||||
{
|
||||
const char *Name;
|
||||
int CodePage;
|
||||
int RangeCount;
|
||||
RANGE Ranges[MAX_RANGE];
|
||||
} ENTRY;
|
||||
|
||||
START_TEST(IsDBCSLeadByteEx)
|
||||
{
|
||||
static const ENTRY Entries[] =
|
||||
{
|
||||
{
|
||||
"English", 437,
|
||||
0
|
||||
},
|
||||
{
|
||||
"ChineseSimpilified", 936,
|
||||
1,
|
||||
{
|
||||
{ 0x81, 0xFE }
|
||||
}
|
||||
},
|
||||
{
|
||||
"ChineseTraditional", 950,
|
||||
1,
|
||||
{
|
||||
{ 0x81, 0xFE }
|
||||
}
|
||||
},
|
||||
{
|
||||
"Japanese", 932,
|
||||
2,
|
||||
{
|
||||
{ 0x81, 0x9F }, { 0xE0, 0xFC }
|
||||
}
|
||||
},
|
||||
{
|
||||
"Korean", 949,
|
||||
1,
|
||||
{
|
||||
{ 0x81, 0xFE }
|
||||
}
|
||||
}
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < _countof(Entries); ++i)
|
||||
{
|
||||
int Index, iRange;
|
||||
int CodePage = Entries[i].CodePage, StartIndex = 0, RangeCount = 0;
|
||||
BOOL InRange = FALSE;
|
||||
RANGE Ranges[MAX_RANGE];
|
||||
const char *Name = Entries[i].Name;
|
||||
|
||||
ZeroMemory(&Ranges, sizeof(Ranges));
|
||||
|
||||
for (Index = 0; Index < 256; ++Index)
|
||||
{
|
||||
if (InRange)
|
||||
{
|
||||
if (!IsDBCSLeadByteEx(CodePage, Index))
|
||||
{
|
||||
Ranges[RangeCount].StartIndex = StartIndex;
|
||||
Ranges[RangeCount].EndIndex = Index - 1;
|
||||
++RangeCount;
|
||||
InRange = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsDBCSLeadByteEx(CodePage, Index))
|
||||
{
|
||||
StartIndex = Index;
|
||||
InRange = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (InRange)
|
||||
{
|
||||
Ranges[RangeCount].StartIndex = StartIndex;
|
||||
Ranges[RangeCount].EndIndex = Index - 1;
|
||||
++RangeCount;
|
||||
}
|
||||
|
||||
ok(RangeCount == Entries[i].RangeCount,
|
||||
"%s: RangeCount expected %d, was %d\n",
|
||||
Name, Entries[i].RangeCount, RangeCount);
|
||||
for (iRange = 0; iRange < Entries[i].RangeCount; ++iRange)
|
||||
{
|
||||
const RANGE *pRange = &Entries[i].Ranges[iRange];
|
||||
int iStart = Ranges[iRange].StartIndex;
|
||||
int iEnd = Ranges[iRange].EndIndex;
|
||||
ok(iStart == pRange->StartIndex,
|
||||
"%s: Ranges[%d].StartIndex expected: 0x%02X, was: 0x%02X\n",
|
||||
Name, iRange, pRange->StartIndex, iStart);
|
||||
ok(iEnd == pRange->EndIndex,
|
||||
"%s: Ranges[%d].EndIndex was expected: 0x%02X, was: 0x%02X\n",
|
||||
Name, iRange, pRange->EndIndex, iEnd);
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,7 +4,6 @@
|
||||
#include <apitest.h>
|
||||
|
||||
extern void func_Console(void);
|
||||
extern void func_CreateProcess(void);
|
||||
extern void func_DefaultActCtx(void);
|
||||
extern void func_DeviceIoControl(void);
|
||||
extern void func_dosdev(void);
|
||||
@@ -15,7 +14,6 @@ extern void func_GetCurrentDirectory(void);
|
||||
extern void func_GetDriveType(void);
|
||||
extern void func_GetModuleFileName(void);
|
||||
extern void func_interlck(void);
|
||||
extern void func_IsDBCSLeadByteEx(void);
|
||||
extern void func_LoadLibraryExW(void);
|
||||
extern void func_lstrcpynW(void);
|
||||
extern void func_lstrlen(void);
|
||||
@@ -32,7 +30,6 @@ extern void func_WideCharToMultiByte(void);
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "ConsoleCP", func_Console },
|
||||
{ "CreateProcess", func_CreateProcess },
|
||||
{ "DefaultActCtx", func_DefaultActCtx },
|
||||
{ "DeviceIoControl", func_DeviceIoControl },
|
||||
{ "dosdev", func_dosdev },
|
||||
@@ -43,7 +40,6 @@ const struct test winetest_testlist[] =
|
||||
{ "GetDriveType", func_GetDriveType },
|
||||
{ "GetModuleFileName", func_GetModuleFileName },
|
||||
{ "interlck", func_interlck },
|
||||
{ "IsDBCSLeadByteEx", func_IsDBCSLeadByteEx },
|
||||
{ "LoadLibraryExW", func_LoadLibraryExW },
|
||||
{ "lstrcpynW", func_lstrcpynW },
|
||||
{ "lstrlen", func_lstrlen },
|
||||
|
@@ -1,10 +0,0 @@
|
||||
|
||||
list(APPEND SOURCE
|
||||
DsRoleGetPrimaryDomainInformation.c
|
||||
testlist.c)
|
||||
|
||||
add_executable(netapi32_apitest ${SOURCE})
|
||||
target_link_libraries(netapi32_apitest wine ${PSEH_LIB})
|
||||
set_module_type(netapi32_apitest win32cui)
|
||||
add_importlibs(netapi32_apitest netapi32 msvcrt kernel32 ntdll)
|
||||
add_rostests_file(TARGET netapi32_apitest)
|
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* PROJECT: ReactOS netapi32.dll API Tests
|
||||
* LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
|
||||
* PURPOSE: Tests for DsRoleGetPrimaryDomainInformation
|
||||
* COPYRIGHT: Copyright 2017 Colin Finck <colin@reactos.org>
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <dsrole.h>
|
||||
|
||||
START_TEST(DsRoleGetPrimaryDomainInformation)
|
||||
{
|
||||
DWORD dwErrorCode;
|
||||
PDSROLE_PRIMARY_DOMAIN_INFO_BASIC pInfo = NULL;
|
||||
|
||||
// Get information about the domain membership of this computer.
|
||||
dwErrorCode = DsRoleGetPrimaryDomainInformation(NULL, DsRolePrimaryDomainInfoBasic, (PBYTE*)&pInfo);
|
||||
ok(dwErrorCode == ERROR_SUCCESS, "DsRoleGetPrimaryDomainInformation returns %lu!\n", dwErrorCode);
|
||||
ok(pInfo->MachineRole >= DsRole_RoleStandaloneWorkstation && pInfo->MachineRole <= DsRole_RolePrimaryDomainController, "pInfo->MachineRole is %u!\n", pInfo->MachineRole);
|
||||
|
||||
if (pInfo)
|
||||
DsRoleFreeMemory(pInfo);
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* PROJECT: ReactOS netapi32.dll API Tests
|
||||
* LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
|
||||
* PURPOSE: Test list
|
||||
* COPYRIGHT: Copyright 2017 Colin Finck <colin@reactos.org>
|
||||
*/
|
||||
|
||||
#define __ROS_LONG64__
|
||||
|
||||
#define STANDALONE
|
||||
#include <apitest.h>
|
||||
|
||||
extern void func_DsRoleGetPrimaryDomainInformation(void);
|
||||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "DsRoleGetPrimaryDomainInformation", func_DsRoleGetPrimaryDomainInformation },
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
@@ -10,7 +10,6 @@ list(APPEND SOURCE
|
||||
NtCreateThread.c
|
||||
NtDeleteKey.c
|
||||
NtFreeVirtualMemory.c
|
||||
NtLoadUnloadKey.c
|
||||
NtMapViewOfSection.c
|
||||
NtMutant.c
|
||||
NtOpenProcessToken.c
|
||||
|
@@ -1,636 +0,0 @@
|
||||
/*
|
||||
* PROJECT: ReactOS API Tests
|
||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||
* PURPOSE: Test for NtLoadKey and NtUnloadKey
|
||||
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <apitest.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#include <ndk/rtlfuncs.h>
|
||||
#include <ndk/cmfuncs.h>
|
||||
#include <ndk/cmtypes.h>
|
||||
#include <ndk/iofuncs.h>
|
||||
#include <ndk/obfuncs.h>
|
||||
#include <ndk/setypes.h>
|
||||
|
||||
/* See xdk/cmtypes.h */
|
||||
#define REG_CREATED_NEW_KEY 1
|
||||
#define REG_OPENED_EXISTING_KEY 2
|
||||
|
||||
#define REG_FORCE_UNLOAD 1
|
||||
|
||||
#if 1
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#else
|
||||
|
||||
#define DPRINT(fmt, ...) printf("(%s:%d) " fmt, __FILE__, __LINE__, ##__VA_ARGS__);
|
||||
#define DPRINT1(fmt, ...) printf("(%s:%d) " fmt, __FILE__, __LINE__, ##__VA_ARGS__);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static BOOLEAN
|
||||
RetrieveCurrentModuleNTDirectory(
|
||||
OUT PUNICODE_STRING NtPath)
|
||||
{
|
||||
WCHAR ModulePath[MAX_PATH];
|
||||
PWSTR PathSep;
|
||||
|
||||
/* Retrieve the current path where the test is running */
|
||||
GetModuleFileNameW(NULL, ModulePath, _countof(ModulePath));
|
||||
PathSep = wcsrchr(ModulePath, L'\\');
|
||||
if (!PathSep)
|
||||
PathSep = ModulePath + wcslen(ModulePath);
|
||||
*PathSep = UNICODE_NULL;
|
||||
|
||||
/* Convert the path to NT format and work with it for now on */
|
||||
return RtlDosPathNameToNtPathName_U(ModulePath, NtPath, NULL, NULL);
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
CreateRegKey(
|
||||
OUT PHANDLE KeyHandle,
|
||||
IN HANDLE RootKey OPTIONAL,
|
||||
IN PUNICODE_STRING KeyName,
|
||||
IN ULONG CreateOptions,
|
||||
OUT PULONG Disposition OPTIONAL)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
RootKey,
|
||||
NULL);
|
||||
return NtCreateKey(KeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
CreateOptions,
|
||||
Disposition);
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
CreateProtoHive(
|
||||
OUT PHANDLE KeyHandle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING KeyName;
|
||||
|
||||
RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\SYSTEM\\$$$PROTO.HIV");
|
||||
Status = CreateRegKey(KeyHandle,
|
||||
NULL,
|
||||
&KeyName,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
NtFlushKey(KeyHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
static VOID
|
||||
DestroyProtoHive(
|
||||
IN HANDLE KeyHandle)
|
||||
{
|
||||
NtDeleteKey(KeyHandle);
|
||||
NtClose(KeyHandle);
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
OpenDirectoryByHandleOrPath(
|
||||
OUT PHANDLE RootPathHandle,
|
||||
IN HANDLE RootDirectory OPTIONAL,
|
||||
IN PUNICODE_STRING RootPath OPTIONAL)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
*RootPathHandle = NULL;
|
||||
|
||||
/*
|
||||
* RootDirectory and RootPath cannot be either both NULL
|
||||
* or both non-NULL, when being specified.
|
||||
*/
|
||||
if ((!RootDirectory && !RootPath) ||
|
||||
( RootDirectory && RootPath))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!RootDirectory && RootPath)
|
||||
{
|
||||
/* Open the root directory path */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
RootPath,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = NtOpenFile(RootPathHandle,
|
||||
// FILE_TRAVERSE is needed to be able to use the handle as RootDirectory for future InitializeObjectAttributes calls.
|
||||
FILE_LIST_DIRECTORY | FILE_ADD_FILE /* | FILE_ADD_SUBDIRECTORY */ | FILE_TRAVERSE | SYNCHRONIZE,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE /* | FILE_OPEN_FOR_BACKUP_INTENT */);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtOpenFile(%wZ) failed, Status 0x%08lx\n", RootPath, Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Mark the handle as being opened locally */
|
||||
*RootPathHandle = (HANDLE)((ULONG_PTR)*RootPathHandle | 1);
|
||||
}
|
||||
else if (RootDirectory && !RootPath)
|
||||
{
|
||||
*RootPathHandle = RootDirectory;
|
||||
}
|
||||
// No other cases possible
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Should be called under privileges
|
||||
*/
|
||||
static NTSTATUS
|
||||
CreateRegistryFile(
|
||||
IN HANDLE RootDirectory OPTIONAL,
|
||||
IN PUNICODE_STRING RootPath OPTIONAL,
|
||||
IN PCWSTR RegistryKey,
|
||||
IN HANDLE ProtoKeyHandle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE RootPathHandle, FileHandle;
|
||||
UNICODE_STRING FileName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
/* Open the root directory */
|
||||
Status = OpenDirectoryByHandleOrPath(&RootPathHandle, RootDirectory, RootPath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("OpenDirectoryByHandleOrPath failed, Status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Create the file */
|
||||
RtlInitUnicodeString(&FileName, RegistryKey);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&FileName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
(HANDLE)((ULONG_PTR)RootPathHandle & ~1), // Remove the opened-locally flag
|
||||
NULL);
|
||||
Status = NtCreateFile(&FileHandle,
|
||||
FILE_GENERIC_WRITE /* | DELETE */,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL,
|
||||
FILE_ATTRIBUTE_NORMAL /* | FILE_FLAG_DELETE_ON_CLOSE */,
|
||||
0,
|
||||
FILE_OVERWRITE_IF,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE,
|
||||
NULL,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtCreateFile(%wZ) failed, Status 0x%08lx\n", &FileName, Status);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Save the selected hive into the file */
|
||||
Status = NtSaveKeyEx(ProtoKeyHandle, FileHandle, REG_LATEST_FORMAT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtSaveKeyEx(%wZ) failed, Status 0x%08lx\n", &FileName, Status);
|
||||
}
|
||||
|
||||
/* Close the file, the root directory (if opened locally), and return */
|
||||
NtClose(FileHandle);
|
||||
Cleanup:
|
||||
if ((ULONG_PTR)RootPathHandle & 1) NtClose((HANDLE)((ULONG_PTR)RootPathHandle & ~1));
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Should be called under privileges
|
||||
*/
|
||||
static NTSTATUS
|
||||
MyDeleteFile(
|
||||
IN HANDLE RootDirectory OPTIONAL,
|
||||
IN PUNICODE_STRING RootPath OPTIONAL,
|
||||
IN PCWSTR FileName,
|
||||
IN BOOLEAN ForceDelete) // ForceDelete can be used to delete read-only files
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE RootPathHandle;
|
||||
UNICODE_STRING NtPath;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HANDLE FileHandle;
|
||||
FILE_DISPOSITION_INFORMATION FileDispInfo;
|
||||
BOOLEAN RetryOnce = FALSE;
|
||||
|
||||
/* Open the root directory */
|
||||
Status = OpenDirectoryByHandleOrPath(&RootPathHandle, RootDirectory, RootPath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("OpenDirectoryByHandleOrPath failed, Status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Open the directory name that was passed in */
|
||||
RtlInitUnicodeString(&NtPath, FileName);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&NtPath,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
RootPathHandle,
|
||||
NULL);
|
||||
|
||||
Retry: /* We go back there once if RetryOnce == TRUE */
|
||||
Status = NtOpenFile(&FileHandle,
|
||||
DELETE | FILE_READ_ATTRIBUTES |
|
||||
(RetryOnce ? FILE_WRITE_ATTRIBUTES : 0),
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtOpenFile failed with Status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RetryOnce)
|
||||
{
|
||||
FILE_BASIC_INFORMATION FileInformation;
|
||||
|
||||
Status = NtQueryInformationFile(FileHandle,
|
||||
&IoStatusBlock,
|
||||
&FileInformation,
|
||||
sizeof(FILE_BASIC_INFORMATION),
|
||||
FileBasicInformation);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtQueryInformationFile failed with Status 0x%08lx\n", Status);
|
||||
NtClose(FileHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;
|
||||
Status = NtSetInformationFile(FileHandle,
|
||||
&IoStatusBlock,
|
||||
&FileInformation,
|
||||
sizeof(FILE_BASIC_INFORMATION),
|
||||
FileBasicInformation);
|
||||
NtClose(FileHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtSetInformationFile failed with Status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ask for the file to be deleted */
|
||||
FileDispInfo.DeleteFile = TRUE;
|
||||
Status = NtSetInformationFile(FileHandle,
|
||||
&IoStatusBlock,
|
||||
&FileDispInfo,
|
||||
sizeof(FILE_DISPOSITION_INFORMATION),
|
||||
FileDispositionInformation);
|
||||
NtClose(FileHandle);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
DPRINT1("Deletion of file '%S' failed, Status 0x%08lx\n", FileName, Status);
|
||||
|
||||
// FIXME: Check the precise value of Status!
|
||||
if (!NT_SUCCESS(Status) && ForceDelete && !RetryOnce)
|
||||
{
|
||||
/* Retry once */
|
||||
RetryOnce = TRUE;
|
||||
goto Retry;
|
||||
}
|
||||
|
||||
/* Return result to the caller */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Should be called under privileges
|
||||
*/
|
||||
static NTSTATUS
|
||||
ConnectRegistry(
|
||||
IN HANDLE RootKey OPTIONAL,
|
||||
IN PCWSTR RegMountPoint,
|
||||
IN HANDLE RootDirectory OPTIONAL,
|
||||
IN PUNICODE_STRING RootPath OPTIONAL,
|
||||
IN PCWSTR RegistryKey)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE RootPathHandle;
|
||||
UNICODE_STRING KeyName, FileName;
|
||||
OBJECT_ATTRIBUTES KeyObjectAttributes;
|
||||
OBJECT_ATTRIBUTES FileObjectAttributes;
|
||||
|
||||
/* Open the root directory */
|
||||
Status = OpenDirectoryByHandleOrPath(&RootPathHandle, RootDirectory, RootPath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("OpenDirectoryByHandleOrPath failed, Status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&KeyName, RegMountPoint);
|
||||
InitializeObjectAttributes(&KeyObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
RootKey,
|
||||
NULL);
|
||||
|
||||
RtlInitUnicodeString(&FileName, RegistryKey);
|
||||
InitializeObjectAttributes(&FileObjectAttributes,
|
||||
&FileName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
(HANDLE)((ULONG_PTR)RootPathHandle & ~1), // Remove the opened-locally flag
|
||||
NULL);
|
||||
|
||||
/* Mount the registry hive in the registry namespace */
|
||||
Status = NtLoadKey(&KeyObjectAttributes, &FileObjectAttributes);
|
||||
|
||||
/* Close the root directory (if opened locally), and return */
|
||||
if ((ULONG_PTR)RootPathHandle & 1) NtClose((HANDLE)((ULONG_PTR)RootPathHandle & ~1));
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Should be called under privileges
|
||||
*/
|
||||
static NTSTATUS
|
||||
DisconnectRegistry(
|
||||
IN HANDLE RootKey OPTIONAL,
|
||||
IN PCWSTR RegMountPoint,
|
||||
IN ULONG Flags)
|
||||
{
|
||||
UNICODE_STRING KeyName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
RtlInitUnicodeString(&KeyName, RegMountPoint);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
RootKey,
|
||||
NULL);
|
||||
// return NtUnloadKey(&ObjectAttributes);
|
||||
return NtUnloadKey2(&ObjectAttributes, Flags);
|
||||
}
|
||||
|
||||
|
||||
START_TEST(NtLoadUnloadKey)
|
||||
{
|
||||
typedef struct _HIVE_LIST_ENTRY
|
||||
{
|
||||
PCWSTR HiveName;
|
||||
PCWSTR RegMountPoint;
|
||||
} HIVE_LIST_ENTRY, *PHIVE_LIST_ENTRY;
|
||||
|
||||
static const HIVE_LIST_ENTRY RegistryHives[] =
|
||||
{
|
||||
{ L"TestHive1", L"\\Registry\\Machine\\TestHive1" },
|
||||
{ L"TestHive2", L"\\Registry\\Machine\\TestHive2" },
|
||||
};
|
||||
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING NtTestPath;
|
||||
UNICODE_STRING KeyName;
|
||||
HANDLE KeyHandle;
|
||||
ULONG Disposition;
|
||||
UINT i;
|
||||
BOOLEAN PrivilegeSet[2] = {FALSE, FALSE};
|
||||
WCHAR PathBuffer[MAX_PATH];
|
||||
|
||||
/* Retrieve our current directory */
|
||||
RetrieveCurrentModuleNTDirectory(&NtTestPath);
|
||||
|
||||
/* Acquire restore privilege */
|
||||
Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[0]);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
skip("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Status 0x%08lx)\n", Status);
|
||||
/* Exit prematurely here.... */
|
||||
// goto Cleanup;
|
||||
RtlFreeUnicodeString(&NtTestPath);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Acquire backup privilege */
|
||||
Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
skip("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Status 0x%08lx)\n", Status);
|
||||
RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]);
|
||||
/* Exit prematurely here.... */
|
||||
// goto Cleanup;
|
||||
RtlFreeUnicodeString(&NtTestPath);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create the template proto-hive */
|
||||
Status = CreateProtoHive(&KeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
skip("CreateProtoHive() failed to create the proto-hive; Status 0x%08lx\n", Status);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Create two registry hive files from it */
|
||||
for (i = 0; i < _countof(RegistryHives); ++i)
|
||||
{
|
||||
Status = CreateRegistryFile(NULL, &NtTestPath,
|
||||
RegistryHives[i].HiveName,
|
||||
KeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("CreateRegistryFile(%S) failed, Status 0x%08lx\n", RegistryHives[i].HiveName, Status);
|
||||
/* Exit prematurely here.... */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* That is now done, remove the proto-hive */
|
||||
DestroyProtoHive(KeyHandle);
|
||||
|
||||
/* Exit prematurely here if we failed */
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto Cleanup;
|
||||
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
|
||||
/* Now, mount the first hive */
|
||||
Status = ConnectRegistry(NULL, RegistryHives[0].RegMountPoint,
|
||||
NULL, &NtTestPath,
|
||||
RegistryHives[0].HiveName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("ConnectRegistry('%wZ\\%S', '%S') failed, Status 0x%08lx\n",
|
||||
&NtTestPath, RegistryHives[0].HiveName, RegistryHives[0].RegMountPoint, Status);
|
||||
}
|
||||
|
||||
/* Create or open a key inside the mounted hive */
|
||||
StringCchPrintfW(PathBuffer, _countof(PathBuffer), L"%s\\%s", RegistryHives[0].RegMountPoint, L"MyKey_1");
|
||||
RtlInitUnicodeString(&KeyName, PathBuffer);
|
||||
|
||||
KeyHandle = NULL;
|
||||
Status = CreateRegKey(&KeyHandle,
|
||||
NULL,
|
||||
&KeyName,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
&Disposition);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("CreateRegKey(%wZ) failed (Status %lx)\n", &KeyName, Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("CreateRegKey(%wZ) succeeded to %s the key (Status %lx)\n",
|
||||
&KeyName,
|
||||
Disposition == REG_CREATED_NEW_KEY ? "create" : /* REG_OPENED_EXISTING_KEY */ "open",
|
||||
Status);
|
||||
}
|
||||
|
||||
/* The key handle must be valid here */
|
||||
Status = NtFlushKey(KeyHandle);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
|
||||
/* Attempt to unmount the hive, with the handle key still opened */
|
||||
Status = DisconnectRegistry(NULL, RegistryHives[0].RegMountPoint, 0); // Same as NtUnloadKey(&ObjectAttributes);
|
||||
DPRINT1("Unmounting '%S' %s\n", RegistryHives[0].RegMountPoint, NT_SUCCESS(Status) ? "succeeded" : "failed");
|
||||
ok_ntstatus(Status, STATUS_CANNOT_DELETE);
|
||||
|
||||
/* The key handle should still be valid here */
|
||||
Status = NtFlushKey(KeyHandle);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
|
||||
#if 0 // Currently, leads to memory corruption !!!!!
|
||||
|
||||
/* Force-unmount the hive, with the handle key still opened */
|
||||
Status = DisconnectRegistry(NULL, RegistryHives[0].RegMountPoint, REG_FORCE_UNLOAD);
|
||||
DPRINT1("Force-unmounting '%S' %s\n", RegistryHives[0].RegMountPoint, NT_SUCCESS(Status) ? "succeeded" : "failed");
|
||||
ok_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
/* The key handle should not be valid anymore */
|
||||
Status = NtFlushKey(KeyHandle);
|
||||
if (Status != STATUS_KEY_DELETED /* Win2k3 */ &&
|
||||
Status != STATUS_HIVE_UNLOADED /* Win7+ */)
|
||||
{
|
||||
ok_ntstatus(Status, STATUS_KEY_DELETED);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* The key handle should not be valid anymore */
|
||||
Status = NtDeleteKey(KeyHandle);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
|
||||
/* Close by principle the handle, but should this fail? */
|
||||
Status = NtClose(KeyHandle);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
|
||||
/* Now, mount the first hive, again */
|
||||
Status = ConnectRegistry(NULL, RegistryHives[0].RegMountPoint,
|
||||
NULL, &NtTestPath,
|
||||
RegistryHives[0].HiveName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("ConnectRegistry('%wZ\\%S', '%S') failed, Status 0x%08lx\n",
|
||||
&NtTestPath, RegistryHives[0].HiveName, RegistryHives[0].RegMountPoint, Status);
|
||||
}
|
||||
|
||||
/* Create or open a key inside the mounted hive */
|
||||
StringCchPrintfW(PathBuffer, _countof(PathBuffer), L"%s\\%s", RegistryHives[0].RegMountPoint, L"MyKey_2");
|
||||
RtlInitUnicodeString(&KeyName, PathBuffer);
|
||||
|
||||
KeyHandle = NULL;
|
||||
Status = CreateRegKey(&KeyHandle,
|
||||
NULL,
|
||||
&KeyName,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
&Disposition);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("CreateRegKey(%wZ) failed (Status %lx)\n", &KeyName, Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("CreateRegKey(%wZ) succeeded to %s the key (Status %lx)\n",
|
||||
&KeyName,
|
||||
Disposition == REG_CREATED_NEW_KEY ? "create" : /* REG_OPENED_EXISTING_KEY */ "open",
|
||||
Status);
|
||||
}
|
||||
|
||||
/* The key handle must be valid here */
|
||||
Status = NtFlushKey(KeyHandle);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
|
||||
/* Delete the key, this should succeed */
|
||||
Status = NtDeleteKey(KeyHandle);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
|
||||
/* Close the handle, this should succeed */
|
||||
Status = NtClose(KeyHandle);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
|
||||
/* Attempt to unmount the hive (no forcing), this should succeed */
|
||||
Status = DisconnectRegistry(NULL, RegistryHives[0].RegMountPoint, 0); // Same as NtUnloadKey(&ObjectAttributes);
|
||||
DPRINT1("Unmounting '%S' %s\n", RegistryHives[0].RegMountPoint, NT_SUCCESS(Status) ? "succeeded" : "failed");
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
|
||||
/* Force-unmount the hive (it is already unmounted), this should fail */
|
||||
Status = DisconnectRegistry(NULL, RegistryHives[0].RegMountPoint, REG_FORCE_UNLOAD);
|
||||
DPRINT1("Force-unmounting '%S' %s\n", RegistryHives[0].RegMountPoint, NT_SUCCESS(Status) ? "succeeded" : "failed");
|
||||
ok_hex(Status, STATUS_INVALID_PARAMETER);
|
||||
|
||||
#if 0
|
||||
/* Close by principle the handle, but should this fail? */
|
||||
Status = NtClose(KeyHandle);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
|
||||
Cleanup:
|
||||
|
||||
/* Destroy the hive files */
|
||||
for (i = 0; i < _countof(RegistryHives); ++i)
|
||||
{
|
||||
Status = MyDeleteFile(NULL, &NtTestPath,
|
||||
RegistryHives[i].HiveName, TRUE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
DPRINT1("MyDeleteFile(%S) failed, Status 0x%08lx\n", RegistryHives[i].HiveName, Status);
|
||||
}
|
||||
|
||||
/* Remove restore and backup privileges */
|
||||
RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE, &PrivilegeSet[1]);
|
||||
RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]);
|
||||
|
||||
RtlFreeUnicodeString(&NtTestPath);
|
||||
}
|
@@ -2,8 +2,6 @@
|
||||
* PROJECT: ReactOS API Tests
|
||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||
* PURPOSE: Test for the NtProtectVirtualMemory API
|
||||
* PROGRAMMERS: Jérôme Gardou <jerome.gardou@reactos.org>
|
||||
* Thomas Faber <thomas.faber@reactos.org>
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
@@ -12,15 +10,13 @@
|
||||
#include <ndk/rtlfuncs.h>
|
||||
#include <ndk/mmfuncs.h>
|
||||
|
||||
static
|
||||
void
|
||||
TestReadWrite(void)
|
||||
START_TEST(NtProtectVirtualMemory)
|
||||
{
|
||||
ULONG* allocationStart = NULL;
|
||||
NTSTATUS status;
|
||||
SIZE_T allocationSize;
|
||||
ULONG oldProtection;
|
||||
|
||||
|
||||
/* Reserve a page */
|
||||
allocationSize = PAGE_SIZE;
|
||||
status = NtAllocateVirtualMemory(NtCurrentProcess(),
|
||||
@@ -30,7 +26,7 @@ TestReadWrite(void)
|
||||
MEM_RESERVE,
|
||||
PAGE_NOACCESS);
|
||||
ok(NT_SUCCESS(status), "Reserving memory failed\n");
|
||||
|
||||
|
||||
/* Commit the page (RW) */
|
||||
status = NtAllocateVirtualMemory(NtCurrentProcess(),
|
||||
(void**)&allocationStart,
|
||||
@@ -39,19 +35,19 @@ TestReadWrite(void)
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
ok(NT_SUCCESS(status), "Commiting memory failed\n");
|
||||
|
||||
|
||||
/* Try writing it */
|
||||
StartSeh()
|
||||
{
|
||||
*allocationStart = 0xFF;
|
||||
} EndSeh(STATUS_SUCCESS);
|
||||
|
||||
|
||||
/* Try reading it */
|
||||
StartSeh()
|
||||
{
|
||||
ok(*allocationStart == 0xFF, "Memory was not written\n");
|
||||
} EndSeh(STATUS_SUCCESS);
|
||||
|
||||
|
||||
/* Set it as read only */
|
||||
status = NtProtectVirtualMemory(NtCurrentProcess(),
|
||||
(void**)&allocationStart,
|
||||
@@ -60,19 +56,19 @@ TestReadWrite(void)
|
||||
&oldProtection);
|
||||
ok(NT_SUCCESS(status), "NtProtectVirtualMemory failed.\n");
|
||||
ok(oldProtection == PAGE_READWRITE, "Expected PAGE_READWRITE, got %08lx.\n", oldProtection);
|
||||
|
||||
|
||||
/* Try writing it */
|
||||
StartSeh()
|
||||
{
|
||||
*allocationStart = 0xAA;
|
||||
} EndSeh(STATUS_ACCESS_VIOLATION);
|
||||
|
||||
|
||||
/* Try reading it */
|
||||
StartSeh()
|
||||
{
|
||||
ok(*allocationStart == 0xFF, "read-only memory were changed.\n");
|
||||
} EndSeh(STATUS_SUCCESS);
|
||||
|
||||
|
||||
/* Set it as no access */
|
||||
status = NtProtectVirtualMemory(NtCurrentProcess(),
|
||||
(void**)&allocationStart,
|
||||
@@ -81,13 +77,13 @@ TestReadWrite(void)
|
||||
&oldProtection);
|
||||
ok(NT_SUCCESS(status), "NtProtectVirtualMemory failed.\n");
|
||||
ok(oldProtection == PAGE_READONLY, "Expected PAGE_READONLY, got %08lx.\n", oldProtection);
|
||||
|
||||
|
||||
/* Try writing it */
|
||||
StartSeh()
|
||||
{
|
||||
*allocationStart = 0xAA;
|
||||
} EndSeh(STATUS_ACCESS_VIOLATION);
|
||||
|
||||
|
||||
/* Try reading it */
|
||||
StartSeh()
|
||||
{
|
||||
@@ -114,7 +110,7 @@ TestReadWrite(void)
|
||||
{
|
||||
ok(*allocationStart == 0xFF, "Memory content was not preserved.\n");
|
||||
} EndSeh(STATUS_SUCCESS);
|
||||
|
||||
|
||||
/* Free memory */
|
||||
status = NtFreeVirtualMemory(NtCurrentProcess(),
|
||||
(void**)&allocationStart,
|
||||
@@ -122,64 +118,3 @@ TestReadWrite(void)
|
||||
MEM_RELEASE);
|
||||
ok(NT_SUCCESS(status), "Failed freeing memory.\n");
|
||||
}
|
||||
|
||||
/* Regression test for CORE-13311 */
|
||||
static
|
||||
void
|
||||
TestFreeNoAccess(void)
|
||||
{
|
||||
PVOID Mem;
|
||||
SIZE_T Size;
|
||||
NTSTATUS Status;
|
||||
ULONG Iteration, PageNumber;
|
||||
PUCHAR Page;
|
||||
ULONG OldProtection;
|
||||
|
||||
for (Iteration = 0; Iteration < 50000; Iteration++)
|
||||
{
|
||||
Mem = NULL;
|
||||
Size = 16 * PAGE_SIZE;
|
||||
Status = NtAllocateVirtualMemory(NtCurrentProcess(),
|
||||
&Mem,
|
||||
0,
|
||||
&Size,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (PageNumber = 0; PageNumber < 16; PageNumber++)
|
||||
{
|
||||
Page = Mem;
|
||||
Page += PageNumber * PAGE_SIZE;
|
||||
ok(*Page == 0,
|
||||
"[%lu, %lu] Got non-zero memory. %x at %p\n",
|
||||
Iteration, PageNumber, *Page, Page);
|
||||
*Page = 123;
|
||||
}
|
||||
|
||||
Status = NtProtectVirtualMemory(NtCurrentProcess(),
|
||||
&Mem,
|
||||
&Size,
|
||||
PAGE_NOACCESS,
|
||||
&OldProtection);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
ok_hex(OldProtection, PAGE_READWRITE);
|
||||
|
||||
Size = 0;
|
||||
Status = NtFreeVirtualMemory(NtCurrentProcess(),
|
||||
&Mem,
|
||||
&Size,
|
||||
MEM_RELEASE);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(NtProtectVirtualMemory)
|
||||
{
|
||||
TestReadWrite();
|
||||
TestFreeNoAccess();
|
||||
}
|
||||
|
@@ -13,7 +13,6 @@ extern void func_NtCreateKey(void);
|
||||
extern void func_NtCreateThread(void);
|
||||
extern void func_NtDeleteKey(void);
|
||||
extern void func_NtFreeVirtualMemory(void);
|
||||
extern void func_NtLoadUnloadKey(void);
|
||||
extern void func_NtMapViewOfSection(void);
|
||||
extern void func_NtMutant(void);
|
||||
extern void func_NtOpenProcessToken(void);
|
||||
@@ -69,7 +68,6 @@ const struct test winetest_testlist[] =
|
||||
{ "NtCreateThread", func_NtCreateThread },
|
||||
{ "NtDeleteKey", func_NtDeleteKey },
|
||||
{ "NtFreeVirtualMemory", func_NtFreeVirtualMemory },
|
||||
{ "NtLoadUnloadKey", func_NtLoadUnloadKey },
|
||||
{ "NtMapViewOfSection", func_NtMapViewOfSection },
|
||||
{ "NtMutant", func_NtMutant },
|
||||
{ "NtOpenProcessToken", func_NtOpenProcessToken },
|
||||
|
@@ -89,10 +89,9 @@ static void test_SetupDiBuildClassInfoList(void)
|
||||
|
||||
if ( size > 0 )
|
||||
{
|
||||
/* That's better to use the first class found, as we know for sure that it exists */
|
||||
memcpy(&test_class_guid, &guid_list[0], sizeof( GUID ) );
|
||||
ok( SetupDiClassNameFromGuidA( &test_class_guid, test_class_name, sizeof( test_class_name ), NULL ),
|
||||
"Error reported %lx\n", GetLastError() );
|
||||
/* That's better to use the first class found, as we know for sure that it exists */
|
||||
memcpy(&test_class_guid, &guid_list[0], sizeof( GUID ) );
|
||||
SetupDiClassNameFromGuidA( &test_class_guid, test_class_name, sizeof( test_class_name ), NULL );
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, guid_list );
|
||||
}
|
||||
@@ -132,13 +131,13 @@ static void test_SetupDiClassGuidsFromNameA(void)
|
||||
"Error reported %lx\n", GetLastError() );
|
||||
ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
|
||||
ok( IsEqualIID( &guid_list[0], &test_class_guid ),
|
||||
"Expected %s, got %s for class %s\n", debugstr_guid( &test_class_guid ), debugstr_guid( &guid_list[0] ), test_class_name );
|
||||
"Expected %s, got %s\n", debugstr_guid( &test_class_guid ), debugstr_guid( &guid_list[0] ) );
|
||||
SetLastError( 0xdeadbeef );
|
||||
ok( SetupDiClassGuidsFromNameA( test_class_name, guid_list, required_size + 1, &size ),
|
||||
"Error reported %lx\n", GetLastError() );
|
||||
ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
|
||||
ok( IsEqualIID( &guid_list[0], &test_class_guid ),
|
||||
"Expected %s, got %s for class %s\n", debugstr_guid( &test_class_guid ), debugstr_guid( &guid_list[0] ), test_class_name );
|
||||
"Expected %s, got %s\n", debugstr_guid( &test_class_guid ), debugstr_guid( &guid_list[0] ) );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, guid_list );
|
||||
}
|
||||
@@ -163,7 +162,7 @@ static void test_SetupDiClassNameFromGuidA(void)
|
||||
"Fail expected\n" );
|
||||
ok_lasterr( ERROR_INSUFFICIENT_BUFFER );
|
||||
ok( required_size > 0, "Expected > 0, got %lu\n", required_size );
|
||||
ok( required_size < MAX_CLASS_NAME_LEN, "Expected < %u, got %lu for GUID %s\n", MAX_CLASS_NAME_LEN, required_size, debugstr_guid( &test_class_guid ) );
|
||||
ok( required_size < MAX_CLASS_NAME_LEN, "Expected < %u, got %lu\n", MAX_CLASS_NAME_LEN, required_size );
|
||||
|
||||
class_name = HeapAlloc( GetProcessHeap(), 0, required_size );
|
||||
if ( !class_name )
|
||||
|
@@ -13,7 +13,6 @@ add_executable(shell32_apitest
|
||||
CShellDesktop.cpp
|
||||
CShellLink.cpp
|
||||
menu.cpp
|
||||
PathResolve.cpp
|
||||
ShellExecuteEx.cpp
|
||||
shelltest.cpp
|
||||
SHParseDisplayName.cpp
|
||||
|
@@ -1,894 +0,0 @@
|
||||
/*
|
||||
* PROJECT: ReactOS api tests
|
||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||
* PURPOSE: Tests for PathResolve
|
||||
* PROGRAMMER: Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
*/
|
||||
|
||||
#include "shelltest.h"
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* NOTE: "App Paths" registry key and PATHEXT environment variable
|
||||
* have no effect for PathResolve.
|
||||
*/
|
||||
|
||||
/* PathResolve */
|
||||
typedef int (WINAPI *PATHRESOLVE)(LPWSTR, LPWSTR *, UINT);
|
||||
|
||||
static HINSTANCE s_hShell32 = NULL;
|
||||
static PATHRESOLVE s_pPathResolve = NULL;
|
||||
static WCHAR s_TestDataPath[MAX_PATH];
|
||||
static WCHAR s_LinkFilePath[MAX_PATH];
|
||||
static WCHAR s_LinkTargetPath[MAX_PATH];
|
||||
static LPWSTR s_Dirs[2];
|
||||
|
||||
/* PathResolve flags */
|
||||
#ifndef PRF_VERIFYEXISTS
|
||||
#define PRF_VERIFYEXISTS 0x01
|
||||
#define PRF_EXECUTABLE 0x02
|
||||
#define PRF_TRYPROGRAMEXTENSIONS (PRF_EXECUTABLE | PRF_VERIFYEXISTS)
|
||||
#define PRF_FIRSTDIRDEF 0x04
|
||||
#define PRF_DONTFINDLNK 0x08
|
||||
#endif
|
||||
#ifndef PRF_REQUIREABSOLUTE
|
||||
#define PRF_REQUIREABSOLUTE 0x10
|
||||
#endif
|
||||
|
||||
#define FLAGS0 0
|
||||
#define FLAGS1 PRF_VERIFYEXISTS
|
||||
#define FLAGS2 PRF_EXECUTABLE
|
||||
#define FLAGS3 PRF_TRYPROGRAMEXTENSIONS
|
||||
#define FLAGS4 (PRF_FIRSTDIRDEF | PRF_VERIFYEXISTS)
|
||||
#define FLAGS5 (PRF_FIRSTDIRDEF | PRF_EXECUTABLE)
|
||||
#define FLAGS6 (PRF_FIRSTDIRDEF | PRF_TRYPROGRAMEXTENSIONS)
|
||||
#define FLAGS7 (PRF_REQUIREABSOLUTE | PRF_VERIFYEXISTS)
|
||||
#define FLAGS8 (PRF_REQUIREABSOLUTE | PRF_EXECUTABLE)
|
||||
#define FLAGS9 (PRF_REQUIREABSOLUTE | PRF_TRYPROGRAMEXTENSIONS)
|
||||
#define FLAGS10 (PRF_REQUIREABSOLUTE | PRF_FIRSTDIRDEF | PRF_VERIFYEXISTS)
|
||||
#define FLAGS11 (PRF_REQUIREABSOLUTE | PRF_FIRSTDIRDEF | PRF_EXECUTABLE)
|
||||
#define FLAGS12 (PRF_REQUIREABSOLUTE | PRF_FIRSTDIRDEF | PRF_TRYPROGRAMEXTENSIONS)
|
||||
#define FLAGS13 0xFFFFFFFF
|
||||
|
||||
#define EF_FULLPATH 1
|
||||
#define EF_TESTDATA 2
|
||||
#define EF_WINDOWS_DIR 4
|
||||
#define EF_SYSTEM_DIR 8
|
||||
#define EF_TYPE_MASK 0xF
|
||||
|
||||
#define EF_NAME_ONLY 16
|
||||
#define EF_APP_PATH 32
|
||||
|
||||
typedef struct ENTRY
|
||||
{
|
||||
INT EntryNumber; /* # */
|
||||
INT Ret;
|
||||
DWORD Error;
|
||||
UINT EF_;
|
||||
LPCWSTR NameBefore;
|
||||
LPCWSTR NameExpected;
|
||||
UINT Flags;
|
||||
LPWSTR *Dirs;
|
||||
} ENTRY;
|
||||
|
||||
#define BEEF 0xBEEF /* Error Code 48879 */
|
||||
#define DEAD 0xDEAD /* Error Code 57005 */
|
||||
#define IGNORE_ERR 0x7F7F7F7F /* Ignore Error Code */
|
||||
#define RAISED 9999 /* exception raised */
|
||||
|
||||
static const ENTRY s_Entries[] =
|
||||
{
|
||||
/* null path */
|
||||
{ 0, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS0 },
|
||||
{ 1, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS1 },
|
||||
{ 2, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS2 },
|
||||
{ 3, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS3 },
|
||||
{ 4, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS4 },
|
||||
{ 5, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS5 },
|
||||
{ 6, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS6 },
|
||||
{ 7, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS7 },
|
||||
{ 8, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS8 },
|
||||
{ 9, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS9 },
|
||||
{ 10, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS10 },
|
||||
{ 11, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS11 },
|
||||
{ 12, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS12 },
|
||||
{ 13, RAISED, DEAD, EF_FULLPATH, NULL, NULL, FLAGS13 },
|
||||
/* empty path */
|
||||
{ 14, 1, BEEF, EF_FULLPATH, L"", NULL, FLAGS0 },
|
||||
{ 15, 1, ERROR_NO_MORE_FILES, EF_FULLPATH, L"", NULL, FLAGS1 },
|
||||
{ 16, 1, ERROR_NO_MORE_FILES, EF_FULLPATH, L"", NULL, FLAGS2 },
|
||||
{ 17, 1, ERROR_NO_MORE_FILES, EF_FULLPATH, L"", NULL, FLAGS3 },
|
||||
{ 18, 1, ERROR_NO_MORE_FILES, EF_FULLPATH, L"", NULL, FLAGS4 },
|
||||
{ 19, 1, ERROR_NO_MORE_FILES, EF_FULLPATH, L"", NULL, FLAGS5 },
|
||||
{ 20, 1, ERROR_NO_MORE_FILES, EF_FULLPATH, L"", NULL, FLAGS6 },
|
||||
{ 21, 1, ERROR_NO_MORE_FILES, EF_FULLPATH, L"", NULL, FLAGS7 },
|
||||
{ 22, 1, ERROR_NO_MORE_FILES, EF_FULLPATH, L"", NULL, FLAGS8 },
|
||||
{ 23, 1, ERROR_NO_MORE_FILES, EF_FULLPATH, L"", NULL, FLAGS9 },
|
||||
{ 24, 1, ERROR_NO_MORE_FILES, EF_FULLPATH, L"", NULL, FLAGS10 },
|
||||
{ 25, 1, ERROR_NO_MORE_FILES, EF_FULLPATH, L"", NULL, FLAGS11 },
|
||||
{ 26, 1, ERROR_NO_MORE_FILES, EF_FULLPATH, L"", NULL, FLAGS12 },
|
||||
{ 27, 1, ERROR_NO_MORE_FILES, EF_FULLPATH, L"", NULL, FLAGS13 },
|
||||
/* Fonts folder (path) */
|
||||
{ 28, 1, IGNORE_ERR, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS0 },
|
||||
{ 29, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS1 },
|
||||
{ 30, 1, BEEF, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS2 },
|
||||
{ 31, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS3 },
|
||||
{ 32, RAISED, DEAD, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS4 },
|
||||
{ 33, RAISED, DEAD, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS5 },
|
||||
{ 34, RAISED, DEAD, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS6 },
|
||||
{ 35, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS7 },
|
||||
{ 36, 1, BEEF, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS8 },
|
||||
{ 37, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS9 },
|
||||
{ 38, RAISED, DEAD, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS10 },
|
||||
{ 39, RAISED, DEAD, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS11 },
|
||||
{ 40, RAISED, DEAD, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS12 },
|
||||
{ 41, RAISED, DEAD, EF_WINDOWS_DIR, L"Fonts", L"Fonts", FLAGS13 },
|
||||
/* Fonts folder (name only) */
|
||||
{ 42, 1, ERROR_FILE_NOT_FOUND, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS0 },
|
||||
{ 43, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS1 },
|
||||
{ 44, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS2 },
|
||||
{ 45, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS3 },
|
||||
{ 46, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS4 },
|
||||
{ 47, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS5 },
|
||||
{ 48, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS6 },
|
||||
{ 49, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS7 },
|
||||
{ 50, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS8 },
|
||||
{ 51, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS9 },
|
||||
{ 52, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS10 },
|
||||
{ 53, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS11 },
|
||||
{ 54, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS12 },
|
||||
{ 55, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS13 },
|
||||
/* Fonts folder with dirs (name only) */
|
||||
{ 56, 1, ERROR_FILE_NOT_FOUND, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS0, s_Dirs },
|
||||
{ 57, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS1, s_Dirs },
|
||||
{ 58, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS2, s_Dirs },
|
||||
{ 59, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS3, s_Dirs },
|
||||
{ 60, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS4, s_Dirs },
|
||||
{ 61, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS5, s_Dirs },
|
||||
{ 62, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS6, s_Dirs },
|
||||
{ 63, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS7, s_Dirs },
|
||||
{ 64, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS8, s_Dirs },
|
||||
{ 65, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS9, s_Dirs },
|
||||
{ 66, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS10, s_Dirs },
|
||||
{ 67, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS11, s_Dirs },
|
||||
{ 68, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS12, s_Dirs },
|
||||
{ 69, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", FLAGS13, s_Dirs },
|
||||
/* system32 folder (path) */
|
||||
{ 70, 1, BEEF, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS0 },
|
||||
{ 71, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS1 },
|
||||
{ 72, 1, BEEF, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS2 },
|
||||
{ 73, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS3 },
|
||||
{ 74, RAISED, DEAD, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS4 },
|
||||
{ 75, RAISED, DEAD, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS5 },
|
||||
{ 76, RAISED, DEAD, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS6 },
|
||||
{ 77, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS7 },
|
||||
{ 78, 1, BEEF, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS8 },
|
||||
{ 79, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS9 },
|
||||
{ 80, RAISED, DEAD, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS10 },
|
||||
{ 81, RAISED, DEAD, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS11 },
|
||||
{ 82, RAISED, DEAD, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS12 },
|
||||
{ 83, RAISED, DEAD, EF_WINDOWS_DIR, L"system32", L"system32", FLAGS13 },
|
||||
/* system32 folder (name only) */
|
||||
{ 84, 1, ERROR_FILE_NOT_FOUND, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS0 },
|
||||
{ 85, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS1 },
|
||||
{ 86, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS2 },
|
||||
{ 87, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS3 },
|
||||
{ 88, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS4 },
|
||||
{ 89, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS5 },
|
||||
{ 90, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS6 },
|
||||
{ 91, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS7 },
|
||||
{ 92, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS8 },
|
||||
{ 93, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS9 },
|
||||
{ 94, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS10 },
|
||||
{ 95, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS11 },
|
||||
{ 96, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS12 },
|
||||
{ 97, 1, ERROR_NO_MORE_FILES, EF_WINDOWS_DIR | EF_NAME_ONLY, L"system32", L"system32", FLAGS13 },
|
||||
/* notepad (path) */
|
||||
{ 98, 1, BEEF, EF_SYSTEM_DIR, L"notepad", L"notepad", FLAGS0 },
|
||||
{ 99, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR, L"notepad", L"notepad.exe", FLAGS1 },
|
||||
{ 100, 1, BEEF, EF_SYSTEM_DIR, L"notepad", L"notepad", FLAGS2 },
|
||||
{ 101, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR, L"notepad", L"notepad.exe", FLAGS3 },
|
||||
{ 102, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad", L"notepad", FLAGS4 },
|
||||
{ 103, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad", L"notepad", FLAGS5 },
|
||||
{ 104, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad", L"notepad", FLAGS6 },
|
||||
{ 105, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR, L"notepad", L"notepad.exe", FLAGS7 },
|
||||
{ 106, 1, BEEF, EF_SYSTEM_DIR, L"notepad", L"notepad", FLAGS8 },
|
||||
{ 107, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR, L"notepad", L"notepad.exe", FLAGS9 },
|
||||
{ 108, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad", L"notepad", FLAGS10 },
|
||||
{ 109, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad", L"notepad", FLAGS11 },
|
||||
{ 110, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad", L"notepad", FLAGS12 },
|
||||
{ 111, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad", L"notepad", FLAGS13 },
|
||||
/* notepad (name only) */
|
||||
{ 112, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS0 },
|
||||
{ 113, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS1 },
|
||||
{ 114, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS2 },
|
||||
{ 115, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS3 },
|
||||
{ 116, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS4 },
|
||||
{ 117, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS5 },
|
||||
{ 118, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS6 },
|
||||
{ 119, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS7 },
|
||||
{ 120, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS8 },
|
||||
{ 121, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS9 },
|
||||
{ 122, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS10 },
|
||||
{ 123, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS11 },
|
||||
{ 124, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS12 },
|
||||
{ 125, 1, ERROR_NO_MORE_FILES, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad", NULL, FLAGS13 },
|
||||
/* notepad.exe (path) */
|
||||
{ 126, 1, BEEF, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS0 },
|
||||
{ 127, 1, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS1 },
|
||||
{ 128, 1, BEEF, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS2 },
|
||||
{ 129, 1, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS3 },
|
||||
{ 130, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS4 },
|
||||
{ 131, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS5 },
|
||||
{ 132, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS6 },
|
||||
{ 133, 1, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS7 },
|
||||
{ 134, 1, BEEF, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS8 },
|
||||
{ 135, 1, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS9 },
|
||||
{ 136, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS10 },
|
||||
{ 137, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS11 },
|
||||
{ 138, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS12 },
|
||||
{ 139, RAISED, DEAD, EF_SYSTEM_DIR, L"notepad.exe", L"notepad.exe", FLAGS13 },
|
||||
/* notepad.exe (name only) */
|
||||
{ 140, 1, BEEF, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS0 },
|
||||
{ 141, 1, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS1 },
|
||||
{ 142, 1, BEEF, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS2 },
|
||||
{ 143, 1, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS3 },
|
||||
{ 144, 1, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS4 },
|
||||
{ 145, 1, BEEF, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS5 },
|
||||
{ 146, 1, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS6 },
|
||||
{ 147, 1, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS7 },
|
||||
{ 148, 1, BEEF, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS8 },
|
||||
{ 149, 1, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS9 },
|
||||
{ 150, 1, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS10 },
|
||||
{ 151, 1, BEEF, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS11 },
|
||||
{ 152, 1, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS12 },
|
||||
{ 153, 1, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", FLAGS13 },
|
||||
/* notepad.com (name only) */
|
||||
{ 154, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS0 },
|
||||
{ 155, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS1 },
|
||||
{ 156, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS2 },
|
||||
{ 157, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS3 },
|
||||
{ 158, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS4 },
|
||||
{ 159, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS5 },
|
||||
{ 160, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS6 },
|
||||
{ 161, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS7 },
|
||||
{ 162, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS8 },
|
||||
{ 163, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS9 },
|
||||
{ 164, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS10 },
|
||||
{ 165, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS11 },
|
||||
{ 166, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS12 },
|
||||
{ 167, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY, L"notepad.com", NULL, FLAGS13 },
|
||||
/* GhostProgram.exe -> notepad.exe (name only, app path) */
|
||||
{ 168, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS0 },
|
||||
{ 169, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS1 },
|
||||
{ 170, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS2 },
|
||||
{ 171, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS3 },
|
||||
{ 172, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS4 },
|
||||
{ 173, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS5 },
|
||||
{ 174, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS6 },
|
||||
{ 175, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS7 },
|
||||
{ 176, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS8 },
|
||||
{ 177, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS9 },
|
||||
{ 178, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS10 },
|
||||
{ 179, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS11 },
|
||||
{ 180, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS12 },
|
||||
{ 181, 0, ERROR_FILE_NOT_FOUND, EF_SYSTEM_DIR | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"notepad.exe", FLAGS13 },
|
||||
/* invalid name */
|
||||
{ 182, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS0 },
|
||||
{ 183, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS1 },
|
||||
{ 184, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS2 },
|
||||
{ 185, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS3 },
|
||||
{ 186, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS4 },
|
||||
{ 187, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS5 },
|
||||
{ 188, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS6 },
|
||||
{ 189, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS7 },
|
||||
{ 190, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS8 },
|
||||
{ 191, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS9 },
|
||||
{ 192, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS10 },
|
||||
{ 193, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS11 },
|
||||
{ 194, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS12 },
|
||||
{ 195, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS13 },
|
||||
/* testdata/2PRONG (path) */
|
||||
{ 196, 1, BEEF, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS0 },
|
||||
{ 197, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS1 },
|
||||
{ 198, 1, BEEF, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS2 },
|
||||
{ 199, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS3 },
|
||||
{ 200, RAISED, DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS4 },
|
||||
{ 201, RAISED, DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS5 },
|
||||
{ 202, RAISED, DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS6 },
|
||||
{ 203, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS7 },
|
||||
{ 204, 1, BEEF, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS8 },
|
||||
{ 205, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS9 },
|
||||
{ 206, RAISED, DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS10 },
|
||||
{ 207, RAISED, DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS11 },
|
||||
{ 208, RAISED, DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS12 },
|
||||
{ 209, RAISED, DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS13 },
|
||||
/* testdata/2PRONG (name only) */
|
||||
{ 210, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS0 },
|
||||
{ 211, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS1 },
|
||||
{ 212, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS2 },
|
||||
{ 213, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS3 },
|
||||
{ 214, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS4 },
|
||||
{ 215, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS5 },
|
||||
{ 216, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS6 },
|
||||
{ 217, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS7 },
|
||||
{ 218, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS8 },
|
||||
{ 219, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS9 },
|
||||
{ 220, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS10 },
|
||||
{ 221, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS11 },
|
||||
{ 222, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS12 },
|
||||
{ 223, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS13 },
|
||||
/* testdata/2PRONG with dirs (name only) */
|
||||
{ 224, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS0, s_Dirs },
|
||||
{ 225, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS1, s_Dirs },
|
||||
{ 226, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS2, s_Dirs },
|
||||
{ 227, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS3, s_Dirs },
|
||||
{ 228, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS4, s_Dirs },
|
||||
{ 229, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS5, s_Dirs },
|
||||
{ 230, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS6, s_Dirs },
|
||||
{ 231, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS7, s_Dirs },
|
||||
{ 232, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS8, s_Dirs },
|
||||
{ 233, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS9, s_Dirs },
|
||||
{ 234, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS10, s_Dirs },
|
||||
{ 235, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS11, s_Dirs },
|
||||
{ 236, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS12, s_Dirs },
|
||||
{ 237, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS13, s_Dirs },
|
||||
/* testdata/2PRONG (name only, app path) */
|
||||
{ 238, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS0 },
|
||||
{ 239, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS1 },
|
||||
{ 240, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS2 },
|
||||
{ 241, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS3 },
|
||||
{ 242, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS4 },
|
||||
{ 243, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS5 },
|
||||
{ 244, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS6 },
|
||||
{ 245, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS7 },
|
||||
{ 246, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS8 },
|
||||
{ 247, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS9 },
|
||||
{ 248, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS10 },
|
||||
{ 249, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS11 },
|
||||
{ 250, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS12 },
|
||||
{ 251, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS13 },
|
||||
/* testdata/2PRONG.txt (path) */
|
||||
{ 252, 1, BEEF, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS0 },
|
||||
{ 253, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS1 },
|
||||
{ 254, 1, BEEF, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS2 },
|
||||
{ 255, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS3 },
|
||||
{ 256, RAISED, DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS4 },
|
||||
{ 257, RAISED, DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS5 },
|
||||
{ 258, RAISED, DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS6 },
|
||||
{ 259, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS7 },
|
||||
{ 260, 1, BEEF, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS8 },
|
||||
{ 261, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS9 },
|
||||
{ 262, RAISED, DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS10 },
|
||||
{ 263, RAISED, DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS11 },
|
||||
{ 264, RAISED, DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS12 },
|
||||
{ 265, RAISED, DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS13 },
|
||||
/* 2PRONG.txt (name only) */
|
||||
{ 266, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS0 },
|
||||
{ 267, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS1 },
|
||||
{ 268, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS2 },
|
||||
{ 269, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS3 },
|
||||
{ 270, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS4 },
|
||||
{ 271, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS5 },
|
||||
{ 272, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS6 },
|
||||
{ 273, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS7 },
|
||||
{ 274, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS8 },
|
||||
{ 275, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS9 },
|
||||
{ 276, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS10 },
|
||||
{ 277, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS11 },
|
||||
{ 278, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS12 },
|
||||
{ 279, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS13 },
|
||||
/* 2PRONG.txt with dirs (name only) */
|
||||
{ 280, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS0, s_Dirs },
|
||||
{ 281, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS1, s_Dirs },
|
||||
{ 282, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS2, s_Dirs },
|
||||
{ 283, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS3, s_Dirs },
|
||||
{ 284, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS4, s_Dirs },
|
||||
{ 285, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS5, s_Dirs },
|
||||
{ 286, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS6, s_Dirs },
|
||||
{ 287, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS7, s_Dirs },
|
||||
{ 288, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS8, s_Dirs },
|
||||
{ 289, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS9, s_Dirs },
|
||||
{ 290, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS10, s_Dirs },
|
||||
{ 291, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS11, s_Dirs },
|
||||
{ 292, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS12, s_Dirs },
|
||||
{ 293, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS13, s_Dirs },
|
||||
/* testdata/CmdLineUtils (path) */
|
||||
{ 294, 1, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS0 },
|
||||
{ 295, 1, ERROR_NO_MORE_FILES, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils.lnk", FLAGS1 },
|
||||
{ 296, 1, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS2 },
|
||||
{ 297, 1, ERROR_NO_MORE_FILES, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils.lnk", FLAGS3 },
|
||||
{ 298, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS4 },
|
||||
{ 299, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS5 },
|
||||
{ 300, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS6 },
|
||||
{ 301, 1, ERROR_NO_MORE_FILES, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils.lnk", FLAGS7 },
|
||||
{ 302, 1, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS8 },
|
||||
{ 303, 1, ERROR_NO_MORE_FILES, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils.lnk", FLAGS9 },
|
||||
{ 304, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS10 },
|
||||
{ 305, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS11 },
|
||||
{ 306, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS12 },
|
||||
{ 307, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS13 },
|
||||
/* testdata/CmdLineUtils with PRF_DONTFINDLNK (path) */
|
||||
{ 308, 1, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS0 | PRF_DONTFINDLNK },
|
||||
{ 309, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS1 | PRF_DONTFINDLNK },
|
||||
{ 310, 1, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS2 | PRF_DONTFINDLNK },
|
||||
{ 311, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS3 | PRF_DONTFINDLNK },
|
||||
{ 312, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS4 | PRF_DONTFINDLNK },
|
||||
{ 313, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS5 | PRF_DONTFINDLNK },
|
||||
{ 314, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS6 | PRF_DONTFINDLNK },
|
||||
{ 315, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS7 | PRF_DONTFINDLNK },
|
||||
{ 316, 1, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS8 | PRF_DONTFINDLNK },
|
||||
{ 317, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS9 | PRF_DONTFINDLNK },
|
||||
{ 318, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS10 | PRF_DONTFINDLNK },
|
||||
{ 319, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS11 | PRF_DONTFINDLNK },
|
||||
{ 320, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS12 | PRF_DONTFINDLNK },
|
||||
{ 321, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS13 | PRF_DONTFINDLNK },
|
||||
/* testdata/CmdLineUtils (name only) */
|
||||
{ 222, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS0 },
|
||||
{ 323, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS1 },
|
||||
{ 324, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS2 },
|
||||
{ 325, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS3 },
|
||||
{ 326, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS4 },
|
||||
{ 327, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS5 },
|
||||
{ 328, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS6 },
|
||||
{ 329, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS7 },
|
||||
{ 330, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS8 },
|
||||
{ 331, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS9 },
|
||||
{ 332, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS10 },
|
||||
{ 333, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS11 },
|
||||
{ 334, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS12 },
|
||||
{ 335, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS13 },
|
||||
/* testdata/CmdLineUtils.exe (path) */
|
||||
{ 336, 1, BEEF, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS0 },
|
||||
{ 337, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS1 },
|
||||
{ 338, 1, BEEF, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS2 },
|
||||
{ 339, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS3 },
|
||||
{ 340, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS4 },
|
||||
{ 341, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS5 },
|
||||
{ 342, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS6 },
|
||||
{ 343, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS7 },
|
||||
{ 344, 1, BEEF, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS8 },
|
||||
{ 345, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS9 },
|
||||
{ 346, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS10 },
|
||||
{ 347, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS11 },
|
||||
{ 348, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS12 },
|
||||
{ 349, RAISED, DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS13 },
|
||||
/* testdata/CmdLineUtils.exe (name only) */
|
||||
{ 350, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS0 },
|
||||
{ 351, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS1 },
|
||||
{ 352, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS2 },
|
||||
{ 353, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS3 },
|
||||
{ 354, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS4 },
|
||||
{ 355, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS5 },
|
||||
{ 356, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS6 },
|
||||
{ 357, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS7 },
|
||||
{ 358, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS8 },
|
||||
{ 359, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS9 },
|
||||
{ 360, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS10 },
|
||||
{ 361, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS11 },
|
||||
{ 362, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS12 },
|
||||
{ 363, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS13 },
|
||||
/* testdata/CmdLineUtils.exe with dirs (name only) */
|
||||
{ 364, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS0, s_Dirs },
|
||||
{ 365, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS1, s_Dirs },
|
||||
{ 366, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS2, s_Dirs },
|
||||
{ 367, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS3, s_Dirs },
|
||||
{ 368, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS4, s_Dirs },
|
||||
{ 369, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS5, s_Dirs },
|
||||
{ 370, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS6, s_Dirs },
|
||||
{ 371, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS7, s_Dirs },
|
||||
{ 372, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS8, s_Dirs },
|
||||
{ 373, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS9, s_Dirs },
|
||||
{ 374, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS10, s_Dirs },
|
||||
{ 375, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS11, s_Dirs },
|
||||
{ 376, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS12, s_Dirs },
|
||||
{ 377, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS13, s_Dirs },
|
||||
/* testdata/CmdLineUtils.exe with dirs (name only) */
|
||||
{ 378, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS0, s_Dirs },
|
||||
{ 379, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS1, s_Dirs },
|
||||
{ 380, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS2, s_Dirs },
|
||||
{ 381, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS3, s_Dirs },
|
||||
{ 382, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS4, s_Dirs },
|
||||
{ 383, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS5, s_Dirs },
|
||||
{ 384, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS6, s_Dirs },
|
||||
{ 385, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS7, s_Dirs },
|
||||
{ 386, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS8, s_Dirs },
|
||||
{ 387, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS9, s_Dirs },
|
||||
{ 388, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS10, s_Dirs },
|
||||
{ 389, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS11, s_Dirs },
|
||||
{ 390, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS12, s_Dirs },
|
||||
{ 391, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS13, s_Dirs },
|
||||
/* GhostProgram.exe -> testdata/CmdLineUtils.exe (name only, app path) */
|
||||
{ 392, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS0 },
|
||||
{ 393, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS1 },
|
||||
{ 394, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS2 },
|
||||
{ 395, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS3 },
|
||||
{ 396, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS4 },
|
||||
{ 397, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS5 },
|
||||
{ 398, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS6 },
|
||||
{ 399, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS7 },
|
||||
{ 400, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS8 },
|
||||
{ 401, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS9 },
|
||||
{ 402, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS10 },
|
||||
{ 403, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS11 },
|
||||
{ 404, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS12 },
|
||||
{ 405, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS13 },
|
||||
/* C:\ */
|
||||
{ 406, 1, BEEF, EF_FULLPATH, L"C:\\", L"C:\\", FLAGS0 },
|
||||
{ 407, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"C:\\", L"C:\\", FLAGS1 },
|
||||
{ 408, 1, BEEF, EF_FULLPATH, L"C:\\", NULL, FLAGS2 },
|
||||
{ 409, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"C:\\", L"C:\\", FLAGS3 },
|
||||
{ 410, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"C:\\", L"C:\\", FLAGS4 },
|
||||
{ 411, 1, BEEF, EF_FULLPATH, L"C:\\", NULL, FLAGS5 },
|
||||
{ 412, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"C:\\", L"C:\\", FLAGS6 },
|
||||
{ 413, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"C:\\", L"C:\\", FLAGS7 },
|
||||
{ 414, 1, BEEF, EF_FULLPATH, L"C:\\", L"C:\\", FLAGS8 },
|
||||
{ 415, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"C:\\", L"C:\\", FLAGS9 },
|
||||
{ 416, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"C:\\", L"C:\\", FLAGS10 },
|
||||
{ 417, 1, BEEF, EF_FULLPATH, L"C:\\", L"C:\\", FLAGS11 },
|
||||
{ 418, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"C:\\", L"C:\\", FLAGS12 },
|
||||
{ 419, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"C:\\", L"C:\\", FLAGS13 },
|
||||
/* CmdLineUtils.lnk */
|
||||
{ 420, 1, BEEF, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS0 },
|
||||
{ 421, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS1 },
|
||||
{ 422, 1, BEEF, EF_FULLPATH, s_LinkFilePath, NULL, FLAGS2 },
|
||||
{ 423, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS3 },
|
||||
{ 424, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS4 },
|
||||
{ 425, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS5 },
|
||||
{ 426, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS6 },
|
||||
{ 427, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS7 },
|
||||
{ 428, 1, BEEF, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS8 },
|
||||
{ 429, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS9 },
|
||||
{ 430, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS10 },
|
||||
{ 431, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS11 },
|
||||
{ 432, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS12 },
|
||||
{ 433, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS13 },
|
||||
/* CmdLineUtils.lnk (with PRF_DONTFINDLNK) */
|
||||
{ 434, 1, BEEF, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS0 | PRF_DONTFINDLNK },
|
||||
{ 435, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS1 | PRF_DONTFINDLNK },
|
||||
{ 436, 1, BEEF, EF_FULLPATH, s_LinkFilePath, NULL, FLAGS2 | PRF_DONTFINDLNK },
|
||||
{ 437, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS3 | PRF_DONTFINDLNK },
|
||||
{ 438, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS4 | PRF_DONTFINDLNK },
|
||||
{ 439, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS5 | PRF_DONTFINDLNK },
|
||||
{ 440, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS6 | PRF_DONTFINDLNK },
|
||||
{ 441, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS7 | PRF_DONTFINDLNK },
|
||||
{ 442, 1, BEEF, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS8 | PRF_DONTFINDLNK },
|
||||
{ 443, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS9 | PRF_DONTFINDLNK },
|
||||
{ 444, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS10 | PRF_DONTFINDLNK },
|
||||
{ 445, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS11 | PRF_DONTFINDLNK },
|
||||
{ 446, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS12 | PRF_DONTFINDLNK },
|
||||
{ 447, RAISED, DEAD, EF_FULLPATH, s_LinkFilePath, s_LinkFilePath, FLAGS13 | PRF_DONTFINDLNK },
|
||||
};
|
||||
|
||||
static BOOL
|
||||
CreateShortcut(LPCWSTR pszLnkFileName,
|
||||
LPCWSTR pszTargetPathName)
|
||||
{
|
||||
IPersistFile *ppf;
|
||||
IShellLinkW* psl;
|
||||
HRESULT hres;
|
||||
|
||||
hres = CoInitialize(NULL);
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
hres = CoCreateInstance(CLSID_ShellLink, NULL,
|
||||
CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl);
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
psl->SetPath(pszTargetPathName);
|
||||
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
hres = ppf->Save(pszLnkFileName, TRUE);
|
||||
ppf->Release();
|
||||
}
|
||||
psl->Release();
|
||||
}
|
||||
CoUninitialize();
|
||||
}
|
||||
SetLastError(hres);
|
||||
|
||||
return SUCCEEDED(hres);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
CreateRegAppPath(INT EntryNumber, const WCHAR* Name, const WCHAR* Value)
|
||||
{
|
||||
HKEY RegistryKey;
|
||||
LONG Result;
|
||||
WCHAR Buffer[1024];
|
||||
DWORD Disposition;
|
||||
|
||||
wcscpy(Buffer, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
|
||||
wcscat(Buffer, Name);
|
||||
Result = RegCreateKeyExW(HKEY_LOCAL_MACHINE, Buffer, 0, NULL,
|
||||
0, KEY_WRITE, NULL, &RegistryKey, &Disposition);
|
||||
if (Result != ERROR_SUCCESS)
|
||||
{
|
||||
trace("#%d: Could not create test key. Status: %lu\n", EntryNumber, Result);
|
||||
return FALSE;
|
||||
}
|
||||
Result = RegSetValueW(RegistryKey, NULL, REG_SZ, Value, 0);
|
||||
if (Result != ERROR_SUCCESS)
|
||||
{
|
||||
trace("#%d: Could not set value of the test key. Status: %lu\n", EntryNumber, Result);
|
||||
RegCloseKey(RegistryKey);
|
||||
return FALSE;
|
||||
}
|
||||
RegCloseKey(RegistryKey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
DeleteRegAppPath(INT EntryNumber, const WCHAR* Name)
|
||||
{
|
||||
LONG Result;
|
||||
WCHAR Buffer[1024];
|
||||
wcscpy(Buffer, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
|
||||
wcscat(Buffer, Name);
|
||||
Result = RegDeleteKeyW(HKEY_LOCAL_MACHINE, Buffer);
|
||||
if (Result != ERROR_SUCCESS)
|
||||
{
|
||||
trace("#%d: Could not remove the test key. Status: %lu\n", EntryNumber, Result);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void DoEntry(INT EntryNumber, const ENTRY *pEntry)
|
||||
{
|
||||
WCHAR Path[MAX_PATH], PathExpected[MAX_PATH];
|
||||
INT Ret;
|
||||
DWORD Error;
|
||||
|
||||
if (pEntry->NameBefore == NULL)
|
||||
{
|
||||
assert(pEntry->NameExpected == NULL);
|
||||
}
|
||||
|
||||
switch (pEntry->EF_ & EF_TYPE_MASK)
|
||||
{
|
||||
case EF_FULLPATH:
|
||||
if (pEntry->NameBefore)
|
||||
{
|
||||
lstrcpyW(Path, pEntry->NameBefore);
|
||||
}
|
||||
if (pEntry->NameExpected)
|
||||
{
|
||||
lstrcpyW(PathExpected, pEntry->NameExpected);
|
||||
}
|
||||
break;
|
||||
|
||||
case EF_TESTDATA:
|
||||
if (pEntry->EF_ & EF_NAME_ONLY)
|
||||
{
|
||||
lstrcpyW(Path, pEntry->NameBefore);
|
||||
}
|
||||
else
|
||||
{
|
||||
lstrcpyW(Path, s_TestDataPath);
|
||||
lstrcatW(Path, L"\\");
|
||||
lstrcatW(Path, pEntry->NameBefore);
|
||||
}
|
||||
|
||||
if (pEntry->NameExpected)
|
||||
{
|
||||
lstrcpyW(PathExpected, s_TestDataPath);
|
||||
lstrcatW(PathExpected, L"\\");
|
||||
lstrcatW(PathExpected, pEntry->NameExpected);
|
||||
}
|
||||
break;
|
||||
|
||||
case EF_WINDOWS_DIR:
|
||||
if (pEntry->EF_ & EF_NAME_ONLY)
|
||||
{
|
||||
lstrcpyW(Path, pEntry->NameBefore);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetWindowsDirectoryW(Path, _countof(Path));
|
||||
lstrcatW(Path, L"\\");
|
||||
lstrcatW(Path, pEntry->NameBefore);
|
||||
}
|
||||
|
||||
if (pEntry->NameExpected)
|
||||
{
|
||||
GetWindowsDirectoryW(PathExpected, _countof(PathExpected));
|
||||
lstrcatW(PathExpected, L"\\");
|
||||
lstrcatW(PathExpected, pEntry->NameExpected);
|
||||
}
|
||||
break;
|
||||
|
||||
case EF_SYSTEM_DIR:
|
||||
if (pEntry->EF_ & EF_NAME_ONLY)
|
||||
{
|
||||
lstrcpyW(Path, pEntry->NameBefore);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetSystemDirectoryW(Path, _countof(Path));
|
||||
lstrcatW(Path, L"\\");
|
||||
lstrcatW(Path, pEntry->NameBefore);
|
||||
}
|
||||
|
||||
if (pEntry->NameExpected)
|
||||
{
|
||||
GetSystemDirectoryW(PathExpected, _countof(PathExpected));
|
||||
lstrcatW(PathExpected, L"\\");
|
||||
lstrcatW(PathExpected, pEntry->NameExpected);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (pEntry->EF_ & EF_APP_PATH)
|
||||
{
|
||||
if (!CreateRegAppPath(EntryNumber, pEntry->NameBefore, PathExpected))
|
||||
{
|
||||
skip("#%d: CreateRegAppPath failure\n", EntryNumber);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
SetLastError(BEEF);
|
||||
if (pEntry->NameBefore)
|
||||
{
|
||||
Ret = (*s_pPathResolve)(Path, pEntry->Dirs, pEntry->Flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ret = (*s_pPathResolve)(NULL, pEntry->Dirs, pEntry->Flags);
|
||||
}
|
||||
Error = GetLastError();
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Ret = RAISED;
|
||||
Error = DEAD;
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
if (pEntry->EF_ & EF_APP_PATH)
|
||||
{
|
||||
ok(DeleteRegAppPath(EntryNumber, pEntry->NameBefore),
|
||||
"#%d: DeleteRegAppPath failed\n", EntryNumber);
|
||||
}
|
||||
|
||||
ok(Ret == pEntry->Ret, "#%d: Ret expected %d, was %d.\n",
|
||||
EntryNumber, pEntry->Ret, Ret);
|
||||
if (pEntry->Error != IGNORE_ERR)
|
||||
{
|
||||
ok(Error == pEntry->Error, "#%d: last error expected %ld, was %ld.\n",
|
||||
EntryNumber, pEntry->Error, Error);
|
||||
}
|
||||
|
||||
if (pEntry->NameExpected && !(pEntry->EF_ & EF_APP_PATH))
|
||||
{
|
||||
ok(lstrcmpW(Path, PathExpected) == 0, "#%d: Path expected %s, was %s.\n",
|
||||
EntryNumber, wine_dbgstr_w(PathExpected), wine_dbgstr_w(Path));
|
||||
}
|
||||
}
|
||||
|
||||
static void TestMain_PathResolve(void)
|
||||
{
|
||||
UINT i;
|
||||
WCHAR Saved[128], *pPathExtSaved;
|
||||
|
||||
/* save PATHEXT */
|
||||
if (GetEnvironmentVariableW(L"PATHEXT", Saved, _countof(Saved)))
|
||||
{
|
||||
pPathExtSaved = Saved;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPathExtSaved = NULL;
|
||||
}
|
||||
|
||||
/* normal */
|
||||
for (i = 0; i < _countof(s_Entries); ++i)
|
||||
{
|
||||
DoEntry(s_Entries[i].EntryNumber, &s_Entries[i]);
|
||||
}
|
||||
|
||||
/* +#1000: reset PATHEXT */
|
||||
if (SetEnvironmentVariableW(L"PATHEXT", NULL))
|
||||
{
|
||||
for (i = 0; i < _countof(s_Entries); ++i)
|
||||
{
|
||||
DoEntry(s_Entries[i].EntryNumber + 1000, &s_Entries[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
skip("SetEnvironmentVariableW failed\n");
|
||||
}
|
||||
|
||||
/* +#2000: set PATHEXT to ".COM;.EXE;.BAT" */
|
||||
if (SetEnvironmentVariableW(L"PATHEXT", L".COM;.EXE;.BAT"))
|
||||
{
|
||||
for (i = 0; i < _countof(s_Entries); ++i)
|
||||
{
|
||||
DoEntry(s_Entries[i].EntryNumber + 2000, &s_Entries[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
skip("SetEnvironmentVariableW failed\n");
|
||||
}
|
||||
|
||||
/* +#3000: set PATHEXT to ".TXT" */
|
||||
if (SetEnvironmentVariableW(L"PATHEXT", L".TXT"))
|
||||
{
|
||||
for (i = 0; i < _countof(s_Entries); ++i)
|
||||
{
|
||||
DoEntry(s_Entries[i].EntryNumber + 3000, &s_Entries[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
skip("SetEnvironmentVariableW failed\n");
|
||||
}
|
||||
|
||||
/* restore PATHEXT */
|
||||
SetEnvironmentVariableW(L"PATHEXT", pPathExtSaved);
|
||||
}
|
||||
|
||||
START_TEST(PathResolve)
|
||||
{
|
||||
LPWSTR pch;
|
||||
|
||||
GetModuleFileNameW(NULL, s_TestDataPath, _countof(s_TestDataPath));
|
||||
pch = wcsrchr(s_TestDataPath, L'\\');
|
||||
if (pch == NULL)
|
||||
pch = wcsrchr(s_TestDataPath, L'/');
|
||||
if (pch == NULL)
|
||||
{
|
||||
skip("GetModuleFileName and/or wcsrchr are insane.\n");
|
||||
return;
|
||||
}
|
||||
lstrcpyW(pch, L"\\testdata");
|
||||
if (GetFileAttributesW(s_TestDataPath) == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
skip("testdata is not found.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
s_Dirs[0] = s_TestDataPath;
|
||||
s_Dirs[1] = NULL;
|
||||
|
||||
lstrcpyW(s_LinkFilePath, s_TestDataPath);
|
||||
lstrcatW(s_LinkFilePath, L"\\");
|
||||
lstrcatW(s_LinkFilePath, L"CmdLineUtils.lnk");
|
||||
|
||||
lstrcpyW(s_LinkTargetPath, s_TestDataPath);
|
||||
lstrcatW(s_LinkTargetPath, L"\\");
|
||||
lstrcatW(s_LinkTargetPath, L"2PRONG.txt");
|
||||
|
||||
ok(CreateShortcut(s_LinkFilePath, s_LinkTargetPath),
|
||||
"CreateShortcut(%s, %s) failed.\n",
|
||||
wine_dbgstr_w(s_LinkFilePath), wine_dbgstr_w(s_LinkTargetPath));
|
||||
|
||||
s_hShell32 = LoadLibraryA("shell32");
|
||||
if (s_hShell32 == NULL)
|
||||
{
|
||||
skip("Unable to load shell32.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
s_pPathResolve = (PATHRESOLVE)GetProcAddress(s_hShell32, "PathResolve");
|
||||
if (s_pPathResolve == NULL)
|
||||
{
|
||||
skip("Unable to get PathResolve address.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
TestMain_PathResolve();
|
||||
|
||||
ok(DeleteFileW(s_LinkFilePath), "DeleteFileW(%s) failed\n",
|
||||
wine_dbgstr_w(s_LinkFilePath));
|
||||
|
||||
FreeLibrary(s_hShell32);
|
||||
s_hShell32 = NULL;
|
||||
s_pPathResolve = NULL;
|
||||
}
|
@@ -10,7 +10,6 @@ extern void func_CMyComputer(void);
|
||||
extern void func_CShellDesktop(void);
|
||||
extern void func_CShellLink(void);
|
||||
extern void func_menu(void);
|
||||
extern void func_PathResolve(void);
|
||||
extern void func_ShellExecuteEx(void);
|
||||
extern void func_SHParseDisplayName(void);
|
||||
|
||||
@@ -23,7 +22,6 @@ const struct test winetest_testlist[] =
|
||||
{ "CShellDesktop", func_CShellDesktop },
|
||||
{ "CShellLink", func_CShellLink },
|
||||
{ "menu", func_menu },
|
||||
{ "PathResolve", func_PathResolve },
|
||||
{ "ShellExecuteEx", func_ShellExecuteEx },
|
||||
{ "SHParseDisplayName", func_SHParseDisplayName },
|
||||
{ 0, 0 }
|
||||
|
@@ -1,6 +1,5 @@
|
||||
|
||||
list(APPEND SOURCE
|
||||
PathFindOnPath.c
|
||||
PathIsUNC.c
|
||||
PathIsUNCServer.c
|
||||
PathIsUNCServerShare.c
|
||||
@@ -10,6 +9,5 @@ list(APPEND SOURCE
|
||||
|
||||
add_executable(shlwapi_apitest ${SOURCE})
|
||||
set_module_type(shlwapi_apitest win32cui)
|
||||
target_link_libraries(shlwapi_apitest ${PSEH_LIB})
|
||||
add_importlibs(shlwapi_apitest shlwapi msvcrt kernel32)
|
||||
add_rostests_file(TARGET shlwapi_apitest)
|
||||
|
@@ -1,348 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Katayama Hirofumi MZ
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
#include <shlwapi.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define EF_FULLPATH 1
|
||||
#define EF_TESTDATA 2
|
||||
#define EF_WIN_DIR 4
|
||||
#define EF_SYS_DIR 8
|
||||
#define EF_TYPE_MASK 0xF
|
||||
|
||||
#define EF_NAME_ONLY 16
|
||||
|
||||
typedef struct ENTRY
|
||||
{
|
||||
INT EntryNumber; /* # */
|
||||
INT Ret;
|
||||
DWORD Error;
|
||||
UINT EF_;
|
||||
LPCWSTR NameBefore;
|
||||
LPCWSTR NameExpected;
|
||||
LPCWSTR PathExpected;
|
||||
LPWSTR * Dirs;
|
||||
} ENTRY;
|
||||
|
||||
#define BEEF 0xBEEF /* Error Code 48879 */
|
||||
#define DEAD 0xDEAD /* Error Code 57005 */
|
||||
#define IGNORE_ERR 0x7F7F7F7F /* Ignore Error Code */
|
||||
#define RAISED 9999 /* exception raised */
|
||||
|
||||
static WCHAR s_TestDataPath[MAX_PATH];
|
||||
static LPWSTR s_Dirs[2];
|
||||
static WCHAR s_WinDir[MAX_PATH];
|
||||
static WCHAR s_SysDir[MAX_PATH];
|
||||
static WCHAR s_FontsDir[MAX_PATH];
|
||||
static WCHAR s_NotepadPath[MAX_PATH];
|
||||
|
||||
static const ENTRY s_Entries[] =
|
||||
{
|
||||
/* NULL or empty path */
|
||||
{ 0, 0, BEEF, EF_FULLPATH, NULL, NULL },
|
||||
{ 1, 1, BEEF, EF_FULLPATH, L"", s_SysDir },
|
||||
/* path without dirs in Windows */
|
||||
{ 2, 0, BEEF, EF_WIN_DIR, L"", L"" },
|
||||
{ 3, 0, BEEF, EF_WIN_DIR, L"Fonts", L"Fonts" },
|
||||
{ 4, 0, BEEF, EF_WIN_DIR, L"notepad", L"notepad" },
|
||||
{ 5, 0, BEEF, EF_WIN_DIR, L"notepad.exe", L"notepad.exe" },
|
||||
{ 6, 0, BEEF, EF_WIN_DIR, L"system32", L"system32" },
|
||||
{ 7, 0, BEEF, EF_WIN_DIR, L"invalid name", L"invalid name" },
|
||||
/* path with dirs in Windows */
|
||||
{ 8, 0, BEEF, EF_WIN_DIR, L"", L"", NULL, s_Dirs },
|
||||
{ 9, 0, BEEF, EF_WIN_DIR, L"Fonts", L"Fonts", NULL, s_Dirs },
|
||||
{ 10, 0, BEEF, EF_WIN_DIR, L"notepad", L"notepad", NULL, s_Dirs },
|
||||
{ 11, 0, BEEF, EF_WIN_DIR, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
|
||||
{ 12, 0, BEEF, EF_WIN_DIR, L"system32", L"system32", NULL, s_Dirs },
|
||||
{ 13, 0, BEEF, EF_WIN_DIR, L"invalid name", L"invalid name", NULL, s_Dirs },
|
||||
/* name only without dirs in Windows */
|
||||
{ 14, 1, BEEF, EF_WIN_DIR | EF_NAME_ONLY, L"", L"system32" },
|
||||
{ 15, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts" },
|
||||
{ 16, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"notepad" },
|
||||
{ 17, 1, BEEF, EF_WIN_DIR | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath },
|
||||
{ 18, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"system32" },
|
||||
{ 19, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name" },
|
||||
/* name only with dirs in Windows */
|
||||
{ 20, 1, BEEF, EF_WIN_DIR | EF_NAME_ONLY, L"", NULL, s_TestDataPath, s_Dirs },
|
||||
{ 21, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", NULL, s_Dirs },
|
||||
{ 22, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"notepad", NULL, L"notepad", s_Dirs },
|
||||
{ 23, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath, s_Dirs },
|
||||
{ 24, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"system32", L"system32", NULL, s_Dirs },
|
||||
{ 25, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name", s_Dirs },
|
||||
/* path without dirs in system32 */
|
||||
{ 26, 0, BEEF, EF_SYS_DIR, L"", L"" },
|
||||
{ 27, 0, BEEF, EF_SYS_DIR, L"Fonts", L"Fonts" },
|
||||
{ 28, 0, BEEF, EF_SYS_DIR, L"notepad", L"notepad" },
|
||||
{ 29, 0, BEEF, EF_SYS_DIR, L"notepad.exe", L"notepad.exe" },
|
||||
{ 30, 0, BEEF, EF_SYS_DIR, L"system32", L"system32" },
|
||||
{ 31, 0, BEEF, EF_SYS_DIR, L"invalid name", L"invalid name" },
|
||||
/* path with dirs in system32 */
|
||||
{ 32, 0, BEEF, EF_SYS_DIR, L"", L"", NULL, s_Dirs },
|
||||
{ 33, 0, BEEF, EF_SYS_DIR, L"Fonts", L"Fonts", NULL, s_Dirs },
|
||||
{ 34, 0, BEEF, EF_SYS_DIR, L"notepad", L"notepad", NULL, s_Dirs },
|
||||
{ 35, 0, BEEF, EF_SYS_DIR, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
|
||||
{ 36, 0, BEEF, EF_SYS_DIR, L"system32", L"system32", NULL, s_Dirs },
|
||||
{ 37, 0, BEEF, EF_SYS_DIR, L"invalid name", L"invalid name", NULL, s_Dirs },
|
||||
/* name only without dirs in system32 */
|
||||
{ 38, 1, BEEF, EF_SYS_DIR | EF_NAME_ONLY, L"", NULL, s_SysDir },
|
||||
{ 39, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"Fonts", NULL, s_FontsDir },
|
||||
{ 40, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"notepad", NULL, L"notepad" },
|
||||
{ 41, 1, BEEF, EF_SYS_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe" },
|
||||
{ 42, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"system32", NULL, s_SysDir },
|
||||
{ 43, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name" },
|
||||
/* name only with dirs in system32 */
|
||||
{ 44, 1, BEEF, EF_SYS_DIR | EF_NAME_ONLY, L"", NULL, s_TestDataPath, s_Dirs },
|
||||
{ 45, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"Fonts", NULL, s_FontsDir, s_Dirs },
|
||||
{ 46, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"notepad", NULL, L"notepad", s_Dirs },
|
||||
{ 47, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
|
||||
{ 48, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"system32", NULL, s_SysDir, s_Dirs },
|
||||
{ 49, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name", s_Dirs },
|
||||
/* path without dirs in testdata dir */
|
||||
{ 50, 0, BEEF, EF_TESTDATA, L"", L"" },
|
||||
{ 51, 0, BEEF, EF_TESTDATA, L"Fonts", L"Fonts" },
|
||||
{ 52, 0, BEEF, EF_TESTDATA, L"notepad", L"notepad" },
|
||||
{ 53, 0, BEEF, EF_TESTDATA, L"notepad.exe", L"notepad.exe" },
|
||||
{ 54, 0, BEEF, EF_TESTDATA, L"system32", L"system32" },
|
||||
{ 55, 0, BEEF, EF_TESTDATA, L"invalid name", L"invalid name" },
|
||||
{ 56, 0, BEEF, EF_TESTDATA, L"README.txt", L"README.txt" },
|
||||
{ 57, 0, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils" },
|
||||
{ 58, 0, BEEF, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe" },
|
||||
/* path with dirs in testdata dir */
|
||||
{ 59, 0, BEEF, EF_TESTDATA, L"", L"", NULL, s_Dirs },
|
||||
{ 60, 0, BEEF, EF_TESTDATA, L"Fonts", L"Fonts", NULL, s_Dirs },
|
||||
{ 61, 0, BEEF, EF_TESTDATA, L"notepad", L"notepad", NULL, s_Dirs },
|
||||
{ 62, 0, BEEF, EF_TESTDATA, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
|
||||
{ 63, 0, BEEF, EF_TESTDATA, L"system32", L"system32", NULL, s_Dirs },
|
||||
{ 64, 0, BEEF, EF_TESTDATA, L"invalid name", L"invalid name", NULL, s_Dirs },
|
||||
{ 65, 0, BEEF, EF_TESTDATA, L"README.txt", L"README.txt", NULL, s_Dirs },
|
||||
{ 66, 0, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", NULL, s_Dirs },
|
||||
{ 67, 0, BEEF, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", NULL, s_Dirs },
|
||||
/* name only without dirs in testdata dir */
|
||||
{ 68, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"", NULL, s_SysDir },
|
||||
{ 69, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"Fonts", NULL, s_FontsDir },
|
||||
{ 70, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"notepad", NULL, L"notepad" },
|
||||
{ 71, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath },
|
||||
{ 72, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"system32", NULL, s_SysDir },
|
||||
{ 73, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name" },
|
||||
{ 74, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"README.txt", L"README.txt", NULL, s_Dirs },
|
||||
{ 75, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, L"CmdLineUtils", s_Dirs },
|
||||
{ 76, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, L"CmdLineUtils.exe", s_Dirs },
|
||||
/* name only with dirs in testdata dir */
|
||||
{ 77, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"", NULL, s_TestDataPath, s_Dirs },
|
||||
{ 78, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"Fonts", NULL, s_FontsDir, s_Dirs },
|
||||
{ 79, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"notepad", NULL, L"notepad", s_Dirs },
|
||||
{ 80, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath, s_Dirs },
|
||||
{ 81, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"system32", NULL, s_SysDir, s_Dirs },
|
||||
{ 82, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name", s_Dirs },
|
||||
{ 83, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"README.txt", L"README.txt", NULL, s_Dirs },
|
||||
{ 84, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, L"CmdLineUtils", s_Dirs },
|
||||
{ 85, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, L"CmdLineUtils.exe", s_Dirs },
|
||||
};
|
||||
|
||||
static void DoEntry(INT EntryNumber, const ENTRY *pEntry, const WCHAR *PathVar)
|
||||
{
|
||||
WCHAR Path[MAX_PATH], PathExpected[MAX_PATH], OldPathVar[256];
|
||||
INT Ret;
|
||||
DWORD Error;
|
||||
|
||||
if (pEntry->NameBefore == NULL)
|
||||
{
|
||||
assert(pEntry->NameExpected == NULL);
|
||||
assert(pEntry->PathExpected == NULL);
|
||||
}
|
||||
|
||||
switch (pEntry->EF_ & EF_TYPE_MASK)
|
||||
{
|
||||
case EF_FULLPATH:
|
||||
if (pEntry->NameBefore)
|
||||
{
|
||||
lstrcpyW(Path, pEntry->NameBefore);
|
||||
}
|
||||
if (pEntry->NameExpected)
|
||||
{
|
||||
lstrcpyW(PathExpected, pEntry->NameExpected);
|
||||
}
|
||||
break;
|
||||
|
||||
case EF_TESTDATA:
|
||||
if (pEntry->EF_ & EF_NAME_ONLY)
|
||||
{
|
||||
lstrcpyW(Path, pEntry->NameBefore);
|
||||
}
|
||||
else
|
||||
{
|
||||
lstrcpyW(Path, s_TestDataPath);
|
||||
lstrcatW(Path, L"\\");
|
||||
lstrcatW(Path, pEntry->NameBefore);
|
||||
}
|
||||
|
||||
if (pEntry->NameExpected)
|
||||
{
|
||||
lstrcpyW(PathExpected, s_TestDataPath);
|
||||
lstrcatW(PathExpected, L"\\");
|
||||
lstrcatW(PathExpected, pEntry->NameExpected);
|
||||
}
|
||||
break;
|
||||
|
||||
case EF_WIN_DIR:
|
||||
if (pEntry->EF_ & EF_NAME_ONLY)
|
||||
{
|
||||
lstrcpyW(Path, pEntry->NameBefore);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetWindowsDirectoryW(Path, _countof(Path));
|
||||
lstrcatW(Path, L"\\");
|
||||
lstrcatW(Path, pEntry->NameBefore);
|
||||
}
|
||||
|
||||
if (pEntry->NameExpected)
|
||||
{
|
||||
GetWindowsDirectoryW(PathExpected, _countof(PathExpected));
|
||||
lstrcatW(PathExpected, L"\\");
|
||||
lstrcatW(PathExpected, pEntry->NameExpected);
|
||||
}
|
||||
break;
|
||||
|
||||
case EF_SYS_DIR:
|
||||
if (pEntry->EF_ & EF_NAME_ONLY)
|
||||
{
|
||||
lstrcpyW(Path, pEntry->NameBefore);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetSystemDirectoryW(Path, _countof(Path));
|
||||
lstrcatW(Path, L"\\");
|
||||
lstrcatW(Path, pEntry->NameBefore);
|
||||
}
|
||||
|
||||
if (pEntry->NameExpected)
|
||||
{
|
||||
GetSystemDirectoryW(PathExpected, _countof(PathExpected));
|
||||
lstrcatW(PathExpected, L"\\");
|
||||
lstrcatW(PathExpected, pEntry->NameExpected);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (PathVar)
|
||||
{
|
||||
if (!GetEnvironmentVariableW(L"PATH", OldPathVar, _countof(OldPathVar)))
|
||||
{
|
||||
skip("#%d: GetEnvironmentVariableW failed\n", EntryNumber);
|
||||
return;
|
||||
}
|
||||
if (!SetEnvironmentVariableW(L"PATH", PathVar))
|
||||
{
|
||||
skip("#%d: SetEnvironmentVariableW failed\n", EntryNumber);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
SetLastError(BEEF);
|
||||
if (pEntry->NameBefore)
|
||||
{
|
||||
Ret = PathFindOnPathW(Path, (LPCWSTR *)pEntry->Dirs);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ret = PathFindOnPathW(NULL, (LPCWSTR *)pEntry->Dirs);
|
||||
}
|
||||
Error = GetLastError();
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Ret = RAISED;
|
||||
Error = DEAD;
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
if (PathVar)
|
||||
{
|
||||
ok(SetEnvironmentVariableW(L"PATH", OldPathVar),
|
||||
"#%d: SetEnvironmentVariableW failed\n", EntryNumber);
|
||||
}
|
||||
|
||||
ok(Ret == pEntry->Ret, "#%d: Ret expected %d, was %d.\n",
|
||||
EntryNumber, pEntry->Ret, Ret);
|
||||
|
||||
if (pEntry->Error != IGNORE_ERR)
|
||||
{
|
||||
ok(Error == pEntry->Error, "#%d: last error expected %ld, was %ld.\n",
|
||||
EntryNumber, pEntry->Error, Error);
|
||||
}
|
||||
|
||||
if (pEntry->PathExpected)
|
||||
{
|
||||
ok(lstrcmpiW(Path, pEntry->PathExpected) == 0, "#%d: Path expected %s, was %s.\n",
|
||||
EntryNumber, wine_dbgstr_w(pEntry->PathExpected), wine_dbgstr_w(Path));
|
||||
}
|
||||
else if (pEntry->NameExpected)
|
||||
{
|
||||
ok(lstrcmpiW(Path, PathExpected) == 0, "#%d: Path expected %s, was %s.\n",
|
||||
EntryNumber, wine_dbgstr_w(PathExpected), wine_dbgstr_w(Path));
|
||||
}
|
||||
}
|
||||
|
||||
static void Test_PathFindOnPathW(void)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
for (i = 0; i < _countof(s_Entries); ++i)
|
||||
{
|
||||
DoEntry(s_Entries[i].EntryNumber, &s_Entries[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(PathFindOnPath)
|
||||
{
|
||||
LPWSTR pch;
|
||||
|
||||
GetWindowsDirectoryW(s_WinDir, _countof(s_WinDir));
|
||||
GetSystemDirectoryW(s_SysDir, _countof(s_SysDir));
|
||||
|
||||
lstrcpyW(s_FontsDir, s_WinDir);
|
||||
lstrcatW(s_FontsDir, L"\\Fonts");
|
||||
|
||||
lstrcpyW(s_NotepadPath, s_SysDir);
|
||||
lstrcatW(s_NotepadPath, L"\\notepad.exe");
|
||||
|
||||
GetModuleFileNameW(NULL, s_TestDataPath, _countof(s_TestDataPath));
|
||||
pch = wcsrchr(s_TestDataPath, L'\\');
|
||||
if (pch == NULL)
|
||||
pch = wcsrchr(s_TestDataPath, L'/');
|
||||
if (pch == NULL)
|
||||
{
|
||||
skip("GetModuleFileName and/or wcsrchr are insane.\n");
|
||||
return;
|
||||
}
|
||||
lstrcpyW(pch, L"\\testdata");
|
||||
if (GetFileAttributesW(s_TestDataPath) == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
skip("testdata is not found.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
s_Dirs[0] = s_TestDataPath;
|
||||
s_Dirs[1] = NULL;
|
||||
|
||||
Test_PathFindOnPathW();
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
#define STANDALONE
|
||||
#include <apitest.h>
|
||||
|
||||
extern void func_PathFindOnPath(void);
|
||||
extern void func_isuncpath(void);
|
||||
extern void func_isuncpathserver(void);
|
||||
extern void func_isuncpathservershare(void);
|
||||
@@ -10,7 +9,6 @@ extern void func_StrFormatByteSizeW(void);
|
||||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "PathFindOnPath", func_PathFindOnPath },
|
||||
{ "PathIsUNC", func_isuncpath },
|
||||
{ "PathIsUNCServer", func_isuncpathserver },
|
||||
{ "PathIsUNCServerShare", func_isuncpathservershare },
|
||||
|
@@ -3,15 +3,13 @@
|
||||
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
|
||||
* PURPOSE: Test for CreateWindowEx
|
||||
* PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org>
|
||||
* Mark Jansen
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
#include <winuser.h>
|
||||
#include <msgtrace.h>
|
||||
#include <user32testhelpers.h>
|
||||
|
||||
static void Test_Params(void)
|
||||
|
||||
START_TEST(CreateWindowEx)
|
||||
{
|
||||
HWND hWnd;
|
||||
DWORD dwError;
|
||||
@@ -67,591 +65,3 @@ static void Test_Params(void)
|
||||
ok(hWnd == NULL, "hWnd = %p\n", hWnd);
|
||||
ok(dwError == ERROR_INVALID_WINDOW_HANDLE, "error = %lu\n", dwError);
|
||||
}
|
||||
|
||||
HWND g_TestWindow = NULL;
|
||||
HWND g_ChildWindow = NULL;
|
||||
|
||||
static int get_iwnd(HWND hWnd)
|
||||
{
|
||||
if (!g_TestWindow)
|
||||
g_TestWindow = hWnd;
|
||||
if (!g_ChildWindow && hWnd != g_TestWindow)
|
||||
g_ChildWindow = hWnd;
|
||||
|
||||
if (hWnd == g_TestWindow)
|
||||
return 1;
|
||||
else if (hWnd == g_ChildWindow)
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD g_FaultLine = 0;
|
||||
DWORD g_NcExpectStyle = 0;
|
||||
DWORD g_NcExpectExStyle = 0;
|
||||
DWORD g_ExpectStyle = 0;
|
||||
DWORD g_ExpectExStyle = 0;
|
||||
|
||||
DWORD g_ChildNcExpectStyle = 0;
|
||||
DWORD g_ChildNcExpectExStyle = 0;
|
||||
DWORD g_ChildExpectStyle = 0;
|
||||
DWORD g_ChildExpectExStyle = 0;
|
||||
|
||||
#define ok_hex_(expression, result) \
|
||||
do { \
|
||||
int _value = (expression); \
|
||||
ok_(__FILE__, g_FaultLine)(_value == (result), "Wrong value for '%s', expected: " #result " (0x%x), got: 0x%x\n", \
|
||||
#expression, (int)(result), _value); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
static int g_ChangeStyle = 0;
|
||||
static LRESULT CALLBACK MSGTestProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LRESULT lRet;
|
||||
int iwnd = get_iwnd(hWnd);
|
||||
|
||||
if(message > WM_USER || !iwnd || IsDWmMsg(message) || IseKeyMsg(message))
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
|
||||
switch(message)
|
||||
{
|
||||
case WM_IME_SETCONTEXT:
|
||||
case WM_IME_NOTIFY:
|
||||
case WM_GETICON:
|
||||
case WM_GETTEXT:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
break;
|
||||
case WM_NCCREATE:
|
||||
{
|
||||
LPCREATESTRUCT create = (LPCREATESTRUCT)lParam;
|
||||
RECORD_MESSAGE(iwnd, message, SENT, 0, 0);
|
||||
ok_hex_(create->style, g_NcExpectStyle);
|
||||
ok_hex_(create->dwExStyle, g_NcExpectExStyle);
|
||||
if (g_ChangeStyle)
|
||||
{
|
||||
DWORD dwStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
|
||||
dwStyle &= ~(WS_EX_CLIENTEDGE);
|
||||
SetWindowLong(hWnd, GWL_EXSTYLE, dwStyle);
|
||||
RECORD_MESSAGE(iwnd, message, MARKER, 0, 0);
|
||||
SetWindowPos(hWnd, NULL, 0, 0, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_DRAWFRAME);
|
||||
|
||||
RECORD_MESSAGE(iwnd, message, MARKER, 0, 0);
|
||||
ok_hex_(create->style, g_NcExpectStyle);
|
||||
ok_hex_(create->dwExStyle, g_NcExpectExStyle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_CREATE:
|
||||
{
|
||||
LPCREATESTRUCT create = (LPCREATESTRUCT)lParam;
|
||||
RECORD_MESSAGE(iwnd, message, SENT, 0, 0);
|
||||
ok_hex_(create->style, g_ExpectStyle);
|
||||
ok_hex_(create->dwExStyle, g_ExpectExStyle);
|
||||
}
|
||||
break;
|
||||
case WM_NCCALCSIZE:
|
||||
case WM_STYLECHANGING:
|
||||
case WM_STYLECHANGED:
|
||||
case WM_SIZE:
|
||||
RECORD_MESSAGE(iwnd, message, SENT, wParam, 0);
|
||||
break;
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
ok(wParam == 0,"expected wParam=0\n");
|
||||
RECORD_MESSAGE(iwnd, message, SENT, ((WINDOWPOS*)lParam)->flags, 0);
|
||||
break;
|
||||
default:
|
||||
RECORD_MESSAGE(iwnd, message, SENT, 0, 0);
|
||||
break;
|
||||
}
|
||||
lRet = DefWindowProc(hWnd, message, wParam, lParam);
|
||||
RECORD_MESSAGE(iwnd, message, SENT_RET, 0, 0);
|
||||
return lRet;
|
||||
}
|
||||
|
||||
MSG_ENTRY create_chain[] =
|
||||
{
|
||||
{ 1, WM_GETMINMAXINFO, SENT },
|
||||
{ 1, WM_GETMINMAXINFO, SENT_RET },
|
||||
{ 1, WM_NCCREATE, SENT },
|
||||
{ 1, WM_NCCREATE, SENT_RET },
|
||||
{ 1, WM_NCCALCSIZE, SENT },
|
||||
{ 1, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 1, WM_CREATE, SENT },
|
||||
{ 1, WM_CREATE, SENT_RET },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
MSG_ENTRY create_chain_modify[] =
|
||||
{
|
||||
{ 1, WM_GETMINMAXINFO, SENT },
|
||||
{ 1, WM_GETMINMAXINFO, SENT_RET },
|
||||
{ 1, WM_NCCREATE, SENT },
|
||||
{ 1, WM_STYLECHANGING, SENT, GWL_EXSTYLE },
|
||||
{ 1, WM_STYLECHANGING, SENT_RET },
|
||||
{ 1, WM_STYLECHANGED, SENT, GWL_EXSTYLE },
|
||||
{ 1, WM_STYLECHANGED, SENT_RET },
|
||||
{ 1, WM_NCCREATE, MARKER },
|
||||
{ 1, WM_WINDOWPOSCHANGING, SENT, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED },
|
||||
{ 1, WM_WINDOWPOSCHANGING, SENT_RET },
|
||||
{ 1, WM_NCCALCSIZE, SENT, TRUE },
|
||||
{ 1, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 1, WM_WINDOWPOSCHANGED, SENT, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED },
|
||||
{ 1, WM_MOVE, SENT },
|
||||
{ 1, WM_MOVE, SENT_RET },
|
||||
{ 1, WM_SIZE, SENT },
|
||||
{ 1, WM_SIZE, SENT_RET },
|
||||
{ 1, WM_WINDOWPOSCHANGED, SENT_RET },
|
||||
{ 1, WM_NCCREATE, MARKER },
|
||||
{ 1, WM_NCCREATE, SENT_RET },
|
||||
{ 1, WM_NCCALCSIZE, SENT },
|
||||
{ 1, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 1, WM_CREATE, SENT },
|
||||
{ 1, WM_CREATE, SENT_RET },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
MSG_ENTRY create_chain_modify_below8_nonsrv[] =
|
||||
{
|
||||
{ 1, WM_GETMINMAXINFO, SENT },
|
||||
{ 1, WM_GETMINMAXINFO, SENT_RET },
|
||||
{ 1, WM_NCCREATE, SENT },
|
||||
{ 1, WM_STYLECHANGING, SENT, GWL_EXSTYLE },
|
||||
{ 1, WM_STYLECHANGING, SENT_RET },
|
||||
{ 1, WM_STYLECHANGED, SENT, GWL_EXSTYLE },
|
||||
{ 1, WM_STYLECHANGED, SENT_RET },
|
||||
{ 1, WM_NCCREATE, MARKER },
|
||||
{ 1, WM_WINDOWPOSCHANGING, SENT, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED },
|
||||
{ 1, WM_WINDOWPOSCHANGING, SENT_RET },
|
||||
{ 1, WM_NCCALCSIZE, SENT, TRUE },
|
||||
{ 1, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 1, WM_WINDOWPOSCHANGED, SENT, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED },
|
||||
{ 1, WM_MOVE, SENT },
|
||||
{ 1, WM_MOVE, SENT_RET },
|
||||
{ 1, WM_SIZE, SENT },
|
||||
{ 1, WM_SIZE, SENT_RET },
|
||||
{ 1, WM_WINDOWPOSCHANGED, SENT_RET },
|
||||
{ 1, WM_NCCALCSIZE, SENT, TRUE },
|
||||
{ 1, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 1, WM_NCCREATE, MARKER },
|
||||
{ 1, WM_NCCREATE, SENT_RET },
|
||||
{ 1, WM_NCCALCSIZE, SENT },
|
||||
{ 1, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 1, WM_CREATE, SENT },
|
||||
{ 1, WM_CREATE, SENT_RET },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static BOOL
|
||||
IsWindowsServer()
|
||||
{
|
||||
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0, 0, VER_NT_WORKSTATION };
|
||||
DWORDLONG const dwlConditionMask = VerSetConditionMask( 0, VER_PRODUCT_TYPE, VER_EQUAL );
|
||||
|
||||
return !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask);
|
||||
}
|
||||
|
||||
|
||||
static BOOL
|
||||
IsWindows8OrGreater()
|
||||
{
|
||||
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
|
||||
DWORDLONG const dwlConditionMask = VerSetConditionMask(VerSetConditionMask(
|
||||
VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL),
|
||||
VER_MINORVERSION, VER_GREATER_EQUAL),
|
||||
VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
|
||||
osvi.dwMajorVersion = HIBYTE(_WIN32_WINNT_WIN8);
|
||||
osvi.dwMinorVersion = LOBYTE(_WIN32_WINNT_WIN8);
|
||||
|
||||
return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
|
||||
}
|
||||
|
||||
static void Test_Messages(void)
|
||||
{
|
||||
HWND hWnd;
|
||||
BOOL Below8NonServer = !IsWindows8OrGreater() && !IsWindowsServer();
|
||||
|
||||
RegisterSimpleClass(MSGTestProc, L"Test_Message_Window_XX");
|
||||
|
||||
g_ChangeStyle = 0;
|
||||
|
||||
g_ExpectStyle = g_NcExpectStyle = 0;
|
||||
g_ExpectExStyle = g_NcExpectExStyle = WS_EX_CLIENTEDGE;
|
||||
g_FaultLine = __LINE__ + 1;
|
||||
hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Test_Message_Window_XX", L"", 0, 10, 20,
|
||||
200, 210, NULL, NULL, 0, NULL);
|
||||
|
||||
ok(hWnd == g_TestWindow, "We are testing with %p instead of %p\n", g_TestWindow, hWnd);
|
||||
COMPARE_CACHE(create_chain);
|
||||
DestroyWindow(hWnd);
|
||||
g_TestWindow = g_ChildWindow = NULL;
|
||||
EMPTY_CACHE();
|
||||
|
||||
g_ExpectStyle = g_NcExpectStyle = WS_OVERLAPPEDWINDOW;
|
||||
g_ExpectExStyle = g_NcExpectExStyle = WS_EX_OVERLAPPEDWINDOW;
|
||||
g_FaultLine = __LINE__ + 1;
|
||||
hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Test_Message_Window_XX", L"", WS_OVERLAPPEDWINDOW, 10, 20,
|
||||
200, 210, NULL, NULL, 0, NULL);
|
||||
|
||||
ok(hWnd == g_TestWindow, "We are testing with %p instead of %p\n", g_TestWindow, hWnd);
|
||||
COMPARE_CACHE(create_chain);
|
||||
DestroyWindow(hWnd);
|
||||
g_TestWindow = g_ChildWindow = NULL;
|
||||
EMPTY_CACHE();
|
||||
|
||||
g_ChangeStyle = 1;
|
||||
|
||||
g_ExpectStyle = g_NcExpectStyle = 0;
|
||||
g_ExpectExStyle = g_NcExpectExStyle = WS_EX_CLIENTEDGE;
|
||||
g_FaultLine = __LINE__ + 1;
|
||||
hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Test_Message_Window_XX", L"", 0, 10, 20,
|
||||
200, 210, NULL, NULL, 0, NULL);
|
||||
|
||||
ok(hWnd == g_TestWindow, "We are testing with %p instead of %p\n", g_TestWindow, hWnd);
|
||||
COMPARE_CACHE(Below8NonServer ? create_chain_modify_below8_nonsrv : create_chain_modify);
|
||||
DestroyWindow(hWnd);
|
||||
g_TestWindow = g_ChildWindow = NULL;
|
||||
EMPTY_CACHE();
|
||||
|
||||
g_ExpectStyle = g_NcExpectStyle = WS_OVERLAPPEDWINDOW;
|
||||
g_ExpectExStyle = g_NcExpectExStyle = WS_EX_OVERLAPPEDWINDOW;
|
||||
g_FaultLine = __LINE__ + 1;
|
||||
hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Test_Message_Window_XX", L"", WS_OVERLAPPEDWINDOW, 10, 20,
|
||||
200, 210, NULL, NULL, 0, NULL);
|
||||
|
||||
ok(hWnd == g_TestWindow, "We are testing with %p instead of %p\n", g_TestWindow, hWnd);
|
||||
COMPARE_CACHE(Below8NonServer ? create_chain_modify_below8_nonsrv : create_chain_modify);
|
||||
DestroyWindow(hWnd);
|
||||
g_TestWindow = g_ChildWindow = NULL;
|
||||
EMPTY_CACHE();
|
||||
|
||||
UnregisterClassW(L"Test_Message_Window_XX", NULL);
|
||||
}
|
||||
|
||||
|
||||
static LRESULT CALLBACK MSGChildProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LRESULT lRet;
|
||||
int iwnd = get_iwnd(hWnd);
|
||||
|
||||
if(message > WM_USER || !iwnd || IsDWmMsg(message) || IseKeyMsg(message))
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
|
||||
switch(message)
|
||||
{
|
||||
case WM_IME_SETCONTEXT:
|
||||
case WM_IME_NOTIFY:
|
||||
case WM_GETICON:
|
||||
case WM_GETTEXT:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
break;
|
||||
case WM_NCCREATE:
|
||||
{
|
||||
LPCREATESTRUCT create = (LPCREATESTRUCT)lParam;
|
||||
RECORD_MESSAGE(iwnd, message, SENT, 0, 0);
|
||||
ok_hex_(create->style, g_ChildNcExpectStyle);
|
||||
ok_hex_(create->dwExStyle, g_ChildNcExpectExStyle);
|
||||
|
||||
if (g_ChangeStyle)
|
||||
{
|
||||
DWORD dwStyle = GetWindowLong(g_TestWindow, GWL_EXSTYLE);
|
||||
dwStyle &= ~(WS_EX_CLIENTEDGE);
|
||||
SetWindowLong(g_TestWindow, GWL_EXSTYLE, dwStyle);
|
||||
RECORD_MESSAGE(iwnd, message, MARKER, 0, 0);
|
||||
SetWindowPos(g_TestWindow, NULL, 0, 0, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_DRAWFRAME);
|
||||
|
||||
RECORD_MESSAGE(iwnd, message, MARKER, 0, 0);
|
||||
ok_hex_(create->style, g_ChildNcExpectStyle);
|
||||
ok_hex_(create->dwExStyle, g_ChildNcExpectExStyle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_CREATE:
|
||||
{
|
||||
LPCREATESTRUCT create = (LPCREATESTRUCT)lParam;
|
||||
RECORD_MESSAGE(iwnd, message, SENT, 0, 0);
|
||||
ok_hex_(create->style, g_ChildExpectStyle);
|
||||
ok_hex_(create->dwExStyle, g_ChildExpectExStyle);
|
||||
}
|
||||
break;
|
||||
case WM_NCCALCSIZE:
|
||||
case WM_STYLECHANGING:
|
||||
case WM_STYLECHANGED:
|
||||
case WM_SIZE:
|
||||
RECORD_MESSAGE(iwnd, message, SENT, wParam, 0);
|
||||
break;
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
ok(wParam == 0,"expected wParam=0\n");
|
||||
RECORD_MESSAGE(iwnd, message, SENT, ((WINDOWPOS*)lParam)->flags, 0);
|
||||
break;
|
||||
default:
|
||||
RECORD_MESSAGE(iwnd, message, SENT, 0, 0);
|
||||
break;
|
||||
}
|
||||
lRet = DefWindowProc(hWnd, message, wParam, lParam);
|
||||
RECORD_MESSAGE(iwnd, message, SENT_RET, 0, 0);
|
||||
return lRet;
|
||||
}
|
||||
|
||||
|
||||
static LRESULT CALLBACK MSGTestProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LRESULT lRet;
|
||||
int iwnd = get_iwnd(hWnd);
|
||||
|
||||
if(message > WM_USER || !iwnd || IsDWmMsg(message) || IseKeyMsg(message))
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
|
||||
switch(message)
|
||||
{
|
||||
case WM_IME_SETCONTEXT:
|
||||
case WM_IME_NOTIFY:
|
||||
case WM_GETICON:
|
||||
case WM_GETTEXT:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
break;
|
||||
case WM_NCCREATE:
|
||||
{
|
||||
HWND child;
|
||||
LPCREATESTRUCT create = (LPCREATESTRUCT)lParam;
|
||||
RECORD_MESSAGE(iwnd, message, SENT, 0, 0);
|
||||
ok_hex_(create->style, g_NcExpectStyle);
|
||||
ok_hex_(create->dwExStyle, g_NcExpectExStyle);
|
||||
|
||||
child = CreateWindowExW(0, L"Test_Message_Window_Child2", L"", WS_CHILD, 0, 0, 10, 10, hWnd, NULL, 0, NULL);
|
||||
RECORD_MESSAGE(iwnd, message, MARKER, 0, 0);
|
||||
ok_(__FILE__, g_FaultLine)(g_ChildWindow == child, "Testing against the wrong child!\n");
|
||||
}
|
||||
break;
|
||||
case WM_NCDESTROY:
|
||||
RECORD_MESSAGE(iwnd, message, SENT, 0, 0);
|
||||
DestroyWindow(g_ChildWindow);
|
||||
break;
|
||||
case WM_CREATE:
|
||||
{
|
||||
LPCREATESTRUCT create = (LPCREATESTRUCT)lParam;
|
||||
RECORD_MESSAGE(iwnd, message, SENT, 0, 0);
|
||||
ok_hex_(create->style, g_ExpectStyle);
|
||||
ok_hex_(create->dwExStyle, g_ExpectExStyle);
|
||||
}
|
||||
break;
|
||||
case WM_NCCALCSIZE:
|
||||
case WM_STYLECHANGING:
|
||||
case WM_STYLECHANGED:
|
||||
case WM_SIZE:
|
||||
RECORD_MESSAGE(iwnd, message, SENT, wParam, 0);
|
||||
break;
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
ok(wParam == 0,"expected wParam=0\n");
|
||||
RECORD_MESSAGE(iwnd, message, SENT, ((WINDOWPOS*)lParam)->flags, 0);
|
||||
break;
|
||||
default:
|
||||
RECORD_MESSAGE(iwnd, message, SENT, 0, 0);
|
||||
break;
|
||||
}
|
||||
lRet = DefWindowProc(hWnd, message, wParam, lParam);
|
||||
RECORD_MESSAGE(iwnd, message, SENT_RET, 0, 0);
|
||||
return lRet;
|
||||
}
|
||||
|
||||
|
||||
MSG_ENTRY child_create_chain[] =
|
||||
{
|
||||
{ 1, WM_GETMINMAXINFO, SENT },
|
||||
{ 1, WM_GETMINMAXINFO, SENT_RET },
|
||||
{ 1, WM_NCCREATE, SENT },
|
||||
{ 2, WM_NCCREATE, SENT },
|
||||
{ 2, WM_NCCREATE, SENT_RET },
|
||||
{ 2, WM_NCCALCSIZE, SENT },
|
||||
{ 2, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 2, WM_CREATE, SENT },
|
||||
{ 2, WM_CREATE, SENT_RET },
|
||||
{ 2, WM_SIZE, SENT },
|
||||
{ 2, WM_SIZE, SENT_RET },
|
||||
{ 2, WM_MOVE, SENT },
|
||||
{ 2, WM_MOVE, SENT_RET },
|
||||
{ 1, WM_PARENTNOTIFY, SENT },
|
||||
{ 1, WM_PARENTNOTIFY, SENT_RET },
|
||||
{ 1, WM_NCCREATE, MARKER },
|
||||
{ 1, WM_NCCREATE, SENT_RET },
|
||||
{ 1, WM_NCCALCSIZE, SENT },
|
||||
{ 1, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 1, WM_CREATE, SENT },
|
||||
{ 1, WM_CREATE, SENT_RET },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
MSG_ENTRY child_create_chain_modify[] =
|
||||
{
|
||||
{ 1, WM_GETMINMAXINFO, SENT },
|
||||
{ 1, WM_GETMINMAXINFO, SENT_RET },
|
||||
{ 1, WM_NCCREATE, SENT },
|
||||
{ 2, WM_NCCREATE, SENT },
|
||||
{ 1, WM_STYLECHANGING, SENT, GWL_EXSTYLE },
|
||||
{ 1, WM_STYLECHANGING, SENT_RET },
|
||||
{ 1, WM_STYLECHANGED, SENT, GWL_EXSTYLE },
|
||||
{ 1, WM_STYLECHANGED, SENT_RET },
|
||||
{ 2, WM_NCCREATE, MARKER },
|
||||
{ 1, WM_WINDOWPOSCHANGING, SENT, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED },
|
||||
{ 1, WM_WINDOWPOSCHANGING, SENT_RET },
|
||||
{ 1, WM_NCCALCSIZE, SENT, TRUE },
|
||||
{ 1, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 1, WM_WINDOWPOSCHANGED, SENT, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED },
|
||||
{ 1, WM_MOVE, SENT },
|
||||
{ 1, WM_MOVE, SENT_RET },
|
||||
{ 1, WM_SIZE, SENT },
|
||||
{ 1, WM_SIZE, SENT_RET },
|
||||
{ 1, WM_WINDOWPOSCHANGED, SENT_RET },
|
||||
{ 2, WM_NCCREATE, MARKER },
|
||||
{ 2, WM_NCCREATE, SENT_RET },
|
||||
{ 2, WM_NCCALCSIZE, SENT },
|
||||
{ 2, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 2, WM_CREATE, SENT },
|
||||
{ 2, WM_CREATE, SENT_RET },
|
||||
{ 2, WM_SIZE, SENT },
|
||||
{ 2, WM_SIZE, SENT_RET },
|
||||
{ 2, WM_MOVE, SENT },
|
||||
{ 2, WM_MOVE, SENT_RET },
|
||||
{ 1, WM_PARENTNOTIFY, SENT },
|
||||
{ 1, WM_PARENTNOTIFY, SENT_RET },
|
||||
{ 1, WM_NCCREATE, MARKER },
|
||||
{ 1, WM_NCCREATE, SENT_RET },
|
||||
{ 1, WM_NCCALCSIZE, SENT },
|
||||
{ 1, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 1, WM_CREATE, SENT },
|
||||
{ 1, WM_CREATE, SENT_RET },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
MSG_ENTRY child_create_chain_modify_below8_nonsrv[] =
|
||||
{
|
||||
{ 1, WM_GETMINMAXINFO, SENT },
|
||||
{ 1, WM_GETMINMAXINFO, SENT_RET },
|
||||
{ 1, WM_NCCREATE, SENT },
|
||||
{ 2, WM_NCCREATE, SENT },
|
||||
{ 1, WM_STYLECHANGING, SENT, GWL_EXSTYLE },
|
||||
{ 1, WM_STYLECHANGING, SENT_RET },
|
||||
{ 1, WM_STYLECHANGED, SENT, GWL_EXSTYLE },
|
||||
{ 1, WM_STYLECHANGED, SENT_RET },
|
||||
{ 2, WM_NCCREATE, MARKER },
|
||||
{ 1, WM_WINDOWPOSCHANGING, SENT, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED },
|
||||
{ 1, WM_WINDOWPOSCHANGING, SENT_RET },
|
||||
{ 1, WM_NCCALCSIZE, SENT, TRUE },
|
||||
{ 1, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 1, WM_WINDOWPOSCHANGED, SENT, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED },
|
||||
{ 1, WM_MOVE, SENT },
|
||||
{ 1, WM_MOVE, SENT_RET },
|
||||
{ 1, WM_SIZE, SENT },
|
||||
{ 1, WM_SIZE, SENT_RET },
|
||||
{ 1, WM_WINDOWPOSCHANGED, SENT_RET },
|
||||
{ 1, WM_NCCALCSIZE, SENT, TRUE },
|
||||
{ 1, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 2, WM_NCCREATE, MARKER },
|
||||
{ 2, WM_NCCREATE, SENT_RET },
|
||||
{ 2, WM_NCCALCSIZE, SENT },
|
||||
{ 2, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 2, WM_CREATE, SENT },
|
||||
{ 2, WM_CREATE, SENT_RET },
|
||||
{ 2, WM_SIZE, SENT },
|
||||
{ 2, WM_SIZE, SENT_RET },
|
||||
{ 2, WM_MOVE, SENT },
|
||||
{ 2, WM_MOVE, SENT_RET },
|
||||
{ 1, WM_PARENTNOTIFY, SENT },
|
||||
{ 1, WM_PARENTNOTIFY, SENT_RET },
|
||||
{ 1, WM_NCCREATE, MARKER },
|
||||
{ 1, WM_NCCREATE, SENT_RET },
|
||||
{ 1, WM_NCCALCSIZE, SENT },
|
||||
{ 1, WM_NCCALCSIZE, SENT_RET },
|
||||
{ 1, WM_CREATE, SENT },
|
||||
{ 1, WM_CREATE, SENT_RET },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void Test_Messages_Child(void)
|
||||
{
|
||||
HWND hWnd;
|
||||
BOOL Below8NonServer = !IsWindows8OrGreater() && !IsWindowsServer();
|
||||
|
||||
RegisterSimpleClass(MSGTestProc2, L"Test_Message_Window_X2");
|
||||
RegisterSimpleClass(MSGChildProc2, L"Test_Message_Window_Child2");
|
||||
|
||||
g_ChangeStyle = 0;
|
||||
|
||||
g_ExpectStyle = g_NcExpectStyle = 0;
|
||||
g_ExpectExStyle = g_NcExpectExStyle = WS_EX_CLIENTEDGE;
|
||||
g_ChildExpectStyle = g_ChildNcExpectStyle = WS_CHILD;
|
||||
g_ChildExpectExStyle = g_ChildNcExpectExStyle = 0;
|
||||
g_FaultLine = __LINE__ + 1;
|
||||
hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Test_Message_Window_X2", L"", 0, 10, 20,
|
||||
200, 210, NULL, NULL, 0, NULL);
|
||||
|
||||
ok(hWnd == g_TestWindow, "We are testing with %p instead of %p\n", g_TestWindow, hWnd);
|
||||
COMPARE_CACHE(child_create_chain);
|
||||
DestroyWindow(hWnd);
|
||||
g_TestWindow = g_ChildWindow = NULL;
|
||||
EMPTY_CACHE();
|
||||
|
||||
g_ExpectStyle = g_NcExpectStyle = WS_OVERLAPPEDWINDOW;
|
||||
g_ExpectExStyle = g_NcExpectExStyle = WS_EX_OVERLAPPEDWINDOW;
|
||||
g_ChildExpectStyle = g_ChildNcExpectStyle = WS_CHILD;
|
||||
g_ChildExpectExStyle = g_ChildNcExpectExStyle = 0;
|
||||
g_FaultLine = __LINE__ + 1;
|
||||
hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Test_Message_Window_X2", L"", WS_OVERLAPPEDWINDOW, 10, 20,
|
||||
200, 210, NULL, NULL, 0, NULL);
|
||||
|
||||
ok(hWnd == g_TestWindow, "We are testing with %p instead of %p\n", g_TestWindow, hWnd);
|
||||
COMPARE_CACHE(child_create_chain);
|
||||
DestroyWindow(hWnd);
|
||||
g_TestWindow = g_ChildWindow = NULL;
|
||||
EMPTY_CACHE();
|
||||
|
||||
g_ChangeStyle = 1;
|
||||
|
||||
g_ExpectStyle = g_NcExpectStyle = 0;
|
||||
g_ExpectExStyle = g_NcExpectExStyle = WS_EX_CLIENTEDGE;
|
||||
g_ChildExpectStyle = g_ChildNcExpectStyle = WS_CHILD;
|
||||
g_ChildExpectExStyle = g_ChildNcExpectExStyle = 0;
|
||||
g_FaultLine = __LINE__ + 1;
|
||||
hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Test_Message_Window_X2", L"", 0, 10, 20,
|
||||
200, 210, NULL, NULL, 0, NULL);
|
||||
|
||||
ok(hWnd == g_TestWindow, "We are testing with %p instead of %p\n", g_TestWindow, hWnd);
|
||||
COMPARE_CACHE(Below8NonServer ? child_create_chain_modify_below8_nonsrv : child_create_chain_modify);
|
||||
DestroyWindow(hWnd);
|
||||
g_TestWindow = g_ChildWindow = NULL;
|
||||
EMPTY_CACHE();
|
||||
|
||||
g_ExpectStyle = g_NcExpectStyle = WS_OVERLAPPEDWINDOW;
|
||||
g_ExpectExStyle = g_NcExpectExStyle = WS_EX_OVERLAPPEDWINDOW;
|
||||
g_ChildExpectStyle = g_ChildNcExpectStyle = WS_CHILD;
|
||||
g_ChildExpectExStyle = g_ChildNcExpectExStyle = 0;
|
||||
g_FaultLine = __LINE__ + 1;
|
||||
hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Test_Message_Window_X2", L"", WS_OVERLAPPEDWINDOW, 10, 20,
|
||||
200, 210, NULL, NULL, 0, NULL);
|
||||
|
||||
ok(hWnd == g_TestWindow, "We are testing with %p instead of %p\n", g_TestWindow, hWnd);
|
||||
COMPARE_CACHE(Below8NonServer ? child_create_chain_modify_below8_nonsrv : child_create_chain_modify);
|
||||
DestroyWindow(hWnd);
|
||||
g_TestWindow = g_ChildWindow = NULL;
|
||||
EMPTY_CACHE();
|
||||
|
||||
UnregisterClassW(L"Test_Message_Window_X2", NULL);
|
||||
UnregisterClassW(L"Test_Message_Window_Child2", NULL);
|
||||
}
|
||||
|
||||
|
||||
START_TEST(CreateWindowEx)
|
||||
{
|
||||
Test_Params();
|
||||
Test_Messages();
|
||||
Test_Messages_Child();
|
||||
}
|
||||
|
@@ -246,7 +246,6 @@ static void Test_References(void)
|
||||
NTSTATUS status;
|
||||
OBJECT_BASIC_INFORMATION objectInfo = { 0 };
|
||||
HDESK hdesk;
|
||||
HDESK hdesk1;
|
||||
BOOL ret;
|
||||
ULONG baseRefs;
|
||||
|
||||
@@ -340,23 +339,6 @@ static void Test_References(void)
|
||||
ok(ret == TRUE, "ret = %d\n", ret);
|
||||
hwinsta = open_winsta(winstaName, &error);
|
||||
ok(hwinsta == NULL && error == ERROR_FILE_NOT_FOUND, "Got %p, %lu\n", hwinsta, error);
|
||||
|
||||
/* Test references by SetThreadDesktop */
|
||||
hdesk1 = GetThreadDesktop(GetCurrentThreadId());
|
||||
ok (hdesk1 != hdesk, "Expected the new desktop not to be the thread desktop\n");
|
||||
|
||||
check_ref(hdesk, 1, 8);
|
||||
baseRefs = objectInfo.PointerCount;
|
||||
ok(baseRefs == 8, "Desktop initially has %lu references, expected 8\n", baseRefs);
|
||||
check_ref(hdesk, 1, baseRefs);
|
||||
|
||||
SetThreadDesktop(hdesk);
|
||||
check_ref(hdesk, 1, baseRefs + 1);
|
||||
ok (GetThreadDesktop(GetCurrentThreadId()) == hdesk, "Expected GetThreadDesktop to return hdesk\n");
|
||||
|
||||
SetThreadDesktop(hdesk1);
|
||||
check_ref(hdesk, 1, baseRefs);
|
||||
ok (GetThreadDesktop(GetCurrentThreadId()) == hdesk1, "Expected GetThreadDesktop to return hdesk1\n");
|
||||
}
|
||||
|
||||
START_TEST(desktop)
|
||||
|
@@ -68,12 +68,7 @@ START_TEST(NtGdiDdQueryDirectDrawObject)
|
||||
|
||||
/* Create ReactX handle */
|
||||
hDirectDraw = (HANDLE) NtGdiDdCreateDirectDrawObject(hdc);
|
||||
RTEST(hDirectDraw != NULL);
|
||||
if (hDirectDraw == NULL)
|
||||
{
|
||||
DeleteDC(hdc);
|
||||
return;
|
||||
}
|
||||
ASSERT(hDirectDraw != NULL);
|
||||
|
||||
/* Start Test ReactX NtGdiDdQueryDirectDrawObject function */
|
||||
|
||||
|
@@ -19,9 +19,7 @@ START_TEST(NtGdiEnumFontOpen)
|
||||
// FIXME: We should load the font first
|
||||
|
||||
idEnum = NtGdiEnumFontOpen(hDC, 2, 0, 32, L"Courier", ANSI_CHARSET, &ulCount);
|
||||
TEST(idEnum != 0);
|
||||
if (idEnum == 0)
|
||||
return;
|
||||
ASSERT(idEnum != 0);
|
||||
|
||||
/* we should have a gdi handle here */
|
||||
TEST(GDI_HANDLE_GET_TYPE(idEnum) == GDI_OBJECT_TYPE_ENUMFONT);
|
||||
|
@@ -4,7 +4,6 @@ list(APPEND SOURCE
|
||||
EnumPrinters.c
|
||||
EnumPrintProcessorDatatypes.c
|
||||
GetDefaultPrinter.c
|
||||
GetPrinterData.c
|
||||
GetPrintProcessorDirectory.c
|
||||
IsValidDevmode.c
|
||||
OpenPrinter.c
|
||||
|
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Print Spooler DLL API Tests
|
||||
* LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
|
||||
* PURPOSE: Tests for GetPrinterData(Ex)A/GetPrinterData(Ex)W/SetPrinterData(Ex)A/SetPrinterData(Ex)W
|
||||
* COPYRIGHT: Copyright 2017 Colin Finck <colin@reactos.org>
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <wingdi.h>
|
||||
#include <winspool.h>
|
||||
#include <winreg.h>
|
||||
|
||||
/* From printing/include/spoolss.h */
|
||||
#define MAX_PRINTER_NAME 220
|
||||
|
||||
typedef struct _SPLREG_VALUE
|
||||
{
|
||||
PSTR pszName;
|
||||
PWSTR pwszName;
|
||||
DWORD dwType;
|
||||
DWORD cbNeededA;
|
||||
BOOL bSettable;
|
||||
}
|
||||
SPLREG_VALUE, *PSPLREG_VALUE;
|
||||
|
||||
SPLREG_VALUE SplRegValues[] = {
|
||||
{ "DefaultSpoolDirectory", L"DefaultSpoolDirectory", REG_SZ, 0xFFFFFFFF, TRUE },
|
||||
{ "PortThreadPriorityDefault", L"PortThreadPriorityDefault", REG_NONE, 4, FALSE },
|
||||
{ "PortThreadPriority", L"PortThreadPriority", REG_DWORD, 4, TRUE },
|
||||
{ "SchedulerThreadPriorityDefault", L"SchedulerThreadPriorityDefault", REG_NONE, 4, FALSE },
|
||||
{ "SchedulerThreadPriority", L"SchedulerThreadPriority", REG_DWORD, 4, TRUE },
|
||||
{ "BeepEnabled", L"BeepEnabled", REG_DWORD, 4, TRUE },
|
||||
|
||||
/* These fail in Win8, probably removed since NT6:
|
||||
|
||||
{ "NetPopup", L"NetPopup", REG_DWORD, 4, TRUE },
|
||||
{ "RetryPopup", L"RetryPopup", REG_DWORD, 4, TRUE },
|
||||
{ "NetPopupToComputer", L"NetPopupToComputer", REG_DWORD, 4, TRUE },
|
||||
|
||||
*/
|
||||
|
||||
{ "EventLog", L"EventLog", REG_DWORD, 4, TRUE },
|
||||
{ "MajorVersion", L"MajorVersion", REG_NONE, 4, FALSE },
|
||||
{ "MinorVersion", L"MinorVersion", REG_NONE, 4, FALSE },
|
||||
{ "Architecture", L"Architecture", REG_NONE, 0xFFFFFFFF, FALSE },
|
||||
{ "OSVersion", L"OSVersion", REG_NONE, sizeof(OSVERSIONINFOA), FALSE },
|
||||
{ "OSVersionEx", L"OSVersionEx", REG_NONE, sizeof(OSVERSIONINFOEXA), FALSE },
|
||||
#if 0
|
||||
{ "DsPresent", L"DsPresent", REG_DWORD, 4, FALSE },
|
||||
{ "DsPresentForUser", L"DsPresentForUser", REG_DWORD, 4, FALSE },
|
||||
#endif
|
||||
{ "RemoteFax", L"RemoteFax", REG_NONE, 4, FALSE },
|
||||
{ "RestartJobOnPoolError", L"RestartJobOnPoolError", REG_DWORD, 4, TRUE },
|
||||
{ "RestartJobOnPoolEnabled", L"RestartJobOnPoolEnabled", REG_DWORD, 4, TRUE },
|
||||
{ "DNSMachineName", L"DNSMachineName", REG_SZ, 0xFFFFFFFF, FALSE },
|
||||
{ "AllowUserManageForms", L"AllowUserManageForms", REG_DWORD, 4, TRUE },
|
||||
{ NULL, NULL, 0, 0, FALSE }
|
||||
};
|
||||
|
||||
START_TEST(GetPrinterData)
|
||||
{
|
||||
DWORD cbNeeded;
|
||||
DWORD cchDefaultPrinter;
|
||||
DWORD dwReturnCode;
|
||||
DWORD dwType;
|
||||
HANDLE hPrinter;
|
||||
PBYTE pDataA;
|
||||
PBYTE pDataW;
|
||||
PSPLREG_VALUE p;
|
||||
WCHAR wszDefaultPrinter[MAX_PRINTER_NAME + 1];
|
||||
|
||||
// Don't supply any parameters, this has to fail with ERROR_INVALID_HANDLE!
|
||||
dwReturnCode = GetPrinterDataExW(NULL, NULL, NULL, NULL, NULL, 0, NULL);
|
||||
ok(dwReturnCode == ERROR_INVALID_HANDLE, "GetPrinterDataExW returns error %lu!\n", dwReturnCode);
|
||||
|
||||
// Open a handle to the local print server.
|
||||
if (!OpenPrinterW(NULL, &hPrinter, NULL))
|
||||
{
|
||||
skip("Could not retrieve a handle to the local print server!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Now try with valid handle, but leave remaining parameters NULL.
|
||||
dwReturnCode = GetPrinterDataExW(hPrinter, NULL, NULL, NULL, NULL, 0, NULL);
|
||||
ok(dwReturnCode == RPC_X_NULL_REF_POINTER, "GetPrinterDataExW returns error %lu!\n", dwReturnCode);
|
||||
|
||||
// Try all valid Print Server data values.
|
||||
for (p = SplRegValues; p->pszName; p++)
|
||||
{
|
||||
// Try the ANSI version of the function.
|
||||
dwType = 0xDEADBEEF;
|
||||
dwReturnCode = GetPrinterDataExA(hPrinter, NULL, p->pszName, &dwType, NULL, 0, &cbNeeded);
|
||||
ok(dwReturnCode == ERROR_MORE_DATA || dwReturnCode == ERROR_FILE_NOT_FOUND, "GetPrinterDataExA returns %lu for \"%s\"!\n", dwReturnCode, p->pszName);
|
||||
if (dwReturnCode != ERROR_MORE_DATA)
|
||||
continue;
|
||||
|
||||
ok(dwType == p->dwType, "dwType is %lu for \"%s\"!\n", dwType, p->pszName);
|
||||
|
||||
if (p->cbNeededA < 0xFFFFFFFF)
|
||||
ok(cbNeeded == p->cbNeededA, "cbNeeded is %lu for \"%s\", but expected %lu!\n", cbNeeded, p->pszName, p->cbNeededA);
|
||||
else
|
||||
ok(cbNeeded > 0, "cbNeeded is 0 for \"%s\"!\n", p->pszName);
|
||||
|
||||
pDataA = HeapAlloc(GetProcessHeap(), 0, cbNeeded);
|
||||
dwReturnCode = GetPrinterDataExA(hPrinter, NULL, p->pszName, NULL, pDataA, cbNeeded, &cbNeeded);
|
||||
ok(dwReturnCode == ERROR_SUCCESS, "GetPrinterDataExA returns %lu for \"%s\"!\n", dwReturnCode, p->pszName);
|
||||
|
||||
// Try the Unicode version of the function too.
|
||||
dwType = 0xDEADBEEF;
|
||||
dwReturnCode = GetPrinterDataExW(hPrinter, NULL, p->pwszName, &dwType, NULL, 0, &cbNeeded);
|
||||
ok(dwReturnCode == ERROR_MORE_DATA, "GetPrinterDataExW returns %lu for \"%s\"!\n", dwReturnCode, p->pszName);
|
||||
ok(dwType == p->dwType, "dwType is %lu for \"%s\"!\n", dwType, p->pszName);
|
||||
|
||||
pDataW = HeapAlloc(GetProcessHeap(), 0, cbNeeded);
|
||||
dwReturnCode = GetPrinterDataExW(hPrinter, NULL, p->pwszName, NULL, pDataW, cbNeeded, &cbNeeded);
|
||||
ok(dwReturnCode == ERROR_SUCCESS, "GetPrinterDataExW returns %lu for \"%s\"!\n", dwReturnCode, p->pszName);
|
||||
|
||||
// Verify that OSVERSIONINFO structures are correctly returned.
|
||||
if (strcmp(p->pszName, "OSVersion") == 0)
|
||||
{
|
||||
POSVERSIONINFOA pOSVersionInfoA = (POSVERSIONINFOA)pDataA;
|
||||
POSVERSIONINFOW pOSVersionInfoW = (POSVERSIONINFOW)pDataW;
|
||||
ok(pOSVersionInfoA->dwOSVersionInfoSize == sizeof(OSVERSIONINFOA), "dwOSVersionInfoSize is %lu!\n", pOSVersionInfoA->dwOSVersionInfoSize);
|
||||
ok(pOSVersionInfoW->dwOSVersionInfoSize == sizeof(OSVERSIONINFOW), "dwOSVersionInfoSize is %lu!\n", pOSVersionInfoW->dwOSVersionInfoSize);
|
||||
}
|
||||
else if (strcmp(p->pszName, "OSVersionEx") == 0)
|
||||
{
|
||||
POSVERSIONINFOEXA pOSVersionInfoA = (POSVERSIONINFOEXA)pDataA;
|
||||
POSVERSIONINFOEXW pOSVersionInfoW = (POSVERSIONINFOEXW)pDataW;
|
||||
ok(pOSVersionInfoA->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA), "dwOSVersionInfoSize is %lu!\n", pOSVersionInfoA->dwOSVersionInfoSize);
|
||||
ok(pOSVersionInfoW->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXW), "dwOSVersionInfoSize is %lu!\n", pOSVersionInfoW->dwOSVersionInfoSize);
|
||||
}
|
||||
|
||||
// Shortly test SetPrinterDataExW by setting the same data we just retrieved.
|
||||
if (p->bSettable)
|
||||
{
|
||||
dwReturnCode = SetPrinterDataExW(hPrinter, NULL, p->pwszName, dwType, pDataW, cbNeeded);
|
||||
ok(dwReturnCode == ERROR_SUCCESS, "SetPrinterDataExW returns %lu for \"%s\"!\n", dwReturnCode, p->pszName);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pDataA);
|
||||
HeapFree(GetProcessHeap(), 0, pDataW);
|
||||
}
|
||||
|
||||
// Try an invalid one.
|
||||
dwReturnCode = GetPrinterDataExW(hPrinter, NULL, L"Invalid", NULL, NULL, 0, &cbNeeded);
|
||||
ok(dwReturnCode == ERROR_INVALID_PARAMETER, "GetPrinterDataExW returns %lu!\n", dwReturnCode);
|
||||
|
||||
ClosePrinter(hPrinter);
|
||||
|
||||
// Open a handle to the default printer.
|
||||
cchDefaultPrinter = _countof(wszDefaultPrinter);
|
||||
ok(GetDefaultPrinterW(wszDefaultPrinter, &cchDefaultPrinter), "GetDefaultPrinterW returns FALSE and requires %lu characters!\n", cchDefaultPrinter);
|
||||
if (!OpenPrinterW(wszDefaultPrinter, &hPrinter, NULL))
|
||||
{
|
||||
skip("Could not retrieve a handle to the default printer!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Using NULL or L"" for pKeyName on a Printer handle yields ERROR_INVALID_PARAMETER.
|
||||
dwReturnCode = GetPrinterDataExW(hPrinter, NULL, L"Name", NULL, NULL, 0, &cbNeeded);
|
||||
ok(dwReturnCode == ERROR_INVALID_PARAMETER, "GetPrinterDataExW returns %lu!\n", dwReturnCode);
|
||||
dwReturnCode = GetPrinterDataExW(hPrinter, L"", L"Name", NULL, NULL, 0, &cbNeeded);
|
||||
ok(dwReturnCode == ERROR_INVALID_PARAMETER, "GetPrinterDataExW returns %lu!\n", dwReturnCode);
|
||||
|
||||
// Using L"\\" allows us to examine the contents of the main printer key anyway.
|
||||
dwReturnCode = GetPrinterDataExW(hPrinter, L"\\", L"Name", &dwType, NULL, 0, &cbNeeded);
|
||||
ok(dwReturnCode == ERROR_MORE_DATA, "GetPrinterDataExW returns %lu!\n", dwReturnCode);
|
||||
ok(dwType == REG_SZ, "dwType is %lu!\n", dwType);
|
||||
ok(cbNeeded > 0, "cbNeeded is 0!\n");
|
||||
|
||||
pDataW = HeapAlloc(GetProcessHeap(), 0, cbNeeded);
|
||||
dwReturnCode = GetPrinterDataExW(hPrinter, L"\\", L"Name", NULL, pDataW, cbNeeded, &cbNeeded);
|
||||
ok(dwReturnCode == ERROR_SUCCESS, "GetPrinterDataExW returns %lu!\n", dwReturnCode);
|
||||
|
||||
// The following test fails if the default printer is a remote printer.
|
||||
ok(wcscmp((PWSTR)pDataW, wszDefaultPrinter) == 0, "pDataW is \"%S\", default printer is \"%S\"!\n", (PWSTR)pDataW, wszDefaultPrinter);
|
||||
|
||||
// SetPrinterDataExW should return ERROR_ACCESS_DENIED when attempting to set the Name.
|
||||
dwReturnCode = SetPrinterDataExW(hPrinter, L"\\", L"Name", REG_SZ, pDataW, cbNeeded);
|
||||
ok(dwReturnCode == ERROR_ACCESS_DENIED, "SetPrinterDataExW returns %lu!\n", dwReturnCode);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pDataW);
|
||||
}
|
@@ -14,7 +14,6 @@ extern void func_ClosePrinter(void);
|
||||
extern void func_EnumPrinters(void);
|
||||
extern void func_EnumPrintProcessorDatatypes(void);
|
||||
extern void func_GetDefaultPrinter(void);
|
||||
extern void func_GetPrinterData(void);
|
||||
extern void func_GetPrintProcessorDirectoryA(void);
|
||||
extern void func_GetPrintProcessorDirectoryW(void);
|
||||
extern void func_IsValidDevmodeA(void);
|
||||
@@ -28,7 +27,6 @@ const struct test winetest_testlist[] =
|
||||
{ "EnumPrinters", func_EnumPrinters },
|
||||
{ "EnumPrintProcessorDatatypes", func_EnumPrintProcessorDatatypes },
|
||||
{ "GetDefaultPrinter", func_GetDefaultPrinter },
|
||||
{ "GetPrinterData", func_GetPrinterData },
|
||||
{ "GetPrintProcessorDirectoryA", func_GetPrintProcessorDirectoryA },
|
||||
{ "GetPrintProcessorDirectoryW", func_GetPrintProcessorDirectoryW },
|
||||
{ "IsValidDevmodeA", func_IsValidDevmodeA },
|
||||
|
@@ -1,7 +1,5 @@
|
||||
|
||||
list(APPEND SOURCE
|
||||
bind.c
|
||||
close.c
|
||||
getaddrinfo.c
|
||||
getnameinfo.c
|
||||
getservbyname.c
|
||||
|
@@ -1,232 +0,0 @@
|
||||
/*
|
||||
* PROJECT: ReactOS api tests
|
||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||
* PURPOSE: Test for bind
|
||||
* PROGRAMMER: Peter Hater
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#define _INC_WINDOWS
|
||||
#define COM_NO_WINDOWS_H
|
||||
#include <stdarg.h>
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <ndk/umtypes.h>
|
||||
|
||||
CHAR LocalAddress[sizeof("255.255.255.255")];
|
||||
#define PORT 58888
|
||||
|
||||
static
|
||||
VOID
|
||||
TestBind(IN_ADDR Address)
|
||||
{
|
||||
int Error;
|
||||
struct
|
||||
{
|
||||
INT Type;
|
||||
INT Proto;
|
||||
struct sockaddr_in Addr;
|
||||
INT ExpectedResult;
|
||||
INT ExpectedWSAResult;
|
||||
struct sockaddr_in ExpectedAddr;
|
||||
} Tests[] =
|
||||
{
|
||||
{ SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } },
|
||||
{ SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} } },
|
||||
{ SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, Address }, 0, 0, { AF_INET, PORT, Address } },
|
||||
{ SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL },
|
||||
{ SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } },
|
||||
{ SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ 0x00, 0x00, 0x00, 0x00 }}} } },
|
||||
{ SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, Address }, 0, 0, { AF_INET, 0, Address } },
|
||||
{ SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL },
|
||||
{ SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } },
|
||||
{ SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} } },
|
||||
{ SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, Address }, 0, 0, { AF_INET, PORT, Address } },
|
||||
{ SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL },
|
||||
{ SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } },
|
||||
{ SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ 0x00, 0x00, 0x00, 0x00 }}} } },
|
||||
{ SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, Address }, 0, 0,{ AF_INET, 0, Address } },
|
||||
{ SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL },
|
||||
};
|
||||
const INT TestCount = _countof(Tests);
|
||||
INT i, AddrSize;
|
||||
SOCKET Socket;
|
||||
struct sockaddr_in Addr;
|
||||
BOOL Broadcast = TRUE;
|
||||
|
||||
for (i = 0; i < TestCount; i++)
|
||||
{
|
||||
trace("%d: %s %d.%d.%d.%d:%d\n", i, Tests[i].Type == SOCK_STREAM ? "TCP" : "UDP", Tests[i].Addr.sin_addr.S_un.S_un_b.s_b1, Tests[i].Addr.sin_addr.S_un.S_un_b.s_b2, Tests[i].Addr.sin_addr.S_un.S_un_b.s_b3, Tests[i].Addr.sin_addr.S_un.S_un_b.s_b4, Tests[i].ExpectedAddr.sin_port);
|
||||
Socket = socket(AF_INET, Tests[i].Type, Tests[i].Proto);
|
||||
if (Socket == INVALID_SOCKET)
|
||||
{
|
||||
skip("Failed to create socket with error %d for test %d, skipping\n", WSAGetLastError(), i);
|
||||
continue;
|
||||
}
|
||||
Error = bind(Socket, (const struct sockaddr *) &Tests[i].Addr, sizeof(Tests[i].Addr));
|
||||
ok(Error == Tests[i].ExpectedResult, "Error %d differs from expected %d for test %d\n", Error, Tests[i].ExpectedResult, i);
|
||||
if (Error)
|
||||
{
|
||||
ok(WSAGetLastError() == Tests[i].ExpectedWSAResult, "Error %d differs from expected %d for test %d\n", WSAGetLastError(), Tests[i].ExpectedWSAResult, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddrSize = sizeof(Addr);
|
||||
Error = getsockname(Socket, (struct sockaddr *) &Addr, &AddrSize);
|
||||
ok(Error == 0, "Unexpected error %d %d on getsockname for test %d\n", Error, WSAGetLastError(), i);
|
||||
ok(AddrSize == sizeof(Addr), "Returned size %d differs from expected %d for test %d\n", AddrSize, sizeof(Addr), i);
|
||||
ok(Addr.sin_addr.s_addr == Tests[i].ExpectedAddr.sin_addr.s_addr, "Expected address %lx differs from returned address %lx for test %d\n", Tests[i].ExpectedAddr.sin_addr.s_addr, Addr.sin_addr.s_addr, i);
|
||||
if (Tests[i].ExpectedAddr.sin_port)
|
||||
{
|
||||
ok(Addr.sin_port == Tests[i].ExpectedAddr.sin_port, "Returned port %d differs from expected %d for test %d\n", Addr.sin_port, Tests[i].ExpectedAddr.sin_port, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(Addr.sin_port != 0, "Port remained zero for test %d\n", i);
|
||||
}
|
||||
}
|
||||
Error = closesocket(Socket);
|
||||
ok(Error == 0, "Unexpected error %d %d on closesocket for test %d\n", Error, WSAGetLastError(), i);
|
||||
}
|
||||
/* Check double bind */
|
||||
Socket = socket(AF_INET, Tests[0].Type, Tests[0].Proto);
|
||||
ok(Socket != INVALID_SOCKET, "Failed to create socket with error %d for double bind test, next tests might be wrong\n", WSAGetLastError());
|
||||
Error = bind(Socket, (const struct sockaddr *) &Tests[0].Addr, sizeof(Tests[0].Addr));
|
||||
ok(Error == Tests[0].ExpectedResult, "Error %d differs from expected %d for double bind test\n", Error, Tests[0].ExpectedResult);
|
||||
if (Error)
|
||||
{
|
||||
ok(WSAGetLastError() == Tests[i].ExpectedWSAResult, "Error %d differs from expected %d for double bind test\n", WSAGetLastError(), Tests[0].ExpectedWSAResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddrSize = sizeof(Addr);
|
||||
Error = getsockname(Socket, (struct sockaddr *) &Addr, &AddrSize);
|
||||
ok(Error == 0, "Unexpected error %d %d on getsockname for double bind test\n", Error, WSAGetLastError());
|
||||
ok(AddrSize == sizeof(Addr), "Returned size %d differs from expected %d for double bind test\n", AddrSize, sizeof(Addr));
|
||||
ok(Addr.sin_addr.s_addr == Tests[0].ExpectedAddr.sin_addr.s_addr, "Expected address %lx differs from returned address %lx for double bind test\n", Tests[0].ExpectedAddr.sin_addr.s_addr, Addr.sin_addr.s_addr);
|
||||
if (Tests[0].ExpectedAddr.sin_port)
|
||||
{
|
||||
ok(Addr.sin_port == Tests[0].ExpectedAddr.sin_port, "Returned port %d differs from expected %d for double bind test\n", Addr.sin_port, Tests[0].ExpectedAddr.sin_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(Addr.sin_port != 0, "Port remained zero for double bind test\n");
|
||||
}
|
||||
Error = bind(Socket, (const struct sockaddr *) &Tests[2].Addr, sizeof(Tests[2].Addr));
|
||||
ok(Error == SOCKET_ERROR && WSAGetLastError() == WSAEINVAL, "Unexpected result %d expected %d and wsa result %d expected %ld for double bind test\n", Error, SOCKET_ERROR, WSAGetLastError(), WSAEINVAL);
|
||||
}
|
||||
Error = closesocket(Socket);
|
||||
ok(Error == 0, "Unexpected error %d %d on closesocket for double bind test\n", Error, WSAGetLastError());
|
||||
/* Check SO_BROADCAST and bind to broadcast address */
|
||||
Socket = socket(AF_INET, Tests[10].Type, Tests[10].Proto);
|
||||
ok(Socket != INVALID_SOCKET, "Failed to create socket with error %d for broadcast test, next tests might be wrong\n", WSAGetLastError());
|
||||
Error = setsockopt(Socket, SOL_SOCKET, SO_BROADCAST, (const char *) &Broadcast, sizeof(Broadcast));
|
||||
ok(Error == 0, "Unexpected error %d %d on setsockopt for broadcast test\n", Error, WSAGetLastError());
|
||||
Error = bind(Socket, (const struct sockaddr *) &Tests[10].Addr, sizeof(Tests[10].Addr));
|
||||
ok(Error == 0, "Unexpected error %d %d on bind for broadcast test\n", Error, WSAGetLastError());
|
||||
Error = closesocket(Socket);
|
||||
ok(Error == 0, "Unexpected error %d %d on closesocket for broadcast test\n", Error, WSAGetLastError());
|
||||
}
|
||||
|
||||
START_TEST(bind)
|
||||
{
|
||||
WSADATA WsaData;
|
||||
int Error;
|
||||
CHAR LocalHostName[128];
|
||||
struct hostent *Hostent;
|
||||
IN_ADDR Address;
|
||||
SOCKET Socket;
|
||||
struct sockaddr_in Addr = { AF_INET };
|
||||
|
||||
/* not yet initialized */
|
||||
StartSeh()
|
||||
Error = bind(INVALID_SOCKET, NULL, 0);
|
||||
ok_dec(Error, -1);
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
StartSeh()
|
||||
Error = bind(INVALID_SOCKET, InvalidPointer, 0);
|
||||
ok_dec(Error, -1);
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
|
||||
Error = WSAStartup(MAKEWORD(2, 2), &WsaData);
|
||||
ok_dec(Error, 0);
|
||||
|
||||
/* initialize LocalAddress for tests */
|
||||
Error = gethostname(LocalHostName, sizeof(LocalHostName));
|
||||
ok_dec(Error, 0);
|
||||
ok_dec(WSAGetLastError(), 0);
|
||||
trace("Local host name is '%s'\n", LocalHostName);
|
||||
Hostent = gethostbyname(LocalHostName);
|
||||
ok(Hostent != NULL, "gethostbyname failed with %d\n", WSAGetLastError());
|
||||
if (Hostent && Hostent->h_addr_list[0] && Hostent->h_length == sizeof(IN_ADDR))
|
||||
{
|
||||
memcpy(&Address, Hostent->h_addr_list[0], sizeof(Address));
|
||||
strcpy(LocalAddress, inet_ntoa(Address));
|
||||
}
|
||||
trace("Local address is '%s'\n", LocalAddress);
|
||||
ok(LocalAddress[0] != '\0',
|
||||
"Could not determine local address. Following test results may be wrong.\n");
|
||||
|
||||
/* parameter tests */
|
||||
StartSeh()
|
||||
Error = bind(INVALID_SOCKET, NULL, 0);
|
||||
ok_dec(Error, SOCKET_ERROR);
|
||||
ok_dec(WSAGetLastError(), WSAENOTSOCK);
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
StartSeh()
|
||||
Error = bind(INVALID_SOCKET, InvalidPointer, 0);
|
||||
ok_dec(Error, SOCKET_ERROR);
|
||||
ok_dec(WSAGetLastError(), WSAENOTSOCK);
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
StartSeh()
|
||||
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
Error = bind(Socket, NULL, 0);
|
||||
ok_dec(Error, SOCKET_ERROR);
|
||||
ok_dec(WSAGetLastError(), WSAEFAULT);
|
||||
closesocket(Socket);
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
StartSeh()
|
||||
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
Error = bind(Socket, InvalidPointer, 0);
|
||||
ok_dec(Error, SOCKET_ERROR);
|
||||
ok_dec(WSAGetLastError(), WSAEFAULT);
|
||||
closesocket(Socket);
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
StartSeh()
|
||||
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
Error = bind(Socket, NULL, sizeof(Addr));
|
||||
ok_dec(Error, SOCKET_ERROR);
|
||||
ok_dec(WSAGetLastError(), WSAEFAULT);
|
||||
closesocket(Socket);
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
StartSeh()
|
||||
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
Error = bind(Socket, InvalidPointer, sizeof(Addr));
|
||||
ok_dec(Error, SOCKET_ERROR);
|
||||
ok_dec(WSAGetLastError(), WSAEFAULT);
|
||||
closesocket(Socket);
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
StartSeh()
|
||||
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
Error = bind(Socket, (const struct sockaddr *) &Addr, 0);
|
||||
ok_dec(Error, SOCKET_ERROR);
|
||||
ok_dec(WSAGetLastError(), WSAEFAULT);
|
||||
closesocket(Socket);
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
StartSeh()
|
||||
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
Error = bind(Socket, (const struct sockaddr *) &Addr, sizeof(Addr)-1);
|
||||
ok_dec(Error, SOCKET_ERROR);
|
||||
ok_dec(WSAGetLastError(), WSAEFAULT);
|
||||
closesocket(Socket);
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
|
||||
TestBind(Address);
|
||||
/* TODO: test IPv6 */
|
||||
|
||||
Error = WSACleanup();
|
||||
ok_dec(Error, 0);
|
||||
}
|
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* PROJECT: ReactOS api tests
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* PURPOSE: Test for WSASocket
|
||||
* PROGRAMMERS: Peter Hater
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ntstatus.h>
|
||||
#include <wine/winternl.h>
|
||||
#include "ws2_32.h"
|
||||
|
||||
void Test_CloseDuplicatedSocket()
|
||||
{
|
||||
char szBuf[10];
|
||||
int err;
|
||||
SOCKET sck, dup_sck;
|
||||
WSAPROTOCOL_INFOW ProtocolInfo;
|
||||
struct sockaddr_in to = { AF_INET, 2222, {{{ 0x7f, 0x00, 0x00, 0x01 }}} };
|
||||
|
||||
/* Create the socket */
|
||||
sck = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if(sck == INVALID_SOCKET)
|
||||
{
|
||||
skip("socket failed %d. Aborting test.\n", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
err = sendto(sck, szBuf, _countof(szBuf), 0, (struct sockaddr *)&to, sizeof(to));
|
||||
ok(err == _countof(szBuf), "sendto err = %d %d\n", err, WSAGetLastError());
|
||||
|
||||
err = WSADuplicateSocketW(sck, GetCurrentProcessId(), &ProtocolInfo);
|
||||
ok(err == 0, "WSADuplicateSocketW err = %d %d\n", err, WSAGetLastError());
|
||||
|
||||
dup_sck = WSASocketW(0, 0, 0, &ProtocolInfo, 0, 0);
|
||||
if (dup_sck == INVALID_SOCKET)
|
||||
{
|
||||
skip("WSASocketW failed %d. Aborting test.\n", WSAGetLastError());
|
||||
closesocket(sck);
|
||||
return;
|
||||
}
|
||||
|
||||
err = sendto(dup_sck, szBuf, _countof(szBuf), 0, (struct sockaddr *)&to, sizeof(to));
|
||||
ok(err == _countof(szBuf), "sendto err = %d %d\n", err, WSAGetLastError());
|
||||
|
||||
err = closesocket(sck);
|
||||
ok(err == 0, "closesocket sck err = %d %d\n", err, WSAGetLastError());
|
||||
|
||||
err = sendto(dup_sck, szBuf, _countof(szBuf), 0, (struct sockaddr *)&to, sizeof(to));
|
||||
ok(err == _countof(szBuf), "sendto err = %d %d\n", err, WSAGetLastError());
|
||||
|
||||
err = closesocket(dup_sck);
|
||||
ok(err == 0, "closesocket dup_sck err = %d %d\n", err, WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// 100 ms
|
||||
#define TIMEOUT_SEC 0
|
||||
#define TIMEOUT_USEC 100000
|
||||
|
||||
// 250 ms
|
||||
#define TIME_SLEEP1 250
|
||||
|
||||
#define THREAD_PROC_LOOPS 5
|
||||
|
||||
#define LISTEN_PORT 22222
|
||||
#define LISTEN_BACKLOG 5
|
||||
|
||||
DWORD WINAPI thread_proc(void* param)
|
||||
{
|
||||
fd_set read, write, except;
|
||||
struct timeval tval;
|
||||
SOCKET sock = (SOCKET)param;
|
||||
int i;
|
||||
|
||||
tval.tv_sec = TIMEOUT_SEC;
|
||||
tval.tv_usec = TIMEOUT_USEC;
|
||||
|
||||
for (i = 0; i < THREAD_PROC_LOOPS; ++i)
|
||||
{
|
||||
FD_ZERO(&read); FD_ZERO(&write); FD_ZERO(&except);
|
||||
// write will be empty
|
||||
FD_SET(sock, &read); FD_SET(sock, &except);
|
||||
|
||||
select(0, &read, &write, &except, &tval);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Test_CloseWhileSelectSameSocket()
|
||||
{
|
||||
int err;
|
||||
SOCKET sock;
|
||||
struct sockaddr_in addrin;
|
||||
HANDLE hthread;
|
||||
|
||||
/* Create the socket */
|
||||
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (sock == INVALID_SOCKET)
|
||||
{
|
||||
skip("socket failed %d. Aborting test.\n", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&addrin, 0, sizeof(struct sockaddr_in));
|
||||
addrin.sin_family = AF_INET;
|
||||
addrin.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
addrin.sin_port = htons(LISTEN_PORT);
|
||||
|
||||
err = bind(sock, (struct sockaddr*)(&addrin), sizeof(struct sockaddr_in));
|
||||
ok(err == 0, "bind err = %d %d\n", err, WSAGetLastError());
|
||||
err = listen(sock, LISTEN_BACKLOG);
|
||||
ok(err == 0, "listen err = %d %d\n", err, WSAGetLastError());
|
||||
|
||||
hthread = CreateThread(NULL, 0, thread_proc, (void*)sock, 0, NULL);
|
||||
ok(hthread != NULL, "CreateThread %ld\n", GetLastError());
|
||||
|
||||
Sleep(TIME_SLEEP1);
|
||||
err = closesocket(sock);
|
||||
ok(err == 0, "closesocket err = %d %d\n", err, WSAGetLastError());
|
||||
|
||||
WaitForSingleObject(hthread, INFINITE);
|
||||
CloseHandle(hthread);
|
||||
return;
|
||||
}
|
||||
|
||||
void Test_CloseWhileSelectDuplicatedSocket()
|
||||
{
|
||||
int err;
|
||||
SOCKET sock, dup_sock;
|
||||
WSAPROTOCOL_INFOW ProtocolInfo;
|
||||
struct sockaddr_in addrin;
|
||||
HANDLE hthread;
|
||||
|
||||
/* Create the socket */
|
||||
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (sock == INVALID_SOCKET)
|
||||
{
|
||||
skip("socket failed %d. Aborting test.\n", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&addrin, 0, sizeof(struct sockaddr_in));
|
||||
addrin.sin_family = AF_INET;
|
||||
addrin.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
addrin.sin_port = htons(LISTEN_PORT);
|
||||
|
||||
err = bind(sock, (struct sockaddr*)(&addrin), sizeof(struct sockaddr_in));
|
||||
ok(err == 0, "bind err = %d %d\n", err, WSAGetLastError());
|
||||
err = listen(sock, LISTEN_BACKLOG);
|
||||
ok(err == 0, "listen err = %d %d\n", err, WSAGetLastError());
|
||||
|
||||
err = WSADuplicateSocketW(sock, GetCurrentProcessId(), &ProtocolInfo);
|
||||
ok(err == 0, "WSADuplicateSocketW err = %d %d\n", err, WSAGetLastError());
|
||||
|
||||
dup_sock = WSASocketW(0, 0, 0, &ProtocolInfo, 0, 0);
|
||||
if (dup_sock == INVALID_SOCKET)
|
||||
{
|
||||
skip("WSASocketW failed %d. Aborting test.\n", WSAGetLastError());
|
||||
closesocket(sock);
|
||||
return;
|
||||
}
|
||||
|
||||
hthread = CreateThread(NULL, 0, thread_proc, (void*)dup_sock, 0, NULL);
|
||||
ok(hthread != NULL, "CreateThread %ld\n", GetLastError());
|
||||
|
||||
err = closesocket(sock);
|
||||
ok(err == 0, "closesocket err = %d %d\n", err, WSAGetLastError());
|
||||
|
||||
Sleep(TIME_SLEEP1);
|
||||
err = closesocket(dup_sock);
|
||||
ok(err == 0, "closesocket err = %d %d\n", err, WSAGetLastError());
|
||||
|
||||
WaitForSingleObject(hthread, INFINITE);
|
||||
CloseHandle(hthread);
|
||||
return;
|
||||
}
|
||||
|
||||
START_TEST(close)
|
||||
{
|
||||
int err;
|
||||
WSADATA wdata;
|
||||
|
||||
/* Start up Winsock */
|
||||
err = WSAStartup(MAKEWORD(2, 2), &wdata);
|
||||
ok(err == 0, "WSAStartup failed, iResult == %d %d\n", err, WSAGetLastError());
|
||||
|
||||
Test_CloseDuplicatedSocket();
|
||||
Test_CloseWhileSelectSameSocket();
|
||||
Test_CloseWhileSelectDuplicatedSocket();
|
||||
|
||||
WSACleanup();
|
||||
}
|
||||
|
@@ -3,8 +3,6 @@
|
||||
#define STANDALONE
|
||||
#include <apitest.h>
|
||||
|
||||
extern void func_bind(void);
|
||||
extern void func_close(void);
|
||||
extern void func_getaddrinfo(void);
|
||||
extern void func_getnameinfo(void);
|
||||
extern void func_getservbyname(void);
|
||||
@@ -21,8 +19,6 @@ extern void func_WSAStartup(void);
|
||||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "bind", func_bind },
|
||||
{ "close", func_close },
|
||||
{ "getaddrinfo", func_getaddrinfo },
|
||||
{ "getnameinfo", func_getnameinfo },
|
||||
{ "getservbyname", func_getservbyname },
|
||||
|
@@ -5,7 +5,6 @@ include_directories(include)
|
||||
# subdirectories containing special-purpose drivers
|
||||
#
|
||||
add_subdirectory(example)
|
||||
add_subdirectory(hidparse)
|
||||
add_subdirectory(kernel32)
|
||||
add_subdirectory(ntos_cc)
|
||||
add_subdirectory(ntos_io)
|
||||
@@ -124,13 +123,11 @@ list(APPEND KMTEST_SOURCE
|
||||
kmtest/testlist.c
|
||||
|
||||
example/Example_user.c
|
||||
hidparse/HidP_user.c
|
||||
kernel32/FindFile_user.c
|
||||
ntos_cc/CcCopyRead_user.c
|
||||
ntos_io/IoCreateFile_user.c
|
||||
ntos_io/IoDeviceObject_user.c
|
||||
ntos_io/IoReadWrite_user.c
|
||||
ntos_mm/MmMapLockedPagesSpecifyCache_user.c
|
||||
ntos_mm/NtCreateSection_user.c
|
||||
ntos_po/PoIrp_user.c
|
||||
tcpip/TcpIp_user.c
|
||||
@@ -156,12 +153,10 @@ add_dependencies(kmtest_drivers
|
||||
kmtest_drv
|
||||
example_drv
|
||||
findfile_drv
|
||||
hidp_drv
|
||||
iocreatefile_drv
|
||||
iodeviceobject_drv
|
||||
iohelper_drv
|
||||
ioreadwrite_drv
|
||||
mmmaplockedpagesspecifycache_drv
|
||||
ntcreatesection_drv
|
||||
poirp_drv
|
||||
tcpip_drv
|
||||
|
@@ -1,18 +0,0 @@
|
||||
|
||||
include_directories(../include)
|
||||
|
||||
#
|
||||
# HidP
|
||||
#
|
||||
list(APPEND HIDP_DRV_SOURCE
|
||||
../kmtest_drv/kmtest_standalone.c
|
||||
HidP_drv.c
|
||||
HidPDescription.c)
|
||||
|
||||
add_library(hidp_drv SHARED ${HIDP_DRV_SOURCE})
|
||||
set_module_type(hidp_drv kernelmodedriver)
|
||||
target_link_libraries(hidp_drv kmtest_printf ${PSEH_LIB})
|
||||
add_importlibs(hidp_drv hidparse ntoskrnl hal)
|
||||
add_target_compile_definitions(hidp_drv KMT_STANDALONE_DRIVER)
|
||||
#add_pch(hidp_drv ../include/kmt_test.h)
|
||||
add_rostests_file(TARGET hidp_drv)
|