Compare commits

...

34 Commits

Author SHA1 Message Date
Shriraj Sawant
3c6def4711 [STOBJECT]
-Documented the required functions and modules.
-Minor cleanup.

svn path=/branches/GSoC_2017/shellext/; revision=75690
2017-08-27 11:45:46 +00:00
Shriraj Sawant
e040b84aa6 [QCKLNCH]
-Documented the required functions and modules.
-Minor cleanup.

svn path=/branches/GSoC_2017/shellext/; revision=75689
2017-08-27 11:42:54 +00:00
Shriraj Sawant
76cb54455c [QCKLNCH]
-Minor adjustments.
-Made the quick launch toolbar align towards left by default, just like windows.

svn path=/branches/GSoC_2017/shellext/; revision=75642
2017-08-22 15:02:42 +00:00
Shriraj Sawant
51cda605ff [STOBJECT]
-Added the proper enumeration filters required for safely removable devices a.k.a hotplug module.
-Minor cleanup.

svn path=/branches/GSoC_2017/shellext/; revision=75641
2017-08-22 14:59:03 +00:00
Shriraj Sawant
dd524eab21 [STOBJECT]
-Added Balloon notification for safely removal icon.
-Added familiar warning dialog when device ejection fails.
-Figured out that 'Problem number' of a device is perhaps an important enumeration filter.
-Minor code cleanup and whitespace fixes.
-Test in win xpvm looks fine, but needs further testing.

svn path=/branches/GSoC_2017/shellext/; revision=75546
2017-08-14 18:29:44 +00:00
Shriraj Sawant
93a5cfc0ef [STOBJECT]
-Added new battery icons and hotplug icons, thanks to Pi_User5.
-Modified resources for the same.
-Modified CSysTray to support icon hiding feature.
-Modified hotplug.cpp by adding experimental enumeration to test icon behavior.
-Icon behavior successfully tested.
-Added code to eject device, works fine.
-Fixed a bug which didn't showed attached devices after reloading. (like after system restart or explorer restart.)
-Now at least pen-drives are safely removable. (Still experimental though, use at your own risk ;P)
-Tested in winxp vm, needs further testing.

svn path=/branches/GSoC_2017/shellext/; revision=75497
2017-08-06 16:33:27 +00:00
Shriraj Sawant
b421d735af [STOBJECT]
-Added hotplug.cpp for handling removable devices notification icon.
-Modified CMakeLists.txt et al to plugin this hotplug to stobject.
-Added basic code to test the hotplug icon and integrate it with stobject.
-Tested in xpvm, needs further testing.

svn path=/branches/GSoC_2017/shellext/; revision=75431
2017-07-28 17:33:38 +00:00
Shriraj Sawant
d13b13ec76 [STOBJECT]
-Fixed bugs related to strings and localization (needs further improvement).
-Fixed ContextMenu Position bug (for both power and volume).
-Now battery tooltip is as dynamic as its icon.

svn path=/branches/GSoC_2017/shellext/; revision=75405
2017-07-25 21:48:51 +00:00
Shriraj Sawant
287232ea2f [STOBJECT]
-Added support for battery enumeration.
-Now battery status is available.
-Added icons and resources respectively for battery levels.
-Now battery changes its icons dynamically as per its quantized levels.

svn path=/branches/GSoC_2017/shellext/; revision=75367
2017-07-17 19:43:53 +00:00
Shriraj Sawant
e0959b80b1 [QCKLNCH]
-Fixed a memory leak issue.
-Apparently Tested in xpvm.
-Needs further testing.

svn path=/branches/GSoC_2017/shellext/; revision=75299
2017-07-07 16:38:37 +00:00
Shriraj Sawant
bbf1ae346a [QCKLNCH]
-Apparently fixed some memory leaks. 
-Removed unnecessary methods.
-Fixed a checkmark bug. :p
-And thus finished any remaining issues of CR-122.

CR-122 (https://code.reactos.org/cru/CR-122#details)

PS: Please raise any other issues which you feel needs correction. I am waiting... ;D

svn path=/branches/GSoC_2017/shellext/; revision=75298
2017-07-07 16:13:47 +00:00
Shriraj Sawant
fe273d3531 [QCKLNCH]
-Removed CWindowImpl
-Added CWindow
-Used OnWinEvent() instead of subclassing
-Handled WM_COMMAND and WM_NOTIFY as needed
-Now along with buttons chevron menu is also working

CR-122 (https://code.reactos.org/cru/CR-122#details)

PS: Thank you everyone for spending your time and giving a thorough review. :)

svn path=/branches/GSoC_2017/shellext/; revision=75297
2017-07-07 14:53:11 +00:00
Shriraj Sawant
c8c4bcfa52 [QCKLNCH]
-Added en-US.rc
-Localized Menu resource.
-Added a string table and localized some strings.
-Major fixes like removing IDeskBar.
-Minor suggestions fixed.

CR-122 (https://code.reactos.org/cru/CR-122#details)

PS: Thank you everyone for spending your time and giving a thorough review. :)

svn path=/branches/GSoC_2017/shellext/; revision=75276
2017-07-04 18:37:00 +00:00
Shriraj Sawant
180321d87a [QCKLNCH]
-Refactors and some code fixes (like CComHeapPtr, IID_PPV_ARG, _countof, etc.).
-Minor suggestions fixed.

CR-122 (https://code.reactos.org/cru/CR-122#details)

SelfNote: Should check if CComHeapPtr is overused! ;p

svn path=/branches/GSoC_2017/shellext/; revision=75272
2017-07-03 15:36:00 +00:00
Shriraj Sawant
26958e704b [QCKLNCH]
-Whitespace fixes
-Minor suggestions fixed.
-Minor refactors and some code fixes.

CR-122 (https://code.reactos.org/cru/CR-122#details)

svn path=/branches/GSoC_2017/shellext/; revision=75260
2017-07-01 20:22:13 +00:00
Shriraj Sawant
8a98b9a578 [QCKLNCH]
-Implemented IContextMenu::InvokeCommand()
-Modified IContextMenu::QueryContextMenu() to support CheckMenuItem()
-Minor code cleanup
-Now Quick Launch Supports the 'show text' and 'view' options.
-Tested on xpvm and ros explorer locally on win10, but needs some thorough testing

svn path=/branches/GSoC_2017/shellext/; revision=75257
2017-07-01 18:34:33 +00:00
Giannis Adamopoulos
9e52604cad * Sync up to trunk HEAD (r75230).
svn path=/branches/GSoC_2017/shellext/; revision=75232
2017-06-29 14:12:11 +00:00
Shriraj Sawant
5809f6ada6 [QCKLNCH]
-Created menu resource in qcklnch.rc
-Added resource.h to manage menu resources and all.
-Added IContextMenu.
-Implemented QueryContextMenu and stubbed other methods.
-Handled WM_RBUTTONUP for folder context menus.
-Minor code corrections.
-Tested working of some menu functions in winXP VM, though further testing is required.

svn path=/branches/GSoC_2017/shellext/; revision=75231
2017-06-29 12:23:13 +00:00
Shriraj Sawant
8c802b5ece [QCKLNCH]
-Added CWindowImpl for proper subclassing.
-Now buttons are alive \0/.
-Code Cleanup.

svn path=/branches/GSoC_2017/shellext/; revision=75198
2017-06-25 20:20:27 +00:00
Shriraj Sawant
02f6a567fa [QCKLNCH]
-Added Browse Folder Interface (under test).
-Now buttons can show respective icons.
-Minor code cleanup.

svn path=/branches/GSoC_2017/shellext/; revision=75174
2017-06-23 20:05:01 +00:00
Shriraj Sawant
ba53ff00eb [QCKLNCH]
-Added IShellFolderBand and stubbed its methods.
-Implemented InitializeSFB.
-Tested enumeration of IShellFolder within CISFBand.

svn path=/branches/GSoC_2017/shellext/; revision=75169
2017-06-23 13:44:28 +00:00
Shriraj Sawant
aa5d11c9c2 [QCKLNCH]
-Added a sample toolbar.
-Tested via CISFBand.

svn path=/branches/GSoC_2017/shellext/; revision=75137
2017-06-19 19:19:10 +00:00
Shriraj Sawant
2613fc122b [QCKLNCH]
-Stubbed CISFBand methods and required interfaces.
-Added a C Constructor for CISFBand.
-Implemented and Tested a button via CISFBand.

svn path=/branches/GSoC_2017/shellext/; revision=75095
2017-06-18 14:59:26 +00:00
Shriraj Sawant
f6af139f35 [QCKLNCH]
-Added CISFBand.h and CISFBand.cpp
-Adjusted CMakeLists.txt
-Other adjustment to start implementing own CISFBand for quick launch.

svn path=/branches/GSoC_2017/shellext/; revision=75074
2017-06-17 15:28:17 +00:00
Shriraj Sawant
96612d92b8 {QCKLNCH]
-Successfully added CISFBand to CQuickLaunchBand.
-Forwarded methods exported by CISFBand to CQuickLaunchBand.

svn path=/branches/GSoC_2017/shellext/; revision=75050
2017-06-15 17:07:22 +00:00
Shriraj Sawant
abfd95f82e [QCKLNCH]
-Tested CISFband in FinalConstruct.
-Performed Clean up on whitespace issues.

svn path=/branches/GSoC_2017/shellext/; revision=75036
2017-06-14 12:58:12 +00:00
Giannis Adamopoulos
a34b262695 [PSDK] -Add IShellFolderBand and IFolderBandPriv interfaces.
svn path=/branches/GSoC_2017/shellext/; revision=75025
2017-06-13 15:00:50 +00:00
Giannis Adamopoulos
e53d4a63ce [PSDK] -Add CLSID_ISFBand, IID_IShellFolderBand and IID_IFolderBandPriv.
svn path=/branches/GSoC_2017/shellext/; revision=75023
2017-06-13 13:56:11 +00:00
Shriraj Sawant
f6e5c08bc6 [QCKLNCH]
-Subclassed button handler to test button click.
-Minor code cleanup. 

svn path=/branches/GSoC_2017/shellext/; revision=74988
2017-06-10 20:54:00 +00:00
Shriraj Sawant
16ddc047d9 [QCKLNCH]
-Created a sample button to test toolbar area.
-Added qcklnch.dll entry in syssetup.inf file for registration.

svn path=/branches/GSoC_2017/shellext/; revision=74961
2017-06-08 15:18:21 +00:00
Shriraj Sawant
48c992a2c2 [QCKLNCH]
-Added .rgs script and other files to facilitate component registration.

svn path=/branches/GSoC_2017/shellext/; revision=74915
2017-06-04 17:33:06 +00:00
Shriraj Sawant
e77b6e64ca [QCKLNCH]
-Added CQuickLaunchBand
-Exposed required Interfaces
-Stubbed the methods

svn path=/branches/GSoC_2017/shellext/; revision=74899
2017-06-04 09:56:54 +00:00
Shriraj Sawant
b1b599d5d9 GSoC_Project: TSE (Taskbar Shell Extension)
[qcklnch]
-Added basic files for coding.
-Made changes in corresponding CMakeLists.txt.

svn path=/branches/GSoC_2017/shellext/; revision=74722
2017-05-31 12:08:03 +00:00
Shriraj Sawant
5489577226 GSoC_Project: TSE (Taskbar Shell Extension)
Test Commit 1.

Added folder to create my project files within.

svn path=/branches/GSoC_2017/shellext/; revision=74721
2017-05-31 11:17:43 +00:00
269 changed files with 6659 additions and 24794 deletions

View File

@@ -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)

View File

View 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);
}

View 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);

View 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)

View 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);
}

View 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()
};

View 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

View 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"

View 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();
}

View 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

View File

@@ -0,0 +1,4 @@
@ stdcall -private DllCanUnloadNow()
@ stdcall -private DllGetClassObject(ptr ptr ptr)
@ stdcall -private DllRegisterServer()
@ stdcall -private DllUnregisterServer()

View 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

View File

@@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {260CB95D-4544-44F6-A079-575BAA60B72F} = s 'Quick Launch'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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; }

View 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;
}

View File

@@ -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"

View File

@@ -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:

View File

@@ -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);

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -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"

View File

@@ -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)

View File

@@ -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);

View File

@@ -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

View File

@@ -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 */

View File

@@ -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
*/

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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)

View File

@@ -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)

View File

@@ -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);

View File

@@ -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)

View File

@@ -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");

View File

@@ -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

View File

@@ -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;

View File

@@ -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");

File diff suppressed because it is too large Load Diff

View File

@@ -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());

View File

@@ -1,2 +0,0 @@
101 RCDATA "testdb.sdb"

View File

@@ -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>

View File

@@ -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 }
};

View File

@@ -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
{

View File

@@ -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")

View File

@@ -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>

View File

@@ -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 }
};

View File

@@ -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);
}
}
}

View File

@@ -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,
},
},
},

View File

@@ -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

View File

@@ -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);

View File

@@ -6,9 +6,7 @@ typedef enum _MSG_TYPE
SENT,
POST,
HOOK,
EVENT,
SENT_RET,
MARKER
EVENT
} MSG_TYPE;
typedef struct _MSG_ENTRY

View File

@@ -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

View File

@@ -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)));
}

View File

@@ -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);
}
}
}

View File

@@ -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 },

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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 }
};

View File

@@ -10,7 +10,6 @@ list(APPEND SOURCE
NtCreateThread.c
NtDeleteKey.c
NtFreeVirtualMemory.c
NtLoadUnloadKey.c
NtMapViewOfSection.c
NtMutant.c
NtOpenProcessToken.c

View File

@@ -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);
}

View File

@@ -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();
}

View File

@@ -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 },

View File

@@ -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 )

View File

@@ -13,7 +13,6 @@ add_executable(shell32_apitest
CShellDesktop.cpp
CShellLink.cpp
menu.cpp
PathResolve.cpp
ShellExecuteEx.cpp
shelltest.cpp
SHParseDisplayName.cpp

View File

@@ -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;
}

View File

@@ -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 }

View File

@@ -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)

View File

@@ -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();
}

View File

@@ -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 },

View File

@@ -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();
}

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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);

View File

@@ -4,7 +4,6 @@ list(APPEND SOURCE
EnumPrinters.c
EnumPrintProcessorDatatypes.c
GetDefaultPrinter.c
GetPrinterData.c
GetPrintProcessorDirectory.c
IsValidDevmode.c
OpenPrinter.c

View File

@@ -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);
}

View File

@@ -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 },

View File

@@ -1,7 +1,5 @@
list(APPEND SOURCE
bind.c
close.c
getaddrinfo.c
getnameinfo.c
getservbyname.c

View File

@@ -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);
}

View File

@@ -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();
}

View File

@@ -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 },

View File

@@ -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

View File

@@ -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)

Some files were not shown because too many files have changed in this diff Show More