diff --git a/rostests/apitests/w32kdll/w32kdll_2k3sp2/w32k_2k3sp2-x86.db b/rostests/apitests/w32kdll/w32kdll_2k3sp2/w32k_2k3sp2-x86.db new file mode 100644 index 00000000000..8808dec397f --- /dev/null +++ b/rostests/apitests/w32kdll/w32kdll_2k3sp2/w32k_2k3sp2-x86.db @@ -0,0 +1,668 @@ +# +# win32k systemcalls taken from Windows 2003 SP2 x86 +# +NtGdiAbortDoc 1 +NtGdiAbortPath 1 +NtGdiAddFontResourceW 6 +NtGdiAddRemoteFontToDC 4 +NtGdiAddFontMemResourceEx 5 +NtGdiRemoveMergeFont 2 +NtGdiAddRemoteMMInstanceToDC 3 +NtGdiAlphaBlend 12 +NtGdiAngleArc 6 +NtGdiAnyLinkedFonts 0 +NtGdiFontIsLinked 1 +NtGdiArcInternal 10 +NtGdiBeginPath 1 +NtGdiBitBlt 11 +NtGdiCancelDC 1 +NtGdiCheckBitmapBits 8 +NtGdiCloseFigure 1 +NtGdiClearBitmapAttributes 2 +NtGdiClearBrushAttributes 2 +NtGdiColorCorrectPalette 6 +NtGdiCombineRgn 4 +NtGdiCombineTransform 3 +NtGdiComputeXformCoefficients 1 +NtGdiConsoleTextOut 4 +NtGdiConvertMetafileRect 2 +NtGdiCreateBitmap 5 +NtGdiCreateClientObj 1 +NtGdiCreateColorSpace 1 +NtGdiCreateColorTransform 8 +NtGdiCreateCompatibleBitmap 3 +NtGdiCreateCompatibleDC 1 +NtGdiCreateDIBBrush 6 +NtGdiCreateDIBitmapInternal 11 +NtGdiCreateDIBSection 9 +NtGdiCreateEllipticRgn 4 +NtGdiCreateHalftonePalette 1 +NtGdiCreateHatchBrushInternal 3 +NtGdiCreateMetafileDC 1 +NtGdiCreatePaletteInternal 2 +NtGdiCreatePatternBrushInternal 3 +NtGdiCreatePen 4 +NtGdiCreateRectRgn 4 +NtGdiCreateRoundRectRgn 6 +NtGdiCreateServerMetaFile 6 +NtGdiCreateSolidBrush 2 +NtGdiD3dContextCreate 4 +NtGdiD3dContextDestroy 1 +NtGdiD3dContextDestroyAll 1 +NtGdiD3dValidateTextureStageState 1 +NtGdiD3dDrawPrimitives2 7 +NtGdiDdGetDriverState 1 +NtGdiDdAddAttachedSurface 3 +NtGdiDdAlphaBlt 3 +NtGdiDdAttachSurface 2 +NtGdiDdBeginMoCompFrame 2 +NtGdiDdBlt 3 +NtGdiDdCanCreateSurface 2 +NtGdiDdCanCreateD3DBuffer 2 +NtGdiDdColorControl 2 +NtGdiDdCreateDirectDrawObject 1 +NtGdiDdCreateSurface 8 +NtGdiDdCreateD3DBuffer 8 +NtGdiDdCreateMoComp 2 +NtGdiDdCreateSurfaceObject 6 +NtGdiDdDeleteDirectDrawObject 1 +NtGdiDdDeleteSurfaceObject 1 +NtGdiDdDestroyMoComp 2 +NtGdiDdDestroySurface 2 +NtGdiDdDestroyD3DBuffer 1 +NtGdiDdEndMoCompFrame 2 +NtGdiDdFlip 5 +NtGdiDdFlipToGDISurface 2 +NtGdiDdGetAvailDriverMemory 2 +NtGdiDdGetBltStatus 2 +NtGdiDdGetDC 2 +NtGdiDdGetDriverInfo 2 +NtGdiDdGetDxHandle 3 +NtGdiDdGetFlipStatus 2 +NtGdiDdGetInternalMoCompInfo 2 +NtGdiDdGetMoCompBuffInfo 2 +NtGdiDdGetMoCompGuids 2 +NtGdiDdGetMoCompFormats 2 +NtGdiDdGetScanLine 2 +NtGdiDdLock 3 +NtGdiDdLockD3D 2 +NtGdiDdQueryDirectDrawObject 11 +NtGdiDdQueryMoCompStatus 2 +NtGdiDdReenableDirectDrawObject 2 +NtGdiDdReleaseDC 1 +NtGdiDdRenderMoComp 2 +NtGdiDdResetVisrgn 2 +NtGdiDdSetColorKey 2 +NtGdiDdSetExclusiveMode 2 +NtGdiDdSetGammaRamp 3 +NtGdiDdCreateSurfaceEx 3 +NtGdiDdSetOverlayPosition 3 +NtGdiDdUnattachSurface 2 +NtGdiDdUnlock 2 +NtGdiDdUnlockD3D 2 +NtGdiDdUpdateOverlay 3 +NtGdiDdWaitForVerticalBlank 2 +NtGdiDvpCanCreateVideoPort 2 +NtGdiDvpColorControl 2 +NtGdiDvpCreateVideoPort 2 +NtGdiDvpDestroyVideoPort 2 +NtGdiDvpFlipVideoPort 4 +NtGdiDvpGetVideoPortBandwidth 2 +NtGdiDvpGetVideoPortField 2 +NtGdiDvpGetVideoPortFlipStatus 2 +NtGdiDvpGetVideoPortInputFormats 2 +NtGdiDvpGetVideoPortLine 2 +NtGdiDvpGetVideoPortOutputFormats 2 +NtGdiDvpGetVideoPortConnectInfo 2 +NtGdiDvpGetVideoSignalStatus 2 +NtGdiDvpUpdateVideoPort 4 +NtGdiDvpWaitForVideoPortSync 2 +NtGdiDvpAcquireNotification 3 +NtGdiDvpReleaseNotification 2 +NtGdiDxgGenericThunk 6 +NtGdiDeleteClientObj 1 +NtGdiDeleteColorSpace 1 +NtGdiDeleteColorTransform 2 +NtGdiDeleteObjectApp 1 +NtGdiDescribePixelFormat 4 +NtGdiGetPerBandInfo 2 +NtGdiDoBanding 4 +NtGdiDoPalette 6 +NtGdiDrawEscape 4 +NtGdiEllipse 5 +NtGdiEnableEudc 1 +NtGdiEndDoc 1 +NtGdiEndPage 1 +NtGdiEndPath 1 +NtGdiEnumFontChunk 5 +NtGdiEnumFontClose 1 +NtGdiEnumFontOpen 7 +NtGdiEnumObjects 4 +NtGdiEqualRgn 2 +NtGdiEudcLoadUnloadLink 7 +NtGdiExcludeClipRect 5 +NtGdiExtCreatePen 11 +NtGdiExtCreateRegion 3 +NtGdiExtEscape 8 +NtGdiExtFloodFill 5 +NtGdiExtGetObjectW 3 +NtGdiExtSelectClipRgn 3 +NtGdiExtTextOutW 9 +NtGdiFillPath 1 +NtGdiFillRgn 3 +NtGdiFlattenPath 1 +NtGdiFlush 0 +NtGdiForceUFIMapping 2 +NtGdiFrameRgn 5 +NtGdiFullscreenControl 5 +NtGdiGetAndSetDCDword 4 +NtGdiGetAppClipBox 2 +NtGdiGetBitmapBits 3 +NtGdiGetBitmapDimension 2 +NtGdiGetBoundsRect 3 +NtGdiGetCharABCWidthsW 6 +NtGdiGetCharacterPlacementW 6 +NtGdiGetCharSet 1 +NtGdiGetCharWidthW 6 +NtGdiGetCharWidthInfo 2 +NtGdiGetColorAdjustment 2 +NtGdiGetColorSpaceforBitmap 1 +NtGdiGetDCDword 3 +NtGdiGetDCforBitmap 1 +NtGdiGetDCObject 2 +NtGdiGetDCPoint 3 +NtGdiGetDeviceCaps 2 +NtGdiGetDeviceGammaRamp 2 +NtGdiGetDeviceCapsAll 2 +NtGdiGetDIBitsInternal 9 +NtGdiGetETM 2 +NtGdiGetEudcTimeStampEx 3 +NtGdiGetFontData 5 +NtGdiGetFontResourceInfoInternalW 7 +NtGdiGetGlyphIndicesW 5 +NtGdiGetGlyphIndicesWInternal 6 +NtGdiGetGlyphOutline 8 +NtGdiGetKerningPairs 3 +NtGdiGetLinkedUFIs 3 +NtGdiGetMiterLimit 2 +NtGdiGetMonitorID 3 +NtGdiGetNearestColor 2 +NtGdiGetNearestPaletteIndex 2 +NtGdiGetObjectBitmapHandle 2 +NtGdiGetOutlineTextMetricsInternalW 4 +NtGdiGetPath 4 +NtGdiGetPixel 3 +NtGdiGetRandomRgn 3 +NtGdiGetRasterizerCaps 2 +NtGdiGetRealizationInfo 3 +NtGdiGetRegionData 3 +NtGdiGetRgnBox 2 +NtGdiGetServerMetaFileBits 7 +NtGdiGetSpoolMessage 4 +NtGdiGetStats 5 +NtGdiGetStockObject 1 +NtGdiGetStringBitmapW 5 +NtGdiGetSystemPaletteUse 1 +NtGdiGetTextCharsetInfo 3 +NtGdiGetTextExtent 5 +NtGdiGetTextExtentExW 8 +NtGdiGetTextFaceW 4 +NtGdiGetTextMetricsW 3 +NtGdiGetTransform 3 +NtGdiGetUFI 6 +NtGdiGetEmbUFI 7 +NtGdiGetUFIPathname 10 +NtGdiGetEmbedFonts 0 +NtGdiChangeGhostFont 2 +NtGdiAddEmbFontToDC 2 +NtGdiGetFontUnicodeRanges 2 +NtGdiGetWidthTable 7 +NtGdiGradientFill 6 +NtGdiHfontCreate 5 +NtGdiIcmBrushInfo 8 +NtGdiInit 0 +NtGdiInitSpool 0 +NtGdiIntersectClipRect 5 +NtGdiInvertRgn 2 +NtGdiLineTo 3 +NtGdiMakeFontDir 5 +NtGdiMakeInfoDC 2 +NtGdiMaskBlt 13 +NtGdiModifyWorldTransform 3 +NtGdiMonoBitmap 1 +NtGdiMoveTo 4 +NtGdiOffsetClipRgn 3 +NtGdiOffsetRgn 3 +NtGdiOpenDCW 7 +NtGdiPatBlt 6 +NtGdiPolyPatBlt 5 +NtGdiPathToRegion 1 +NtGdiPlgBlt 11 +NtGdiPolyDraw 4 +NtGdiPolyPolyDraw 5 +NtGdiPolyTextOutW 4 +NtGdiPtInRegion 3 +NtGdiPtVisible 3 +NtGdiQueryFonts 3 +NtGdiQueryFontAssocInfo 1 +NtGdiRectangle 5 +NtGdiRectInRegion 2 +NtGdiRectVisible 2 +NtGdiRemoveFontResourceW 6 +NtGdiRemoveFontMemResourceEx 1 +NtGdiResetDC 5 +NtGdiResizePalette 2 +NtGdiRestoreDC 2 +NtGdiRoundRect 7 +NtGdiSaveDC 1 +NtGdiScaleViewportExtEx 6 +NtGdiScaleWindowExtEx 6 +GreSelectBitmap 2 +NtGdiSelectBrush 2 +NtGdiSelectClipPath 2 +NtGdiSelectFont 2 +NtGdiSelectPen 2 +NtGdiSetBitmapAttributes 2 +NtGdiSetBitmapBits 3 +NtGdiSetBitmapDimension 4 +NtGdiSetBoundsRect 3 +NtGdiSetBrushAttributes 2 +NtGdiSetBrushOrg 4 +NtGdiSetColorAdjustment 2 +NtGdiSetColorSpace 2 +NtGdiSetDeviceGammaRamp 2 +NtGdiSetDIBitsToDeviceInternal 16 +NtGdiSetFontEnumeration 1 +NtGdiSetFontXform 3 +NtGdiSetIcmMode 3 +NtGdiSetLinkedUFIs 3 +NtGdiSetMagicColors 3 +NtGdiSetMetaRgn 1 +NtGdiSetMiterLimit 3 +NtGdiGetDeviceWidth 1 +NtGdiMirrorWindowOrg 1 +NtGdiSetLayout 3 +NtGdiSetPixel 4 +NtGdiSetPixelFormat 2 +NtGdiSetRectRgn 5 +NtGdiSetSystemPaletteUse 2 +NtGdiSetTextJustification 3 +NtGdiSetupPublicCFONT 3 +NtGdiSetVirtualResolution 5 +NtGdiSetSizeDevice 3 +NtGdiStartDoc 4 +NtGdiStartPage 1 +NtGdiStretchBlt 12 +NtGdiStretchDIBitsInternal 16 +NtGdiStrokeAndFillPath 1 +NtGdiStrokePath 1 +NtGdiSwapBuffers 1 +NtGdiTransformPoints 5 +NtGdiTransparentBlt 11 +NtGdiUnloadPrinterDriver 2 +NtGdiUnmapMemFont 1 +NtGdiUnrealizeObject 1 +NtGdiUpdateColors 1 +NtGdiWidenPath 1 +NtUserActivateKeyboardLayout 2 +NtUserAlterWindowStyle 3 +NtUserAssociateInputContext 3 +NtUserAttachThreadInput 3 +NtUserBeginPaint 2 +NtUserBitBltSysBmp 8 +NtUserBlockInput 1 +NtUserBuildHimcList 4 +NtUserBuildHwndList 7 +NtUserBuildNameList 4 +NtUserBuildPropList 4 +NtUserCallHwnd 2 +NtUserCallHwndLock 2 +NtUserCallHwndOpt 2 +NtUserCallHwndParam 3 +NtUserCallHwndParamLock 3 +NtUserCallMsgFilter 2 +NtUserCallNextHookEx 4 +NtUserCallNoParam 1 +NtUserCallOneParam 2 +NtUserCallTwoParam 3 +NtUserChangeClipboardChain 2 +NtUserChangeDisplaySettings 4 +NtUserCheckImeHotKey 2 +NtUserCheckMenuItem 3 +NtUserChildWindowFromPointEx 4 +NtUserClipCursor 1 +NtUserCloseClipboard 0 +NtUserCloseDesktop 1 +NtUserCloseWindowStation 1 +NtUserConsoleControl 3 +NtUserConvertMemHandle 2 +NtUserCopyAcceleratorTable 3 +NtUserCountClipboardFormats 0 +NtUserCreateAcceleratorTable 2 +NtUserCreateCaret 4 +NtUserCreateDesktop 5 +NtUserCreateInputContext 1 +NtUserCreateLocalMemHandle 4 +NtUserCreateWindowEx 15 +NtUserCreateWindowStation 7 +NtUserDdeGetQualityOfService 3 +NtUserDdeInitialize 5 +NtUserDdeSetQualityOfService 3 +NtUserDeferWindowPos 8 +NtUserDefSetText 2 +NtUserDeleteMenu 3 +NtUserDestroyAcceleratorTable 1 +NtUserDestroyCursor 2 +NtUserDestroyInputContext 1 +NtUserDestroyMenu 1 +NtUserDestroyWindow 1 +NtUserDisableThreadIme 1 +NtUserDispatchMessage 1 +NtUserDragDetect 3 +NtUserDragObject 5 +NtUserDrawAnimatedRects 4 +NtUserDrawCaption 4 +NtUserDrawCaptionTemp 7 +NtUserDrawIconEx 11 +NtUserDrawMenuBarTemp 5 +NtUserEmptyClipboard 0 +NtUserEnableMenuItem 3 +NtUserEnableScrollBar 3 +NtUserEndDeferWindowPosEx 2 +NtUserEndMenu 0 +NtUserEndPaint 2 +NtUserEnumDisplayDevices 4 +NtUserEnumDisplayMonitors 4 +NtUserEnumDisplaySettings 4 +NtUserEvent 1 +NtUserExcludeUpdateRgn 2 +NtUserFillWindow 4 +NtUserFindExistingCursorIcon 3 +NtUserFindWindowEx 5 +NtUserFlashWindowEx 1 +NtUserGetAltTabInfo 6 +NtUserGetAncestor 2 +NtUserGetAppImeLevel 1 +NtUserGetAsyncKeyState 1 +NtUserGetAtomName 2 +NtUserGetCaretBlinkTime 0 +NtUserGetCaretPos 1 +NtUserGetClassInfoEx 5 +NtUserGetClassName 3 +NtUserGetClipboardData 2 +NtUserGetClipboardFormatName 3 +NtUserGetClipboardOwner 0 +NtUserGetClipboardSequenceNumber 0 +NtUserGetClipboardViewer 0 +NtUserGetClipCursor 1 +NtUserGetComboBoxInfo 2 +NtUserGetControlBrush 3 +NtUserGetControlColor 4 +NtUserGetCPD 3 +NtUserGetCursorFrameInfo 4 +NtUserGetCursorInfo 1 +NtUserGetDC 1 +NtUserGetDCEx 3 +NtUserGetDoubleClickTime 0 +NtUserGetForegroundWindow 0 +NtUserGetGuiResources 2 +NtUserGetGUIThreadInfo 2 +NtUserGetIconInfo 6 +NtUserGetIconSize 4 +NtUserGetImeHotKey 4 +NtUserGetImeInfoEx 2 +NtUserGetInternalWindowPos 3 +NtUserGetKeyboardLayoutList 2 +NtUserGetKeyboardLayoutName 1 +NtUserGetKeyboardState 1 +NtUserGetKeyNameText 3 +NtUserGetKeyState 1 +NtUserGetListBoxInfo 1 +NtUserGetMenuBarInfo 4 +NtUserGetMenuIndex 2 +NtUserGetMenuItemRect 4 +NtUserGetMessage 4 +NtUserGetMouseMovePointsEx 5 +NtUserGetObjectInformation 5 +NtUserGetOpenClipboardWindow 0 +NtUserGetPriorityClipboardFormat 2 +NtUserGetProcessWindowStation 0 +NtUserGetRawInputBuffer 3 +NtUserGetRawInputData 5 +NtUserGetRawInputDeviceInfo 4 +NtUserGetRawInputDeviceList 3 +NtUserGetRegisteredRawInputDevices 3 +NtUserGetScrollBarInfo 3 +NtUserGetSystemMenu 2 +NtUserGetThreadDesktop 2 +NtUserGetThreadState 1 +NtUserGetTitleBarInfo 2 +NtUserGetUpdateRect 3 +NtUserGetUpdateRgn 3 +NtUserGetWindowDC 1 +NtUserGetWindowPlacement 2 +NtUserGetWOWClass 2 +NtUserHardErrorControl 3 +NtUserHideCaret 1 +NtUserHiliteMenuItem 4 +NtUserImpersonateDdeClientWindow 2 +NtUserInitialize 3 +NtUserInitializeClientPfnArrays 4 +NtUserInitTask 12 +NtUserInternalGetWindowText 3 +NtUserInvalidateRect 3 +NtUserInvalidateRgn 3 +NtUserIsClipboardFormatAvailable 1 +NtUserKillTimer 2 +NtUserLoadKeyboardLayoutEx 7 +NtUserLockWindowStation 1 +NtUserLockWindowUpdate 1 +NtUserLockWorkStation 0 +NtUserMapVirtualKeyEx 4 +NtUserMenuItemFromPoint 4 +NtUserMessageCall 7 +NtUserMinMaximize 3 +NtUserMNDragLeave 0 +NtUserMNDragOver 2 +NtUserModifyUserStartupInfoFlags 2 +NtUserMoveWindow 6 +NtUserNotifyIMEStatus 3 +NtUserNotifyProcessCreate 4 +NtUserNotifyWinEvent 4 +NtUserOpenClipboard 2 +NtUserOpenDesktop 3 +NtUserOpenInputDesktop 3 +NtUserOpenWindowStation 2 +NtUserPaintDesktop 1 +NtUserPeekMessage 5 +NtUserPostMessage 4 +NtUserPostThreadMessage 4 +NtUserPrintWindow 3 +NtUserProcessConnect 3 +NtUserQueryInformationThread 4 +NtUserQueryInputContext 2 +NtUserQuerySendMessage 1 +NtUserQueryWindow 2 +NtUserRealChildWindowFromPoint 3 +NtUserRealInternalGetMessage 6 +NtUserRealWaitMessageEx 2 +NtUserRedrawWindow 4 +NtUserRegisterClassExWOW 7 +NtUserRegisterUserApiHook 4 +NtUserRegisterHotKey 4 +NtUserRegisterRawInputDevices 3 +NtUserRegisterTasklist 1 +NtUserRegisterWindowMessage 1 +NtUserRemoveMenu 3 +NtUserRemoveProp 2 +NtUserResolveDesktop 4 +NtUserResolveDesktopForWOW 1 +NtUserSBGetParms 4 +NtUserScrollDC 7 +NtUserScrollWindowEx 8 +NtUserSelectPalette 3 +NtUserSendInput 3 +NtUserSetActiveWindow 1 +NtUserSetAppImeLevel 2 +NtUserSetCapture 1 +NtUserSetClassLong 4 +NtUserSetClassWord 3 +NtUserSetClipboardData 3 +NtUserSetClipboardViewer 1 +NtUserSetConsoleReserveKeys 2 +NtUserSetCursor 1 +NtUserSetCursorContents 2 +NtUserSetCursorIconData 4 +NtUserSetFocus 1 +NtUserSetImeHotKey 5 +NtUserSetImeInfoEx 1 +NtUserSetImeOwnerWindow 2 +NtUserSetInformationProcess 4 +NtUserSetInformationThread 4 +NtUserSetInternalWindowPos 4 +NtUserSetKeyboardState 1 +NtUserSetLogonNotifyWindow 1 +NtUserSetMenu 3 +NtUserSetMenuContextHelpId 2 +NtUserSetMenuDefaultItem 3 +NtUserSetMenuFlagRtoL 1 +NtUserSetObjectInformation 4 +NtUserSetParent 2 +NtUserSetProcessWindowStation 1 +NtUserSetProp 3 +NtUserSetScrollInfo 4 +NtUserSetShellWindowEx 2 +NtUserSetSysColors 4 +NtUserSetSystemCursor 2 +NtUserSetSystemMenu 2 +NtUserSetSystemTimer 4 +NtUserSetThreadDesktop 1 +NtUserSetThreadLayoutHandles 2 +NtUserSetThreadState 2 +NtUserSetTimer 4 +NtUserSetWindowFNID 2 +NtUserSetWindowLong 4 +NtUserSetWindowPlacement 2 +NtUserSetWindowPos 7 +NtUserSetWindowRgn 3 +NtUserSetWindowsHookAW 3 +NtUserSetWindowsHookEx 6 +NtUserSetWindowStationUser 4 +NtUserSetWindowWord 3 +NtUserSetWinEventHook 8 +NtUserShowCaret 1 +NtUserShowScrollBar 3 +NtUserShowWindow 2 +NtUserShowWindowAsync 2 +NtUserSoundSentry 0 +NtUserSwitchDesktop 1 +NtUserSystemParametersInfo 4 +NtUserTestForInteractiveUser 1 +NtUserThunkedMenuInfo 2 +NtUserThunkedMenuItemInfo 6 +NtUserToUnicodeEx 7 +NtUserTrackMouseEvent 1 +NtUserTrackPopupMenuEx 6 +NtUserCalcMenuBar 5 +NtUserPaintMenuBar 6 +NtUserTranslateAccelerator 3 +NtUserTranslateMessage 2 +NtUserUnhookWindowsHookEx 1 +NtUserUnhookWinEvent 1 +NtUserUnloadKeyboardLayout 1 +NtUserUnlockWindowStation 1 +NtUserUnregisterClass 3 +NtUserUnregisterUserApiHook 0 +NtUserUnregisterHotKey 2 +NtUserUpdateInputContext 3 +NtUserUpdateInstance 3 +NtUserUpdateLayeredWindow 10 +NtUserGetLayeredWindowAttributes 4 +NtUserSetLayeredWindowAttributes 4 +NtUserUpdatePerUserSystemParameters 2 +NtUserUserHandleGrantAccess 3 +NtUserValidateHandleSecure 1 +NtUserValidateRect 2 +NtUserValidateTimerCallback 1 +NtUserVkKeyScanEx 3 +NtUserWaitForInputIdle 3 +NtUserWaitForMsgAndEvent 1 +NtUserWaitMessage 0 +NtUserWin32PoolAllocationStats 6 +NtUserWindowFromPoint 2 +NtUserYieldTask 0 +NtUserRemoteConnect 3 +NtUserRemoteRedrawRectangle 4 +NtUserRemoteRedrawScreen 0 +NtUserRemoteStopScreenUpdates 0 +NtUserCtxDisplayIOCtl 3 +NtGdiEngAssociateSurface 3 +NtGdiEngCreateBitmap 6 +NtGdiEngCreateDeviceSurface 4 +NtGdiEngCreateDeviceBitmap 4 +NtGdiEngCreatePalette 6 +NtGdiEngComputeGlyphSet 3 +NtGdiEngCopyBits 6 +NtGdiEngDeletePalette 1 +NtGdiEngDeleteSurface 1 +NtGdiEngEraseSurface 3 +NtGdiEngUnlockSurface 1 +NtGdiEngLockSurface 1 +NtGdiEngBitBlt 11 +NtGdiEngStretchBlt 11 +NtGdiEngPlgBlt 11 +NtGdiEngMarkBandingSurface 1 +NtGdiEngStrokePath 8 +NtGdiEngFillPath 7 +NtGdiEngStrokeAndFillPath 10 +NtGdiEngPaint 5 +NtGdiEngLineTo 9 +NtGdiEngAlphaBlend 7 +NtGdiEngGradientFill 10 +NtGdiEngTransparentBlt 8 +NtGdiEngTextOut 10 +NtGdiEngStretchBltROP 13 +NtGdiXLATEOBJ_cGetPalette 4 +NtGdiXLATEOBJ_iXlate 2 +NtGdiXLATEOBJ_hGetColorTransform 1 +NtGdiCLIPOBJ_bEnum 3 +NtGdiCLIPOBJ_cEnumStart 5 +NtGdiCLIPOBJ_ppoGetPath 1 +NtGdiEngDeletePath 1 +NtGdiEngCreateClip 0 +NtGdiEngDeleteClip 1 +NtGdiBRUSHOBJ_ulGetBrushColor 1 +NtGdiBRUSHOBJ_pvAllocRbrush 2 +NtGdiBRUSHOBJ_pvGetRbrush 1 +NtGdiBRUSHOBJ_hGetColorTransform 1 +NtGdiXFORMOBJ_bApplyXform 5 +NtGdiXFORMOBJ_iGetXform 2 +NtGdiFONTOBJ_vGetInfo 3 +NtGdiFONTOBJ_pxoGetXform 1 +NtGdiFONTOBJ_cGetGlyphs 5 +NtGdiFONTOBJ_pifi 1 +NtGdiFONTOBJ_pfdg 1 +NtGdiFONTOBJ_pQueryGlyphAttrs 2 +NtGdiFONTOBJ_pvTrueTypeFontFile 2 +NtGdiFONTOBJ_cGetAllGlyphHandles 2 +NtGdiSTROBJ_bEnum 3 +NtGdiSTROBJ_bEnumPositionsOnly 3 +NtGdiSTROBJ_bGetAdvanceWidths 4 +NtGdiSTROBJ_vEnumStart 1 +NtGdiSTROBJ_dwGetCodePage 1 +NtGdiPATHOBJ_vGetBounds 2 +NtGdiPATHOBJ_bEnum 2 +NtGdiPATHOBJ_vEnumStart 1 +NtGdiPATHOBJ_vEnumStartClipLines 4 +NtGdiPATHOBJ_bEnumClipLines 3 +NtGdiGetDhpdev 1 +NtGdiEngCheckAbort 1 +NtGdiHT_Get8BPPFormatPalette 4 +NtGdiHT_Get8BPPMaskPalette 6 +NtGdiUpdateTransform 1 +NtGdiSetPUMPDOBJ 4 +NtGdiBRUSHOBJ_DeleteRbrush 2 +NtGdiUnmapMemFont 1 +NtGdiDrawStream 3 +NtGdiMakeObjectXferable 2 +NtGdiMakeObjectUnXferable 1 diff --git a/rostests/apitests/w32kdll/w32kdll_2ksp4/w32k_2ksp4-x86.db b/rostests/apitests/w32kdll/w32kdll_2ksp4/w32k_2ksp4-x86.db new file mode 100644 index 00000000000..b8fda7a4f0d --- /dev/null +++ b/rostests/apitests/w32kdll/w32kdll_2ksp4/w32k_2ksp4-x86.db @@ -0,0 +1,643 @@ +# +# win32k systemcalls taken from Windows 2000 SP4 x86 +# +NtGdiAbortDoc 1 +NtGdiAbortPath 1 +NtGdiAddFontResourceW 6 +NtGdiAddRemoteFontToDC 4 +NtGdiAddFontMemResourceEx 5 +NtGdiRemoveMergeFont 2 +NtGdiAddRemoteMMInstanceToDC 3 +NtGdiAlphaBlend 12 +NtGdiAngleArc 6 +NtGdiAnyLinkedFonts 0 +NtGdiFontIsLinked 1 +NtGdiArcInternal 10 +NtGdiBeginPath 1 +NtGdiBitBlt 11 +NtGdiCancelDC 1 +NtGdiCheckBitmapBits 8 +NtGdiCloseFigure 1 +NtGdiColorCorrectPalette 6 +NtGdiCombineRgn 4 +NtGdiCombineTransform 3 +NtGdiComputeXformCoefficients 1 +NtGdiConsoleTextOut 4 +NtGdiConvertMetafileRect 2 +NtGdiCreateBitmap 5 +NtGdiCreateClientObj 1 +NtGdiCreateColorSpace 1 +NtGdiCreateColorTransform 8 +NtGdiCreateCompatibleBitmap 3 +NtGdiCreateCompatibleDC 1 +NtGdiCreateDIBBrush 6 +NtGdiCreateDIBitmapInternal 11 +NtGdiCreateDIBSection 9 +NtGdiCreateEllipticRgn 4 +NtGdiCreateHalftonePalette 1 +NtGdiCreateHatchBrushInternal 3 +NtGdiCreateMetafileDC 1 +NtGdiCreatePaletteInternal 2 +NtGdiCreatePatternBrushInternal 3 +NtGdiCreatePen 4 +NtGdiCreateRectRgn 4 +NtGdiCreateRoundRectRgn 6 +NtGdiCreateServerMetaFile 6 +NtGdiCreateSolidBrush 2 +NtGdiD3dContextCreate 4 +NtGdiD3dContextDestroy 1 +NtGdiD3dContextDestroyAll 1 +NtGdiD3dValidateTextureStageState 1 +NtGdiD3dDrawPrimitives2 7 +NtGdiDdGetDriverState 1 +NtGdiDdAddAttachedSurface 3 +NtGdiDdAlphaBlt 3 +NtGdiDdAttachSurface 2 +NtGdiDdBeginMoCompFrame 2 +NtGdiDdBlt 3 +NtGdiDdCanCreateSurface 2 +NtGdiDdCanCreateD3DBuffer 2 +NtGdiDdColorControl 2 +NtGdiDdCreateDirectDrawObject 1 +NtGdiDdCreateSurface 8 +NtGdiDdCreateD3DBuffer 8 +NtGdiDdCreateMoComp 2 +NtGdiDdCreateSurfaceObject 6 +NtGdiDdDeleteDirectDrawObject 1 +NtGdiDdDeleteSurfaceObject 1 +NtGdiDdDestroyMoComp 2 +NtGdiDdDestroySurface 2 +NtGdiDdDestroyD3DBuffer 1 +NtGdiDdEndMoCompFrame 2 +NtGdiDdFlip 5 +NtGdiDdFlipToGDISurface 2 +NtGdiDdGetAvailDriverMemory 2 +NtGdiDdGetBltStatus 2 +NtGdiDdGetDC 2 +NtGdiDdGetDriverInfo 2 +NtGdiDdGetDxHandle 3 +NtGdiDdGetFlipStatus 2 +NtGdiDdGetInternalMoCompInfo 2 +NtGdiDdGetMoCompBuffInfo 2 +NtGdiDdGetMoCompGuids 2 +NtGdiDdGetMoCompFormats 2 +NtGdiDdGetScanLine 2 +NtGdiDdLock 3 +NtGdiDdLockD3D 2 +NtGdiDdQueryDirectDrawObject 11 +NtGdiDdQueryMoCompStatus 2 +NtGdiDdReenableDirectDrawObject 2 +NtGdiDdReleaseDC 1 +NtGdiDdRenderMoComp 2 +NtGdiDdResetVisrgn 2 +NtGdiDdSetColorKey 2 +NtGdiDdSetExclusiveMode 2 +NtGdiDdSetGammaRamp 3 +NtGdiDdCreateSurfaceEx 3 +NtGdiDdSetOverlayPosition 3 +NtGdiDdUnattachSurface 2 +NtGdiDdUnlock 2 +NtGdiDdUnlockD3D 2 +NtGdiDdUpdateOverlay 3 +NtGdiDdWaitForVerticalBlank 2 +NtGdiDvpCanCreateVideoPort 2 +NtGdiDvpColorControl 2 +NtGdiDvpCreateVideoPort 2 +NtGdiDvpDestroyVideoPort 2 +NtGdiDvpFlipVideoPort 4 +NtGdiDvpGetVideoPortBandwidth 2 +NtGdiDvpGetVideoPortField 2 +NtGdiDvpGetVideoPortFlipStatus 2 +NtGdiDvpGetVideoPortInputFormats 2 +NtGdiDvpGetVideoPortLine 2 +NtGdiDvpGetVideoPortOutputFormats 2 +NtGdiDvpGetVideoPortConnectInfo 2 +NtGdiDvpGetVideoSignalStatus 2 +NtGdiDvpUpdateVideoPort 4 +NtGdiDvpWaitForVideoPortSync 2 +NtGdiDeleteClientObj 1 +NtGdiDeleteColorSpace 1 +NtGdiDeleteColorTransform 2 +NtGdiDeleteObjectApp 1 +NtGdiDescribePixelFormat 4 +NtGdiGetPerBandInfo 2 +NtGdiDoBanding 4 +NtGdiDoPalette 6 +NtGdiDrawEscape 4 +NtGdiEllipse 5 +NtGdiEnableEudc 1 +NtGdiEndDoc 1 +NtGdiEndPage 1 +NtGdiEndPath 1 +NtGdiEnumFontChunk 5 +NtGdiEnumFontClose 1 +NtGdiEnumFontOpen 7 +NtGdiEnumObjects 4 +NtGdiEqualRgn 2 +NtGdiEudcEnumFaceNameLinkW 4 +NtGdiEudcLoadUnloadLink 7 +NtGdiExcludeClipRect 5 +NtGdiExtCreatePen 11 +NtGdiExtCreateRegion 3 +NtGdiExtEscape 8 +NtGdiExtFloodFill 5 +NtGdiExtGetObjectW 3 +NtGdiExtSelectClipRgn 3 +NtGdiExtTextOutW 9 +NtGdiFillPath 1 +NtGdiFillRgn 3 +NtGdiFlattenPath 1 +NtGdiFlushUserBatch 0 +NtGdiFlush 0 +NtGdiForceUFIMapping 2 +NtGdiFrameRgn 5 +NtGdiFullscreenControl 5 +NtGdiGetAndSetDCDword 4 +NtGdiGetAppClipBox 2 +NtGdiGetBitmapBits 3 +NtGdiGetBitmapDimension 2 +NtGdiGetBoundsRect 3 +NtGdiGetCharABCWidthsW 6 +NtGdiGetCharacterPlacementW 6 +NtGdiGetCharSet 1 +NtGdiGetCharWidthW 6 +NtGdiGetCharWidthInfo 2 +NtGdiGetColorAdjustment 2 +NtGdiGetColorSpaceforBitmap 1 +NtGdiGetDCDword 3 +NtGdiGetDCforBitmap 1 +NtGdiGetDCObject 2 +NtGdiGetDCPoint 3 +NtGdiGetDeviceCaps 2 +NtGdiGetDeviceGammaRamp 2 +NtGdiGetDeviceCapsAll 2 +NtGdiGetDIBitsInternal 9 +NtGdiGetETM 2 +NtGdiGetEudcTimeStampEx 3 +NtGdiGetFontData 5 +NtGdiGetFontResourceInfoInternalW 7 +NtGdiGetGlyphIndicesW 5 +NtGdiGetGlyphIndicesWInternal 6 +NtGdiGetGlyphOutline 8 +NtGdiGetKerningPairs 3 +NtGdiGetLinkedUFIs 3 +NtGdiGetMiterLimit 2 +NtGdiGetMonitorID 3 +NtGdiGetNearestColor 2 +NtGdiGetNearestPaletteIndex 2 +NtGdiGetObjectBitmapHandle 2 +NtGdiGetOutlineTextMetricsInternalW 4 +NtGdiGetPath 4 +NtGdiGetPixel 3 +NtGdiGetRandomRgn 3 +NtGdiGetRasterizerCaps 2 +NtGdiGetRealizationInfo 2 +NtGdiGetRegionData 3 +NtGdiGetRgnBox 2 +NtGdiGetServerMetaFileBits 7 +NtGdiGetSpoolMessage 4 +NtGdiGetStats 5 +NtGdiGetStockObject 1 +NtGdiGetStringBitmapW 5 +NtGdiGetSystemPaletteUse 1 +NtGdiGetTextCharsetInfo 3 +NtGdiGetTextExtent 5 +NtGdiGetTextExtentExW 8 +NtGdiGetTextFaceW 4 +NtGdiGetTextMetricsW 3 +NtGdiGetTransform 3 +NtGdiGetUFI 6 +NtGdiGetUFIPathname 10 +NtGdiGetFontUnicodeRanges 2 +NtGdiGetWidthTable 7 +NtGdiGradientFill 6 +NtGdiHfontCreate 5 +NtGdiIcmBrushInfo 8 +NtGdiInit 0 +NtGdiInitSpool 0 +NtGdiIntersectClipRect 5 +NtGdiInvertRgn 2 +NtGdiLineTo 3 +NtGdiMakeFontDir 5 +NtGdiMakeInfoDC 2 +NtGdiMaskBlt 13 +NtGdiModifyWorldTransform 3 +NtGdiMonoBitmap 1 +NtGdiMoveTo 4 +NtGdiOffsetClipRgn 3 +NtGdiOffsetRgn 3 +NtGdiOpenDCW 7 +NtGdiPatBlt 6 +NtGdiPolyPatBlt 5 +NtGdiPathToRegion 1 +NtGdiPlgBlt 11 +NtGdiPolyDraw 4 +NtGdiPolyPolyDraw 5 +NtGdiPolyTextOutW 4 +NtGdiPtInRegion 3 +NtGdiPtVisible 3 +NtGdiQueryFonts 3 +NtGdiQueryFontAssocInfo 1 +NtGdiRectangle 5 +NtGdiRectInRegion 2 +NtGdiRectVisible 2 +NtGdiRemoveFontResourceW 6 +NtGdiRemoveFontMemResourceEx 1 +NtGdiResetDC 5 +NtGdiResizePalette 2 +NtGdiRestoreDC 2 +NtGdiRoundRect 7 +NtGdiSaveDC 1 +NtGdiScaleViewportExtEx 6 +NtGdiScaleWindowExtEx 6 +NtGdiSelectBitmap 2 +NtGdiSelectBrush 2 +NtGdiSelectClipPath 2 +NtGdiSelectFont 2 +NtGdiSelectPen 2 +NtGdiSetBitmapBits 3 +NtGdiSetBitmapDimension 4 +NtGdiSetBoundsRect 3 +NtGdiSetBrushOrg 4 +NtGdiSetColorAdjustment 2 +NtGdiSetColorSpace 2 +NtGdiSetDeviceGammaRamp 2 +NtGdiSetDIBitsToDeviceInternal 16 +NtGdiSetFontEnumeration 1 +NtGdiSetFontXform 3 +NtGdiSetIcmMode 3 +NtGdiSetLinkedUFIs 3 +NtGdiSetMagicColors 3 +NtGdiSetMetaRgn 1 +NtGdiSetMiterLimit 3 +NtGdiGetDeviceWidth 1 +NtGdiMirrorWindowOrg 1 +NtGdiSetLayout 3 +NtGdiSetPixel 4 +NtGdiSetPixelFormat 2 +NtGdiSetRectRgn 5 +NtGdiSetSystemPaletteUse 2 +NtGdiSetTextJustification 3 +NtGdiSetupPublicCFONT 3 +NtGdiSetVirtualResolution 5 +NtGdiSetSizeDevice 3 +NtGdiStartDoc 4 +NtGdiStartPage 1 +NtGdiStretchBlt 12 +NtGdiStretchDIBitsInternal 16 +NtGdiStrokeAndFillPath 1 +NtGdiStrokePath 1 +NtGdiSwapBuffers 1 +NtGdiTransformPoints 5 +NtGdiTransparentBlt 11 +NtGdiUnloadPrinterDriver 2 +NtGdiUnmapMemFont 1 +NtGdiUnrealizeObject 1 +NtGdiUpdateColors 1 +NtGdiWidenPath 1 +NtUserActivateKeyboardLayout 2 +NtUserAlterWindowStyle 3 +NtUserAssociateInputContext 3 +NtUserAttachThreadInput 3 +NtUserBeginPaint 2 +NtUserBitBltSysBmp 8 +NtUserBlockInput 1 +NtUserBuildHimcList 4 +NtUserBuildHwndList 7 +NtUserBuildNameList 4 +NtUserBuildPropList 4 +NtUserCallHwnd 2 +NtUserCallHwndLock 2 +NtUserCallHwndOpt 2 +NtUserCallHwndParam 3 +NtUserCallHwndParamLock 3 +NtUserCallMsgFilter 2 +NtUserCallNextHookEx 4 +NtUserCallNoParam 1 +NtUserCallOneParam 1 +NtUserCallTwoParam 3 +NtUserChangeClipboardChain 2 +NtUserChangeDisplaySettings 5 +NtUserCheckImeHotKey 3 +NtUserCheckMenuItem 3 +NtUserChildWindowFromPointEx 4 +NtUserClipCursor 1 +NtUserCloseClipboard 0 +NtUserCloseDesktop 1 +NtUserCloseWindowStation 1 +NtUserConsoleControl 3 +NtUserConvertMemHandle 2 +NtUserCopyAcceleratorTable 3 +NtUserCountClipboardFormats 1 +NtUserCreateAcceleratorTable 2 +NtUserCreateCaret 4 +NtUserCreateDesktop 5 +NtUserCreateInputContext 1 +NtUserCreateLocalMemHandle 4 +NtUserCreateWindowEx 13 +NtUserCreateWindowStation 6 +NtUserDdeGetQualityOfService 3 +NtUserDdeInitialize 5 +NtUserDdeSetQualityOfService 3 +NtUserDeferWindowPos 8 +NtUserDefSetText 2 +NtUserDeleteMenu 3 +NtUserDestroyAcceleratorTable 1 +NtUserDestroyCursor 2 +NtUserDestroyInputContext 1 +NtUserDestroyMenu 1 +NtUserDestroyWindow 1 +NtUserDisableThreadIme 1 +NtUserDispatchMessage 1 +NtUserDragDetect 3 +NtUserDragObject 5 +NtUserDrawAnimatedRects 4 +NtUserDrawCaption 4 +NtUserDrawCaptionTemp 7 +NtUserDrawIconEx 11 +NtUserDrawMenuBarTemp 5 +NtUserEmptyClipboard 0 +NtUserEnableMenuItem 3 +NtUserEnableScrollBar 3 +NtUserEndDeferWindowPosEx 2 +NtUserEndMenu 0 +NtUserEndPaint 2 +NtUserEnumDisplayDevices 4 +NtUserEnumDisplayMonitors 4 +NtUserEnumDisplaySettings 4 +NtUserEvent 1 +NtUserExcludeUpdateRgn 2 +NtUserFillWindow 4 +NtUserFindExistingCursorIcon 3 +NtUserFindWindowEx 5 +NtUserFlashWindowEx 1 +NtUserGetAltTabInfo 6 +NtUserGetAncestor 2 +NtUserGetAppImeLevel 1 +NtUserGetAsyncKeyState 1 +NtUserGetCaretBlinkTime 0 +NtUserGetCaretPos 1 +NtUserGetClassInfo 5 +NtUserGetClassName 3 +NtUserGetClipboardData 2 +NtUserGetClipboardFormatName 3 +NtUserGetClipboardOwner 0 +NtUserGetClipboardSequenceNumber 0 +NtUserGetClipboardViewer 0 +NtUserGetClipCursor 1 +NtUserGetComboBoxInfo 2 +NtUserGetControlBrush 3 +NtUserGetControlColor 4 +NtUserGetCPD 3 +NtUserGetCursorFrameInfo 4 +NtUserGetCursorInfo 1 +NtUserGetDC 1 +NtUserGetDCEx 3 +NtUserGetDoubleClickTime 0 +NtUserGetForegroundWindow 0 +NtUserGetGuiResources 2 +NtUserGetGUIThreadInfo 2 +NtUserGetIconInfo 6 +NtUserGetIconSize 4 +NtUserGetImeHotKey 4 +NtUserGetImeInfoEx 2 +NtUserGetInternalWindowPos 3 +NtUserGetKeyboardLayoutList 2 +NtUserGetKeyboardLayoutName 1 +NtUserGetKeyboardState 1 +NtUserGetKeyNameText 3 +NtUserGetKeyState 1 +NtUserGetListBoxInfo 1 +NtUserGetMenuBarInfo 4 +NtUserGetMenuIndex 2 +NtUserGetMenuItemRect 4 +NtUserGetMessage 4 +NtUserGetMouseMovePointsEx 5 +NtUserGetObjectInformation 5 +NtUserGetOpenClipboardWindow 0 +NtUserGetPriorityClipboardFormat 2 +NtUserGetProcessWindowStation 0 +NtUserGetScrollBarInfo 3 +NtUserGetSystemMenu 2 +NtUserGetThreadDesktop 2 +NtUserGetThreadState 1 +NtUserGetTitleBarInfo 2 +NtUserGetUpdateRect 3 +NtUserGetUpdateRgn 3 +NtUserGetWindowDC 1 +NtUserGetWindowPlacement 2 +NtUserGetWOWClass 2 +NtUserHardErrorControl 3 +NtUserHideCaret 1 +NtUserHiliteMenuItem 4 +NtUserImpersonateDdeClientWindow 2 +NtUserInitialize 3 +NtUserInitializeClientPfnArrays 4 +NtUserInitTask 11 +NtUserInternalGetWindowText 3 +NtUserInvalidateRect 3 +NtUserInvalidateRgn 3 +NtUserIsClipboardFormatAvailable 1 +NtUserKillTimer 2 +NtUserLoadKeyboardLayoutEx 6 +NtUserLockWindowStation 1 +NtUserLockWindowUpdate 1 +NtUserLockWorkStation 0 +NtUserMapVirtualKeyEx 4 +NtUserMenuItemFromPoint 4 +NtUserMessageCall 7 +NtUserMinMaximize 3 +NtUserMNDragLeave 1 +NtUserMNDragOver 2 +NtUserModifyUserStartupInfoFlags 2 +NtUserMoveWindow 6 +NtUserNotifyIMEStatus 3 +NtUserNotifyProcessCreate 4 +NtUserNotifyWinEvent 4 +NtUserOpenClipboard 2 +NtUserOpenDesktop 3 +NtUserOpenInputDesktop 3 +NtUserOpenWindowStation 2 +NtUserPaintDesktop 1 +NtUserPeekMessage 5 +NtUserPostMessage 4 +NtUserPostThreadMessage 4 +NtUserProcessConnect 3 +NtUserQueryInformationThread 5 +NtUserQueryInputContext 2 +NtUserQuerySendMessage 1 +NtUserQueryUserCounters 5 +NtUserQueryWindow 2 +NtUserRealChildWindowFromPoint 3 +NtUserRedrawWindow 4 +NtUserRegisterClassExWOW 6 +NtUserRegisterHotKey 4 +NtUserRegisterTasklist 1 +NtUserRegisterWindowMessage 1 +NtUserRemoveMenu 3 +NtUserRemoveProp 2 +NtUserResolveDesktop 4 +NtUserResolveDesktopForWOW 1 +NtUserSBGetParms 4 +NtUserScrollDC 7 +NtUserScrollWindowEx 8 +NtUserSelectPalette 3 +NtUserSendInput 3 +NtUserSendMessageCallback 6 +NtUserSendNotifyMessage 4 +NtUserSetActiveWindow 1 +NtUserSetAppImeLevel 2 +NtUserSetCapture 1 +NtUserSetClassLong 4 +NtUserSetClassWord 3 +NtUserSetClipboardData 3 +NtUserSetClipboardViewer 1 +NtUserSetConsoleReserveKeys 2 +NtUserSetCursor 1 +NtUserSetCursorContents 2 +NtUserSetCursorIconData 4 +NtUserSetDbgTag 2 +NtUserSetFocus 1 +NtUserSetImeHotKey 5 +NtUserSetImeInfoEx 1 +NtUserSetImeOwnerWindow 2 +NtUserSetInformationProcess 4 +NtUserSetInformationThread 5 +NtUserSetInternalWindowPos 4 +NtUserSetKeyboardState 1 +NtUserSetLogonNotifyWindow 1 +NtUserSetMenu 3 +NtUserSetMenuContextHelpId 2 +NtUserSetMenuDefaultItem 3 +NtUserSetMenuFlagRtoL 1 +NtUserSetObjectInformation 4 +NtUserSetParent 2 +NtUserSetProcessWindowStation 1 +NtUserSetProp 3 +NtUserSetRipFlags 2 +NtUserSetScrollInfo 4 +NtUserSetShellWindowEx 2 +NtUserSetSysColors 4 +NtUserSetSystemCursor 2 +NtUserSetSystemMenu 2 +NtUserSetSystemTimer 4 +NtUserSetThreadDesktop 1 +NtUserSetThreadLayoutHandles 2 +NtUserSetThreadState 2 +NtUserSetTimer 4 +NtUserSetWindowFNID 2 +NtUserSetWindowLong 4 +NtUserSetWindowPlacement 2 +NtUserSetWindowPos 7 +NtUserSetWindowRgn 3 +NtUserSetWindowsHookAW 3 +NtUserSetWindowsHookEx 6 +NtUserSetWindowStationUser 4 +NtUserSetWindowWord 3 +NtUserSetWinEventHook 8 +NtUserShowCaret 1 +NtUserShowScrollBar 3 +NtUserShowWindow 2 +NtUserShowWindowAsync 2 +NtUserSoundSentry 0 +NtUserSwitchDesktop 1 +NtUserSystemParametersInfo 4 +NtUserTestForInteractiveUser 1 +NtUserThunkedMenuInfo 2 +NtUserThunkedMenuItemInfo 6 +NtUserToUnicodeEx 7 +NtUserTrackMouseEvent 1 +NtUserTrackPopupMenuEx 6 +NtUserTranslateAccelerator 3 +NtUserTranslateMessage 2 +NtUserUnhookWindowsHookEx 1 +NtUserUnhookWinEvent 1 +NtUserUnloadKeyboardLayout 1 +NtUserUnlockWindowStation 1 +NtUserUnregisterClass 3 +NtUserUnregisterHotKey 2 +NtUserUpdateInputContext 3 +NtUserUpdateInstance 3 +NtUserUpdateLayeredWindow 9 +NtUserSetLayeredWindowAttributes 4 +NtUserUpdatePerUserSystemParameters 2 +NtUserUserHandleGrantAccess 3 +NtUserValidateHandleSecure 1 +NtUserValidateRect 2 +NtUserVkKeyScanEx 3 +NtUserWaitForInputIdle 3 +NtUserWaitForMsgAndEvent 1 +NtUserWaitMessage 0 +NtUserWin32PoolAllocationStats 6 +NtUserWindowFromPoint 2 +NtUserYieldTask 0 +NtUserRemoteConnect 3 +NtUserRemoteRedrawRectangle 4 +NtUserRemoteRedrawScreen 0 +NtUserRemoteStopScreenUpdates 0 +NtUserCtxDisplayIOCtl 3 +NtGdiEngAssociateSurface 3 +NtGdiEngCreateBitmap 6 +NtGdiEngCreateDeviceSurface 4 +NtGdiEngCreateDeviceBitmap 4 +NtGdiEngCreatePalette 6 +NtGdiEngComputeGlyphSet 3 +NtGdiEngCopyBits 6 +NtGdiEngDeletePalette 1 +NtGdiEngDeleteSurface 1 +NtGdiEngEraseSurface 3 +NtGdiEngUnlockSurface 1 +NtGdiEngLockSurface 1 +NtGdiEngBitBlt 11 +NtGdiEngStretchBlt 11 +NtGdiEngPlgBlt 11 +NtGdiEngMarkBandingSurface 1 +NtGdiEngStrokePath 8 +NtGdiEngFillPath 7 +NtGdiEngStrokeAndFillPath 10 +NtGdiEngPaint 5 +NtGdiEngLineTo 9 +NtGdiEngAlphaBlend 7 +NtGdiEngGradientFill 10 +NtGdiEngTransparentBlt 8 +NtGdiEngTextOut 10 +NtGdiEngStretchBltROP 13 +NtGdiXLATEOBJ_cGetPalette 4 +NtGdiXLATEOBJ_iXlate 2 +NtGdiXLATEOBJ_hGetColorTransform 1 +NtGdiCLIPOBJ_bEnum 3 +NtGdiCLIPOBJ_cEnumStart 5 +NtGdiCLIPOBJ_ppoGetPath 1 +NtGdiEngDeletePath 1 +NtGdiEngCreateClip 0 +NtGdiEngDeleteClip 1 +NtGdiBRUSHOBJ_ulGetBrushColor 1 +NtGdiBRUSHOBJ_pvAllocRbrush 2 +NtGdiBRUSHOBJ_pvGetRbrush 1 +NtGdiBRUSHOBJ_hGetColorTransform 1 +NtGdiXFORMOBJ_bApplyXform 5 +NtGdiXFORMOBJ_iGetXform 2 +NtGdiFONTOBJ_vGetInfo 3 +NtGdiFONTOBJ_pxoGetXform 1 +NtGdiFONTOBJ_cGetGlyphs 5 +NtGdiFONTOBJ_pifi 1 +NtGdiFONTOBJ_pfdg 1 +NtGdiFONTOBJ_pQueryGlyphAttrs 2 +NtGdiFONTOBJ_pvTrueTypeFontFile 2 +NtGdiFONTOBJ_cGetAllGlyphHandles 2 +NtGdiSTROBJ_bEnum 3 +NtGdiSTROBJ_bEnumPositionsOnly 3 +NtGdiSTROBJ_bGetAdvanceWidths 4 +NtGdiSTROBJ_vEnumStart 1 +NtGdiSTROBJ_dwGetCodePage 1 +NtGdiPATHOBJ_vGetBounds 2 +NtGdiPATHOBJ_bEnum 2 +NtGdiPATHOBJ_vEnumStart 1 +NtGdiPATHOBJ_vEnumStartClipLines 4 +NtGdiPATHOBJ_bEnumClipLines 3 +NtGdiGetDhpdev 1 +NtGdiEngCheckAbort 1 +NtGdiHT_Get8BPPFormatPalette 4 +NtGdiHT_Get8BPPMaskPalette 6 +NtGdiUpdateTransform 1 +NtUserValidateTimerCallback 3 diff --git a/rostests/apitests/w32kdll/w32kdll_vista/w32kdll_vista-x86.db b/rostests/apitests/w32kdll/w32kdll_vista/w32kdll_vista-x86.db new file mode 100644 index 00000000000..1ab85e69981 --- /dev/null +++ b/rostests/apitests/w32kdll/w32kdll_vista/w32kdll_vista-x86.db @@ -0,0 +1,775 @@ +# +# win32k systemcalls taken from Windows Vista SP0 x86 +# +NtGdiAbortDoc 1 +NtGdiAbortPath 1 +NtGdiAddFontResourceW 6 +NtGdiAddRemoteFontToDC 4 +NtGdiAddFontMemResourceEx 5 +NtGdiRemoveMergeFont 2 +NtGdiAddRemoteMMInstanceToDC 3 +NtGdiAlphaBlend 12 +NtGdiAngleArc 6 +NtGdiAnyLinkedFonts 0 +NtGdiFontIsLinked 1 +NtGdiArcInternal 10 +NtGdiBeginPath 1 +NtGdiBitBlt 11 +NtGdiCancelDC 1 +NtGdiCheckBitmapBits 8 +NtGdiCloseFigure 1 +NtGdiClearBitmapAttributes 2 +NtGdiClearBrushAttributes 2 +NtGdiColorCorrectPalette 6 +NtGdiCombineRgn 4 +NtGdiCombineTransform 3 +NtGdiComputeXformCoefficients 1 +NtGdiConfigureOPMProtectedOutput 4 +NtGdiConsoleTextOut 4 +NtGdiConvertMetafileRect 2 +NtGdiCreateBitmap 5 +NtGdiCreateClientObj 1 +NtGdiCreateColorSpace 1 +NtGdiCreateColorTransform 8 +NtGdiCreateCompatibleBitmap 3 +NtGdiCreateCompatibleDC 1 +NtGdiCreateDIBBrush 6 +NtGdiCreateDIBitmapInternal 11 +NtGdiCreateDIBSection 9 +NtGdiCreateEllipticRgn 4 +NtGdiCreateHalftonePalette 1 +NtGdiCreateHatchBrushInternal 3 +NtGdiCreateMetafileDC 1 +NtGdiCreateOPMProtectedOutputs 5 +NtGdiCreatePaletteInternal 2 +NtGdiCreatePatternBrushInternal 3 +NtGdiCreatePen 4 +NtGdiCreateRectRgn 4 +NtGdiCreateRoundRectRgn 6 +NtGdiCreateServerMetaFile 6 +NtGdiCreateSolidBrush 2 +NtGdiD3dContextCreate 4 +NtGdiD3dContextDestroy 1 +NtGdiD3dContextDestroyAll 1 +NtGdiD3dValidateTextureStageState 1 +NtGdiD3dDrawPrimitives2 7 +NtGdiDdGetDriverState 1 +NtGdiDdAddAttachedSurface 3 +NtGdiDdAlphaBlt 3 +NtGdiDdAttachSurface 2 +NtGdiDdBeginMoCompFrame 2 +NtGdiDdBlt 3 +NtGdiDdCanCreateSurface 2 +NtGdiDdCanCreateD3DBuffer 2 +NtGdiDdColorControl 2 +NtGdiDdCreateDirectDrawObject 1 +NtGdiDdCreateSurface 8 +NtGdiDdCreateD3DBuffer 8 +NtGdiDdCreateMoComp 2 +NtGdiDdCreateSurfaceObject 6 +NtGdiDdDeleteDirectDrawObject 1 +NtGdiDdDeleteSurfaceObject 1 +NtGdiDdDestroyMoComp 2 +NtGdiDdDestroySurface 2 +NtGdiDdDestroyD3DBuffer 1 +NtGdiDdEndMoCompFrame 2 +NtGdiDdFlip 5 +NtGdiDdFlipToGDISurface 2 +NtGdiDdGetAvailDriverMemory 2 +NtGdiDdGetBltStatus 2 +NtGdiDdGetDC 2 +NtGdiDdGetDriverInfo 2 +NtGdiDdGetDxHandle 3 +NtGdiDdGetFlipStatus 2 +NtGdiDdGetInternalMoCompInfo 2 +NtGdiDdGetMoCompBuffInfo 2 +NtGdiDdGetMoCompGuids 2 +NtGdiDdGetMoCompFormats 2 +NtGdiDdGetScanLine 2 +NtGdiDdLock 3 +NtGdiDdLockD3D 2 +NtGdiDdQueryDirectDrawObject 11 +NtGdiDdQueryMoCompStatus 2 +NtGdiDdReenableDirectDrawObject 2 +NtGdiDdReleaseDC 1 +NtGdiDdRenderMoComp 2 +NtGdiDdResetVisrgn 2 +NtGdiDdSetColorKey 2 +NtGdiDdSetExclusiveMode 2 +NtGdiDdSetGammaRamp 3 +NtGdiDdCreateSurfaceEx 3 +NtGdiDdSetOverlayPosition 3 +NtGdiDdUnattachSurface 2 +NtGdiDdUnlock 2 +NtGdiDdUnlockD3D 2 +NtGdiDdUpdateOverlay 3 +NtGdiDdWaitForVerticalBlank 2 +NtGdiDvpCanCreateVideoPort 2 +NtGdiDvpColorControl 2 +NtGdiDvpCreateVideoPort 2 +NtGdiDvpDestroyVideoPort 2 +NtGdiDvpFlipVideoPort 4 +NtGdiDvpGetVideoPortBandwidth 2 +NtGdiDvpGetVideoPortField 2 +NtGdiDvpGetVideoPortFlipStatus 2 +NtGdiDvpGetVideoPortInputFormats 2 +NtGdiDvpGetVideoPortLine 2 +NtGdiDvpGetVideoPortOutputFormats 2 +NtGdiDvpGetVideoPortConnectInfo 2 +NtGdiDvpGetVideoSignalStatus 2 +NtGdiDvpUpdateVideoPort 4 +NtGdiDvpWaitForVideoPortSync 2 +NtGdiDvpAcquireNotification 3 +NtGdiDvpReleaseNotification 2 +NtGdiDxgGenericThunk 6 +NtGdiDeleteClientObj 1 +NtGdiDeleteColorSpace 1 +NtGdiDeleteColorTransform 2 +NtGdiDeleteObjectApp 1 +NtGdiDescribePixelFormat 4 +NtGdiDestroyOPMProtectedOutput 1 +NtGdiGetPerBandInfo 2 +NtGdiDoBanding 4 +NtGdiDoPalette 6 +NtGdiDrawEscape 4 +NtGdiEllipse 5 +NtGdiEnableEudc 1 +NtGdiEndDoc 1 +NtGdiEndPage 1 +NtGdiEndPath 1 +NtGdiEnumFontChunk 5 +NtGdiEnumFontClose 1 +NtGdiEnumFontOpen 7 +NtGdiEnumObjects 4 +NtGdiEqualRgn 2 +NtGdiEudcLoadUnloadLink 7 +NtGdiExcludeClipRect 5 +NtGdiExtCreatePen 11 +NtGdiExtCreateRegion 3 +NtGdiExtEscape 8 +NtGdiExtFloodFill 5 +NtGdiExtGetObjectW 3 +NtGdiExtSelectClipRgn 3 +NtGdiExtTextOutW 9 +NtGdiFillPath 1 +NtGdiFillRgn 3 +NtGdiFlattenPath 1 +NtGdiFlush 0 +NtGdiForceUFIMapping 2 +NtGdiFrameRgn 5 +NtGdiFullscreenControl 5 +NtGdiGetAndSetDCDword 4 +NtGdiGetAppClipBox 2 +NtGdiGetBitmapBits 3 +NtGdiGetBitmapDimension 2 +NtGdiGetBoundsRect 3 +NtGdiGetCertificate 4 +NtGdiGetCertificateSize 3 +NtGdiGetCharABCWidthsW 6 +NtGdiGetCharacterPlacementW 6 +NtGdiGetCharSet 1 +NtGdiGetCharWidthW 6 +NtGdiGetCharWidthInfo 2 +NtGdiGetColorAdjustment 2 +NtGdiGetColorSpaceforBitmap 1 +NtGdiGetCOPPCompatibleOPMInformation 3 +NtGdiGetDCDword 3 +NtGdiGetDCforBitmap 1 +NtGdiGetDCObject 2 +NtGdiGetDCPoint 3 +NtGdiGetDeviceCaps 2 +NtGdiGetDeviceGammaRamp 2 +NtGdiGetDeviceCapsAll 2 +NtGdiGetDIBitsInternal 9 +NtGdiGetETM 2 +NtGdiGetEudcTimeStampEx 3 +NtGdiGetFontData 5 +NtGdiGetFontResourceInfoInternalW 7 +NtGdiGetGlyphIndicesW 5 +NtGdiGetGlyphIndicesWInternal 6 +NtGdiGetGlyphOutline 8 +NtGdiGetOPMInformation 3 +NtGdiGetKerningPairs 3 +NtGdiGetLinkedUFIs 3 +NtGdiGetMiterLimit 2 +NtGdiGetMonitorID 3 +NtGdiGetNearestColor 2 +NtGdiGetNearestPaletteIndex 2 +NtGdiGetObjectBitmapHandle 2 +NtGdiGetOPMRandomNumber 2 +NtGdiGetOutlineTextMetricsInternalW 4 +NtGdiGetPath 4 +NtGdiGetPixel 3 +NtGdiGetRandomRgn 3 +NtGdiGetRasterizerCaps 2 +NtGdiGetRealizationInfo 3 +NtGdiGetRegionData 3 +NtGdiGetRgnBox 2 +NtGdiGetServerMetaFileBits 7 +NtGdiGetSpoolMessage 4 +NtGdiGetStats 5 +NtGdiGetStockObject 1 +NtGdiGetStringBitmapW 5 +NtGdiGetSuggestedOPMProtectedOutputArraySize 2 +NtGdiGetSystemPaletteUse 1 +NtGdiGetTextCharsetInfo 3 +NtGdiGetTextExtent 5 +NtGdiGetTextExtentExW 8 +NtGdiGetTextFaceW 4 +NtGdiGetTextMetricsW 3 +NtGdiGetTransform 3 +NtGdiGetUFI 6 +NtGdiGetEmbUFI 7 +NtGdiGetUFIPathname 10 +NtGdiGetEmbedFonts 0 +NtGdiChangeGhostFont 2 +NtGdiAddEmbFontToDC 2 +NtGdiGetFontUnicodeRanges 2 +NtGdiGetWidthTable 7 +NtGdiGradientFill 6 +NtGdiHfontCreate 5 +NtGdiIcmBrushInfo 8 +NtGdiInit 0 +NtGdiInitSpool 0 +NtGdiIntersectClipRect 5 +NtGdiInvertRgn 2 +NtGdiLineTo 3 +NtGdiMakeFontDir 5 +NtGdiMakeInfoDC 2 +NtGdiMaskBlt 13 +NtGdiModifyWorldTransform 3 +NtGdiMonoBitmap 1 +NtGdiMoveTo 4 +NtGdiOffsetClipRgn 3 +NtGdiOffsetRgn 3 +NtGdiOpenDCW 8 +NtGdiPatBlt 6 +NtGdiPolyPatBlt 5 +NtGdiPathToRegion 1 +NtGdiPlgBlt 11 +NtGdiPolyDraw 4 +NtGdiPolyPolyDraw 5 +NtGdiPolyTextOutW 4 +NtGdiPtInRegion 3 +NtGdiPtVisible 3 +NtGdiQueryFonts 3 +NtGdiQueryFontAssocInfo 1 +NtGdiRectangle 5 +NtGdiRectInRegion 2 +NtGdiRectVisible 2 +NtGdiRemoveFontResourceW 6 +NtGdiRemoveFontMemResourceEx 1 +NtGdiResetDC 5 +NtGdiResizePalette 2 +NtGdiRestoreDC 2 +NtGdiRoundRect 7 +NtGdiSaveDC 1 +NtGdiScaleViewportExtEx 6 +NtGdiScaleWindowExtEx 6 +NtGdiSelectBitmap 2 +NtGdiSelectBrush 2 +NtGdiSelectClipPath 2 +NtGdiSelectFont 2 +NtGdiSelectPen 2 +NtGdiSetBitmapAttributes 2 +NtGdiSetBitmapBits 3 +NtGdiSetBitmapDimension 4 +NtGdiSetBoundsRect 3 +NtGdiSetBrushAttributes 2 +NtGdiSetBrushOrg 4 +NtGdiSetColorAdjustment 2 +NtGdiSetColorSpace 2 +NtGdiSetDeviceGammaRamp 2 +NtGdiSetDIBitsToDeviceInternal 16 +NtGdiSetFontEnumeration 1 +NtGdiSetFontXform 3 +NtGdiSetIcmMode 3 +NtGdiSetLinkedUFIs 3 +NtGdiSetMagicColors 3 +NtGdiSetMetaRgn 1 +NtGdiSetMiterLimit 3 +NtGdiGetDeviceWidth 1 +NtGdiMirrorWindowOrg 1 +NtGdiSetLayout 3 +NtGdiSetOPMSigningKeyAndSequenceNumbers 2 +NtGdiSetPixel 4 +NtGdiSetPixelFormat 2 +NtGdiSetRectRgn 5 +NtGdiSetSystemPaletteUse 2 +NtGdiSetTextJustification 3 +NtGdiSetupPublicCFONT 3 +NtGdiSetVirtualResolution 5 +NtGdiSetSizeDevice 3 +NtGdiStartDoc 4 +NtGdiStartPage 1 +NtGdiStretchBlt 12 +NtGdiStretchDIBitsInternal 16 +NtGdiStrokeAndFillPath 1 +NtGdiStrokePath 1 +NtGdiSwapBuffers 1 +NtGdiTransformPoints 5 +NtGdiTransparentBlt 11 +NtGdiUnloadPrinterDriver 2 +NtGdiUnmapMemFont 1 +NtGdiUnrealizeObject 1 +NtGdiUpdateColors 1 +NtGdiWidenPath 1 +NtUserActivateKeyboardLayout 2 +NtUserAddClipboardFormatListener 1 +NtUserAlterWindowStyle 3 +NtUserAssociateInputContext 3 +NtUserAttachThreadInput 3 +NtUserBeginPaint 2 +NtUserBitBltSysBmp 8 +NtUserBlockInput 1 +NtUserBuildHimcList 4 +NtUserBuildHwndList 7 +NtUserBuildNameList 4 +NtUserBuildPropList 4 +NtUserCallHwnd 2 +NtUserCallHwndLock 2 +NtUserCallHwndOpt 2 +NtUserCallHwndParam 3 +NtUserCallHwndParamLock 3 +NtUserCallMsgFilter 2 +NtUserCallNextHookEx 4 +NtUserCallNoParam 1 +NtUserCallOneParam 2 +NtUserCallTwoParam 3 +NtUserChangeClipboardChain 2 +NtUserChangeDisplaySettings 4 +NtUserCheckAccessForIntegrityLevel 3 +NtUserCheckDesktopByThreadId 1 +NtUserCheckWindowThreadDesktop 3 +NtUserCheckImeHotKey 2 +NtUserCheckMenuItem 3 +NtUserChildWindowFromPointEx 4 +NtUserClipCursor 1 +NtUserCloseClipboard 0 +NtUserCloseDesktop 1 +NtUserCloseWindowStation 1 +NtUserConsoleControl 3 +NtUserConvertMemHandle 2 +NtUserCopyAcceleratorTable 3 +NtUserCountClipboardFormats 0 +NtUserCreateAcceleratorTable 2 +NtUserCreateCaret 4 +NtUserCreateDesktopEx 6 +NtUserCreateInputContext 1 +NtUserCreateLocalMemHandle 4 +NtUserCreateWindowEx 15 +NtUserCreateWindowStation 7 +NtUserDdeInitialize 5 +NtUserDeferWindowPos 8 +NtUserDefSetText 2 +NtUserDeleteMenu 3 +NtUserDestroyAcceleratorTable 1 +NtUserDestroyCursor 2 +NtUserDestroyInputContext 1 +NtUserDestroyMenu 1 +NtUserDestroyWindow 1 +NtUserDisableThreadIme 1 +NtUserDispatchMessage 1 +NtUserDoSoundConnect 0 +NtUserDoSoundDisconnect 0 +NtUserDragDetect 3 +NtUserDragObject 5 +NtUserDrawAnimatedRects 4 +NtUserDrawCaption 4 +NtUserDrawCaptionTemp 7 +NtUserDrawIconEx 11 +NtUserDrawMenuBarTemp 5 +NtUserEmptyClipboard 0 +NtUserEnableMenuItem 3 +NtUserEnableScrollBar 3 +NtUserEndDeferWindowPosEx 2 +NtUserEndMenu 0 +NtUserEndPaint 2 +NtUserEnumDisplayDevices 4 +NtUserEnumDisplayMonitors 4 +NtUserEnumDisplaySettings 4 +NtUserEvent 1 +NtUserExcludeUpdateRgn 2 +NtUserFillWindow 4 +NtUserFindExistingCursorIcon 3 +NtUserFindWindowEx 5 +NtUserFlashWindowEx 1 +NtUserFrostCrashedWindow 2 +NtUserGetAltTabInfo 6 +NtUserGetAncestor 2 +NtUserGetAppImeLevel 1 +NtUserGetAsyncKeyState 1 +NtUserGetAtomName 2 +NtUserGetCaretBlinkTime 0 +NtUserGetCaretPos 1 +NtUserGetClassInfoEx 5 +NtUserGetClassName 3 +NtUserGetClipboardData 2 +NtUserGetClipboardFormatName 3 +NtUserGetClipboardOwner 0 +NtUserGetClipboardSequenceNumber 0 +NtUserGetClipboardViewer 0 +NtUserGetClipCursor 1 +NtUserGetComboBoxInfo 2 +NtUserGetControlBrush 3 +NtUserGetControlColor 4 +NtUserGetCPD 3 +NtUserGetCursorFrameInfo 4 +NtUserGetCursorInfo 1 +NtUserGetDC 1 +NtUserGetDCEx 3 +NtUserGetDoubleClickTime 0 +NtUserGetForegroundWindow 0 +NtUserGetGuiResources 2 +NtUserGetGUIThreadInfo 2 +NtUserGetIconInfo 6 +NtUserGetIconSize 4 +NtUserGetImeHotKey 4 +NtUserGetImeInfoEx 2 +NtUserGetInternalWindowPos 3 +NtUserGetKeyboardLayoutList 2 +NtUserGetKeyboardLayoutName 1 +NtUserGetKeyboardState 1 +NtUserGetKeyNameText 3 +NtUserGetKeyState 1 +NtUserGetListBoxInfo 1 +NtUserGetMenuBarInfo 4 +NtUserGetMenuIndex 2 +NtUserGetMenuItemRect 4 +NtUserGetMessage 4 +NtUserGetMouseMovePointsEx 5 +NtUserGetObjectInformation 5 +NtUserGetOpenClipboardWindow 0 +NtUserGetPriorityClipboardFormat 2 +NtUserGetProcessWindowStation 0 +NtUserGetRawInputBuffer 3 +NtUserGetRawInputData 5 +NtUserGetRawInputDeviceInfo 4 +NtUserGetRawInputDeviceList 3 +NtUserGetRegisteredRawInputDevices 3 +NtUserGetScrollBarInfo 3 +NtUserGetSystemMenu 2 +NtUserGetThreadDesktop 2 +NtUserGetThreadState 1 +NtUserGetTitleBarInfo 2 +NtUserGetUpdatedClipboardFormats 3 +NtUserGetUpdateRect 3 +NtUserGetUpdateRgn 3 +NtUserGetWindowDC 1 +NtUserGetWindowPlacement 2 +NtUserGetWOWClass 2 +NtUserGhostWindowFromHungWindow 1 +NtUserHardErrorControl 3 +NtUserHideCaret 1 +NtUserHiliteMenuItem 4 +NtUserHungWindowFromGhostWindow 1 +NtUserImpersonateDdeClientWindow 2 +NtUserInitialize 2 +NtUserInitializeClientPfnArrays 4 +NtUserInitTask 12 +NtUserInternalGetWindowText 3 +NtUserInternalGetWindowIcon 2 +NtUserInvalidateRect 3 +NtUserInvalidateRgn 3 +NtUserIsClipboardFormatAvailable 1 +NtUserKillTimer 2 +NtUserLoadKeyboardLayoutEx 7 +NtUserLockWindowStation 1 +NtUserLockWindowUpdate 1 +NtUserLockWorkStation 0 +NtUserLogicalToPhysicalPoint 2 +NtUserMapVirtualKeyEx 4 +NtUserMenuItemFromPoint 4 +NtUserMessageCall 7 +NtUserMinMaximize 3 +NtUserMNDragLeave 0 +NtUserMNDragOver 2 +NtUserModifyUserStartupInfoFlags 2 +NtUserMoveWindow 6 +NtUserNotifyIMEStatus 3 +NtUserNotifyProcessCreate 4 +NtUserNotifyWinEvent 4 +NtUserOpenClipboard 2 +NtUserOpenDesktop 3 +NtUserOpenInputDesktop 3 +NtUserOpenThreadDesktop 5 +NtUserOpenWindowStation 2 +NtUserPaintDesktop 1 +NtUserPaintMonitor 3 +NtUserPeekMessage 5 +NtUserPhysicalToLogicalPoint 2 +NtUserPostMessage 4 +NtUserPostThreadMessage 4 +NtUserPrintWindow 3 +NtUserProcessConnect 2 +NtUserQueryInformationThread 4 +NtUserQueryInputContext 2 +NtUserQuerySendMessage 1 +NtUserQueryWindow 2 +NtUserRealChildWindowFromPoint 3 +NtUserRealInternalGetMessage 6 +NtUserRealWaitMessageEx 2 +NtUserRedrawWindow 4 +NtUserRegisterClassExWOW 7 +NtUserRegisterErrorReportingDialog 2 +NtUserRegisterUserApiHook 4 +NtUserRegisterHotKey 4 +NtUserRegisterRawInputDevices 3 +NtUserRegisterTasklist 1 +NtUserRegisterWindowMessage 1 +NtUserRemoveClipboardFormatListener 1 +NtUserRemoveMenu 3 +NtUserRemoveProp 2 +NtUserResolveDesktop 4 +NtUserResolveDesktopForWOW 1 +NtUserSBGetParms 4 +NtUserScrollDC 7 +NtUserScrollWindowEx 8 +NtUserSelectPalette 3 +NtUserSendInput 3 +NtUserSetActiveWindow 1 +NtUserSetAppImeLevel 2 +NtUserSetCapture 1 +NtUserSetClassLong 4 +NtUserSetClassWord 3 +NtUserSetClipboardData 3 +NtUserSetClipboardViewer 1 +NtUserSetConsoleReserveKeys 2 +NtUserSetCursor 1 +NtUserSetCursorContents 2 +NtUserSetCursorIconData 4 +NtUserSetFocus 1 +NtUserSetImeHotKey 5 +NtUserSetImeInfoEx 1 +NtUserSetImeOwnerWindow 2 +NtUserSetInformationProcess 4 +NtUserSetInformationThread 4 +NtUserSetInternalWindowPos 4 +NtUserSetKeyboardState 1 +NtUserSetMenu 3 +NtUserSetMenuContextHelpId 2 +NtUserSetMenuDefaultItem 3 +NtUserSetMenuFlagRtoL 1 +NtUserSetObjectInformation 4 +NtUserSetParent 2 +NtUserSetProcessWindowStation 1 +NtUserGetProp 2 +NtUserSetProp 3 +NtUserSetScrollInfo 4 +NtUserSetShellWindowEx 2 +NtUserSetSysColors 4 +NtUserSetSystemCursor 2 +NtUserSetSystemMenu 2 +NtUserSetSystemTimer 3 +NtUserSetThreadDesktop 1 +NtUserSetThreadLayoutHandles 2 +NtUserSetThreadState 2 +NtUserSetTimer 4 +NtUserSetProcessDPIAware 0 +NtUserSetWindowFNID 2 +NtUserSetWindowLong 4 +NtUserSetWindowPlacement 2 +NtUserSetWindowPos 7 +NtUserSetWindowRgn 3 +NtUserGetWindowRgnEx 3 +NtUserSetWindowRgnEx 3 +NtUserSetWindowsHookAW 3 +NtUserSetWindowsHookEx 6 +NtUserSetWindowStationUser 4 +NtUserSetWindowWord 3 +NtUserSetWinEventHook 8 +NtUserShowCaret 1 +NtUserShowScrollBar 3 +NtUserShowWindow 2 +NtUserShowWindowAsync 2 +NtUserSoundSentry 0 +NtUserSwitchDesktop 2 +NtUserSystemParametersInfo 4 +NtUserTestForInteractiveUser 1 +NtUserThunkedMenuInfo 2 +NtUserThunkedMenuItemInfo 6 +NtUserToUnicodeEx 7 +NtUserTrackMouseEvent 1 +NtUserTrackPopupMenuEx 6 +NtUserCalcMenuBar 5 +NtUserPaintMenuBar 6 +NtUserTranslateAccelerator 3 +NtUserTranslateMessage 2 +NtUserUnhookWindowsHookEx 1 +NtUserUnhookWinEvent 1 +NtUserUnloadKeyboardLayout 1 +NtUserUnlockWindowStation 1 +NtUserUnregisterClass 3 +NtUserUnregisterUserApiHook 0 +NtUserUnregisterHotKey 2 +NtUserUpdateInputContext 3 +NtUserUpdateInstance 3 +NtUserUpdateLayeredWindow 10 +NtUserGetLayeredWindowAttributes 4 +NtUserSetLayeredWindowAttributes 4 +NtUserUpdatePerUserSystemParameters 1 +NtUserUserHandleGrantAccess 3 +NtUserValidateHandleSecure 1 +NtUserValidateRect 2 +NtUserValidateTimerCallback 1 +NtUserVkKeyScanEx 3 +NtUserWaitForInputIdle 3 +NtUserWaitForMsgAndEvent 1 +NtUserWaitMessage 0 +NtUserWin32PoolAllocationStats 6 +NtUserWindowFromPhysicalPoint 2 +NtUserWindowFromPoint 2 +NtUserYieldTask 0 +NtUserRemoteConnect 3 +NtUserRemoteRedrawRectangle 4 +NtUserRemoteRedrawScreen 0 +NtUserRemoteStopScreenUpdates 0 +NtUserCtxDisplayIOCtl 3 +NtUserRegisterSessionPort 1 +NtUserUnregisterSessionPort 0 +NtUserUpdateWindowTransform 3 +NtUserDwmStartRedirection 1 +NtUserDwmStopRedirection 0 +NtUserDwmHintDxUpdate 2 +NtUserDwmGetDxRgn 3 +NtUserGetWindowMinimizeRect 2 +NtGdiEngAssociateSurface 3 +NtGdiEngCreateBitmap 6 +NtGdiEngCreateDeviceSurface 4 +NtGdiEngCreateDeviceBitmap 4 +NtGdiEngCreatePalette 6 +NtGdiEngComputeGlyphSet 3 +NtGdiEngCopyBits 6 +NtGdiEngDeletePalette 1 +NtGdiEngDeleteSurface 1 +NtGdiEngEraseSurface 3 +NtGdiEngUnlockSurface 1 +NtGdiEngLockSurface 1 +NtGdiEngBitBlt 11 +NtGdiEngStretchBlt 11 +NtGdiEngPlgBlt 11 +NtGdiEngMarkBandingSurface 1 +NtGdiEngStrokePath 8 +NtGdiEngFillPath 7 +NtGdiEngStrokeAndFillPath 10 +NtGdiEngPaint 5 +NtGdiEngLineTo 9 +NtGdiEngAlphaBlend 7 +NtGdiEngGradientFill 10 +NtGdiEngTransparentBlt 8 +NtGdiEngTextOut 10 +NtGdiEngStretchBltROP 13 +NtGdiXLATEOBJ_cGetPalette 4 +NtGdiXLATEOBJ_iXlate 2 +NtGdiXLATEOBJ_hGetColorTransform 1 +NtGdiCLIPOBJ_bEnum 3 +NtGdiCLIPOBJ_cEnumStart 5 +NtGdiCLIPOBJ_ppoGetPath 1 +NtGdiEngDeletePath 1 +NtGdiEngCreateClip 0 +NtGdiEngDeleteClip 1 +NtGdiBRUSHOBJ_ulGetBrushColor 1 +NtGdiBRUSHOBJ_pvAllocRbrush 2 +NtGdiBRUSHOBJ_pvGetRbrush 1 +NtGdiBRUSHOBJ_hGetColorTransform 1 +NtGdiXFORMOBJ_bApplyXform 5 +NtGdiXFORMOBJ_iGetXform 2 +NtGdiFONTOBJ_vGetInfo 3 +NtGdiFONTOBJ_pxoGetXform 1 +NtGdiFONTOBJ_cGetGlyphs 5 +NtGdiFONTOBJ_pifi 1 +NtGdiFONTOBJ_pfdg 1 +NtGdiFONTOBJ_pQueryGlyphAttrs 2 +NtGdiFONTOBJ_pvTrueTypeFontFile 2 +NtGdiFONTOBJ_cGetAllGlyphHandles 2 +NtGdiSTROBJ_bEnum 3 +NtGdiSTROBJ_bEnumPositionsOnly 3 +NtGdiSTROBJ_bGetAdvanceWidths 4 +NtGdiSTROBJ_vEnumStart 1 +NtGdiSTROBJ_dwGetCodePage 1 +NtGdiPATHOBJ_vGetBounds 2 +NtGdiPATHOBJ_bEnum 2 +NtGdiPATHOBJ_vEnumStart 1 +NtGdiPATHOBJ_vEnumStartClipLines 4 +NtGdiPATHOBJ_bEnumClipLines 3 +NtGdiGetDhpdev 1 +NtGdiEngCheckAbort 1 +NtGdiHT_Get8BPPFormatPalette 4 +NtGdiHT_Get8BPPMaskPalette 6 +NtGdiUpdateTransform 1 +NtGdiSetPUMPDOBJ 4 +NtGdiBRUSHOBJ_DeleteRbrush 2 +NtGdiUMPDEngFreeUserMem 1 +NtGdiDrawStream 3 +NtGdiDwmGetDirtyRgn 5 +NtGdiDwmGetSurfaceData 2 +NtGdiDdDDICreateAllocation 1 +NtGdiDdDDIQueryResourceInfo 1 +NtGdiDdDDIOpenResource 1 +NtGdiDdDDIDestroyAllocation 1 +NtGdiDdDDISetAllocationPriority 1 +NtGdiDdDDIQueryAllocationResidency 1 +NtGdiDdDDICreateDevice 1 +NtGdiDdDDIDestroyDevice 1 +NtGdiDdDDICreateContext 1 +NtGdiDdDDIDestroyContext 1 +NtGdiDdDDICreateSynchronizationObject 1 +NtGdiDdDDIDestroySynchronizationObject 1 +NtGdiDdDDIWaitForSynchronizationObject 1 +NtGdiDdDDISignalSynchronizationObject 1 +NtGdiDdDDIGetRuntimeData 1 +NtGdiDdDDIQueryAdapterInfo 1 +NtGdiDdDDILock 1 +NtGdiDdDDIUnlock 1 +NtGdiDdDDIGetDisplayModeList 1 +NtGdiDdDDISetDisplayMode 1 +NtGdiDdDDIGetMultisampleMethodList 1 +NtGdiDdDDIPresent 1 +NtGdiDdDDIRender 1 +NtGdiDdDDIOpenAdapterFromDeviceName 1 +NtGdiDdDDIOpenAdapterFromHdc 1 +NtGdiDdDDICloseAdapter 1 +NtGdiDdDDIGetSharedPrimaryHandle 1 +NtGdiDdDDIEscape 1 +NtGdiDdDDIQueryStatistics 1 +NtGdiDdDDISetVidPnSourceOwner 1 +NtGdiDdDDIGetPresentHistory 1 +NtGdiDdDDICreateOverlay 1 +NtGdiDdDDIUpdateOverlay 1 +NtGdiDdDDIFlipOverlay 1 +NtGdiDdDDIDestroyOverlay 1 +NtGdiDdDDIWaitForVerticalBlankEvent 1 +NtGdiDdDDISetGammaRamp 1 +NtGdiDdDDIGetDeviceState 1 +NtGdiDdDDICreateDCFromMemory 1 +NtGdiDdDDIDestroyDCFromMemory 1 +NtGdiDdDDISetContextSchedulingPriority 1 +NtGdiDdDDIGetContextSchedulingPriority 1 +NtGdiDdDDISetProcessSchedulingPriorityClass 2 +NtGdiDdDDIGetProcessSchedulingPriorityClass 2 +NtGdiDdDDIReleaseProcessVidPnSourceOwners 1 +NtGdiDdDDIGetScanLine 1 +NtGdiDdDDISetQueuedLimit 1 +NtGdiDdDDIPollDisplayChildren 1 +NtGdiDdDDIInvalidateActiveVidPn 1 +NtGdiDdDDICheckOcclusion 1 +NtGdiDdDDIWaitForIdle 1 +NtGdiDdDDICheckMonitorPowerState 1 +NtGdiDdDDICheckExclusiveOwnership 0 +NtGdiDdDDISetDisplayPrivateDriverFormat 1 +NtGdiDdDDISharedPrimaryLockNotification 1 +NtGdiDdDDISharedPrimaryUnLockNotification 1 +NtGdiMakeObjectXferable 2 +NtGdiMakeObjectUnXferable 1 +NtGdiGetNumberOfPhysicalMonitors 2 +NtGdiGetPhysicalMonitors 4 +NtGdiGetPhysicalMonitorDescription 3 +NtGdiDestroyPhysicalMonitor 1 +NtGdiDDCCIGetVCPFeature 5 +NtGdiDDCCISetVCPFeature 3 +NtGdiDDCCISaveCurrentSettings 1 +NtGdiDDCCIGetCapabilitiesStringLength 2 +NtGdiDDCCIGetCapabilitiesString 3 +NtGdiDDCCIGetTimingReport 2 +NtUserSetMirrorRendering 2 +NtUserShowSystemCursor 1 diff --git a/rostests/apitests/w32kdll/w32kdll_xpsp2/w32k_xpsp2-x86.db b/rostests/apitests/w32kdll/w32kdll_xpsp2/w32k_xpsp2-x86.db new file mode 100644 index 00000000000..7db341886d9 --- /dev/null +++ b/rostests/apitests/w32kdll/w32kdll_xpsp2/w32k_xpsp2-x86.db @@ -0,0 +1,670 @@ +# +# win32k systemcalls taken from Windows XP SP2 x86 +# +NtGdiAbortDoc 1 +NtGdiAbortPath 1 +NtGdiAddFontResourceW 6 +NtGdiAddRemoteFontToDC 4 +NtGdiAddFontMemResourceEx 5 +NtGdiRemoveMergeFont 2 +NtGdiAddRemoteMMInstanceToDC 3 +NtGdiAlphaBlend 12 +NtGdiAngleArc 6 +NtGdiAnyLinkedFonts 0 +NtGdiFontIsLinked 1 +NtGdiArcInternal 10 +NtGdiBeginPath 1 +NtGdiBitBlt 11 +NtGdiCancelDC 1 +NtGdiCheckBitmapBits 8 +NtGdiCloseFigure 1 +NtGdiClearBitmapAttributes 2 +NtGdiClearBrushAttributes 2 +NtGdiColorCorrectPalette 6 +NtGdiCombineRgn 4 +NtGdiCombineTransform 3 +NtGdiComputeXformCoefficients 1 +NtGdiConsoleTextOut 4 +NtGdiConvertMetafileRect 2 +NtGdiCreateBitmap 5 +NtGdiCreateClientObj 1 +NtGdiCreateColorSpace 1 +NtGdiCreateColorTransform 8 +NtGdiCreateCompatibleBitmap 3 +NtGdiCreateCompatibleDC 1 +NtGdiCreateDIBBrush 6 +NtGdiCreateDIBitmapInternal 11 +NtGdiCreateDIBSection 9 +NtGdiCreateEllipticRgn 4 +NtGdiCreateHalftonePalette 1 +NtGdiCreateHatchBrushInternal 3 +NtGdiCreateMetafileDC 1 +NtGdiCreatePaletteInternal 2 +NtGdiCreatePatternBrushInternal 3 +NtGdiCreatePen 4 +NtGdiCreateRectRgn 4 +NtGdiCreateRoundRectRgn 6 +NtGdiCreateServerMetaFile 6 +NtGdiCreateSolidBrush 2 +NtGdiD3dContextCreate 4 +NtGdiD3dContextDestroy 1 +NtGdiD3dContextDestroyAll 1 +NtGdiD3dValidateTextureStageState 1 +NtGdiD3dDrawPrimitives2 7 +NtGdiDdGetDriverState 1 +NtGdiDdAddAttachedSurface 3 +NtGdiDdAlphaBlt 3 +NtGdiDdAttachSurface 2 +NtGdiDdBeginMoCompFrame 2 +NtGdiDdBlt 3 +NtGdiDdCanCreateSurface 2 +NtGdiDdCanCreateD3DBuffer 2 +NtGdiDdColorControl 2 +NtGdiDdCreateDirectDrawObject 1 +NtGdiDdCreateSurface 8 +NtGdiDdCreateD3DBuffer 8 +NtGdiDdCreateMoComp 2 +NtGdiDdCreateSurfaceObject 6 +NtGdiDdDeleteDirectDrawObject 1 +NtGdiDdDeleteSurfaceObject 1 +NtGdiDdDestroyMoComp 2 +NtGdiDdDestroySurface 2 +NtGdiDdDestroyD3DBuffer 1 +NtGdiDdEndMoCompFrame 2 +NtGdiDdFlip 5 +NtGdiDdFlipToGDISurface 2 +NtGdiDdGetAvailDriverMemory 2 +NtGdiDdGetBltStatus 2 +NtGdiDdGetDC 2 +NtGdiDdGetDriverInfo 2 +NtGdiDdGetDxHandle 3 +NtGdiDdGetFlipStatus 2 +NtGdiDdGetInternalMoCompInfo 2 +NtGdiDdGetMoCompBuffInfo 2 +NtGdiDdGetMoCompGuids 2 +NtGdiDdGetMoCompFormats 2 +NtGdiDdGetScanLine 2 +NtGdiDdLock 3 +NtGdiDdLockD3D 2 +NtGdiDdQueryDirectDrawObject 11 +NtGdiDdQueryMoCompStatus 2 +NtGdiDdReenableDirectDrawObject 2 +NtGdiDdReleaseDC 1 +NtGdiDdRenderMoComp 2 +NtGdiDdResetVisrgn 2 +NtGdiDdSetColorKey 2 +NtGdiDdSetExclusiveMode 2 +NtGdiDdSetGammaRamp 3 +NtGdiDdCreateSurfaceEx 3 +NtGdiDdSetOverlayPosition 3 +NtGdiDdUnattachSurface 2 +NtGdiDdUnlock 2 +NtGdiDdUnlockD3D 2 +NtGdiDdUpdateOverlay 3 +NtGdiDdWaitForVerticalBlank 2 +NtGdiDvpCanCreateVideoPort 2 +NtGdiDvpColorControl 2 +NtGdiDvpCreateVideoPort 2 +NtGdiDvpDestroyVideoPort 2 +NtGdiDvpFlipVideoPort 4 +NtGdiDvpGetVideoPortBandwidth 2 +NtGdiDvpGetVideoPortField 2 +NtGdiDvpGetVideoPortFlipStatus 2 +NtGdiDvpGetVideoPortInputFormats 2 +NtGdiDvpGetVideoPortLine 2 +NtGdiDvpGetVideoPortOutputFormats 2 +NtGdiDvpGetVideoPortConnectInfo 2 +NtGdiDvpGetVideoSignalStatus 2 +NtGdiDvpUpdateVideoPort 4 +NtGdiDvpWaitForVideoPortSync 2 +NtGdiDvpAcquireNotification 3 +NtGdiDvpReleaseNotification 2 +NtGdiDxgGenericThunk 6 +NtGdiDeleteClientObj 1 +NtGdiDeleteColorSpace 1 +NtGdiDeleteColorTransform 2 +NtGdiDeleteObjectApp 1 +NtGdiDescribePixelFormat 4 +NtGdiGetPerBandInfo 2 +NtGdiDoBanding 4 +NtGdiDoPalette 6 +NtGdiDrawEscape 4 +NtGdiEllipse 5 +NtGdiEnableEUDC 1 +NtGdiEndDoc 1 +NtGdiEndPage 1 +NtGdiEndPath 1 +NtGdiEnumFontChunk 5 +NtGdiEnumFontClose 1 +NtGdiEnumFontOpen 7 +NtGdiEnumObjects 4 +NtGdiEqualRgn 2 +NtGdiEudcLoadUnloadLink 7 +NtGdiExcludeClipRect 5 +NtGdiExtCreatePen 11 +NtGdiExtCreateRegion 3 +NtGdiExtEscape 8 +NtGdiExtFloodFill 5 +NtGdiExtGetObjectW 3 +NtGdiExtSelectClipRgn 3 +NtGdiExtTextOutW 9 +NtGdiFillPath 1 +NtGdiFillRgn 3 +NtGdiFlattenPath 1 +NtGdiFlushUserBatch 0 +NtGdiFlush 0 +NtGdiForceUFIMapping 2 +NtGdiFrameRgn 5 +NtGdiFullscreenControl 5 +NtGdiGetAndSetDCDword 4 +NtGdiGetAppClipBox 2 +NtGdiGetBitmapBits 3 +NtGdiGetBitmapDimension 2 +NtGdiGetBoundsRect 3 +NtGdiGetCharABCWidthsW 6 +NtGdiGetCharacterPlacementW 6 +NtGdiGetCharSet 1 +NtGdiGetCharWidthW 6 +NtGdiGetCharWidthInfo 2 +NtGdiGetColorAdjustment 2 +NtGdiGetColorSpaceforBitmap 1 +NtGdiGetDCDword 3 +NtGdiGetDCforBitmap 1 +NtGdiGetDCObject 2 +NtGdiGetDCPoint 3 +NtGdiGetDeviceCaps 2 +NtGdiGetDeviceGammaRamp 2 +NtGdiGetDeviceCapsAll 2 +NtGdiGetDIBitsInternal 9 +NtGdiGetETM 2 +NtGdiGetEudcTimeStampEx 3 +NtGdiGetFontData 5 +NtGdiGetFontResourceInfoInternalW 7 +NtGdiGetGlyphIndicesW 5 +NtGdiGetGlyphIndicesWInternal 6 +NtGdiGetGlyphOutline 8 +NtGdiGetKerningPairs 3 +NtGdiGetLinkedUFIs 3 +NtGdiGetMiterLimit 2 +NtGdiGetMonitorID 3 +NtGdiGetNearestColor 2 +NtGdiGetNearestPaletteIndex 2 +NtGdiGetObjectBitmapHandle 2 +NtGdiGetOutlineTextMetricsInternalW 4 +NtGdiGetPath 4 +NtGdiGetPixel 3 +NtGdiGetRandomRgn 3 +NtGdiGetRasterizerCaps 2 +NtGdiGetRealizationInfo 3 +NtGdiGetRegionData 3 +NtGdiGetRgnBox 2 +NtGdiGetServerMetaFileBits 7 +NtGdiGetSpoolMessage 4 +NtGdiGetStats 5 +NtGdiGetStockObject 1 +NtGdiGetStringBitmapW 5 +NtGdiGetSystemPaletteUse 1 +NtGdiGetTextCharsetInfo 3 +NtGdiGetTextExtent 5 +NtGdiGetTextExtentExW 8 +NtGdiGetTextFaceW 4 +NtGdiGetTextMetricsW 3 +NtGdiGetTransform 3 +NtGdiGetUFI 6 +NtGdiGetEmbUFI 7 +NtGdiGetUFIPathname 10 +NtGdiGetEmbedFonts 0 +NtGdiChangeGhostFont 2 +NtGdiAddEmbFontToDC 2 +NtGdiGetFontUnicodeRanges 2 +NtGdiGetWidthTable 7 +NtGdiGradientFill 6 +NtGdiHfontCreate 5 +NtGdiIcmBrushInfo 8 +NtGdiInit 0 +NtGdiInitSpool 0 +NtGdiIntersectClipRect 5 +NtGdiInvertRgn 2 +NtGdiLineTo 3 +NtGdiMakeFontDir 5 +NtGdiMakeInfoDC 2 +NtGdiMaskBlt 13 +NtGdiModifyWorldTransform 3 +NtGdiMonoBitmap 1 +NtGdiMoveTo 4 +NtGdiOffsetClipRgn 3 +NtGdiOffsetRgn 3 +NtGdiOpenDCW 7 +NtGdiPatBlt 6 +NtGdiPolyPatBlt 5 +NtGdiPathToRegion 1 +NtGdiPlgBlt 11 +NtGdiPolyDraw 4 +NtGdiPolyPolyDraw 5 +NtGdiPolyTextOutW 4 +NtGdiPtInRegion 3 +NtGdiPtVisible 3 +NtGdiQueryFonts 3 +NtGdiQueryFontAssocInfo 1 +NtGdiRectangle 5 +NtGdiRectInRegion 2 +NtGdiRectVisible 2 +NtGdiRemoveFontResourceW 6 +NtGdiRemoveFontMemResourceEx 1 +NtGdiResetDC 5 +NtGdiResizePalette 2 +NtGdiRestoreDC 2 +NtGdiRoundRect 7 +NtGdiSaveDC 1 +NtGdiScaleViewportExtEx 6 +NtGdiScaleWindowExtEx 6 +NtGdiSelectBitmap 2 +NtGdiSelectBrush 2 +NtGdiSelectClipPath 2 +NtGdiSelectFont 2 +NtGdiSelectPen 2 +NtGdiSetBitmapAttributes 2 +NtGdiSetBitmapBits 3 +NtGdiSetBitmapDimension 4 +NtGdiSetBoundsRect 3 +NtGdiSetBrushAttributes 2 +NtGdiSetBrushOrg 4 +NtGdiSetColorAdjustment 2 +NtGdiSetColorSpace 2 +NtGdiSetDeviceGammaRamp 2 +NtGdiSetDIBitsToDeviceInternal 16 +NtGdiSetFontEnumeration 1 +NtGdiSetFontXform 3 +NtGdiSetIcmMode 3 +NtGdiSetLinkedUFIs 3 +NtGdiSetMagicColors 3 +NtGdiSetMetaRgn 1 +NtGdiSetMiterLimit 3 +NtGdiGetDeviceWidth 1 +NtGdiMirrorWindowOrg 1 +NtGdiSetLayout 3 +NtGdiSetPixel 4 +NtGdiSetPixelFormat 2 +NtGdiSetRectRgn 5 +NtGdiSetSystemPaletteUse 2 +NtGdiSetTextJustification 3 +NtGdiSetupPublicCFONT 3 +NtGdiSetVirtualResolution 5 +NtGdiSetSizeDevice 3 +NtGdiStartDoc 4 +NtGdiStartPage 1 +NtGdiStretchBlt 12 +NtGdiStretchDIBitsInternal 16 +NtGdiStrokeAndFillPath 1 +NtGdiStrokePath 1 +NtGdiSwapBuffers 1 +NtGdiTransformPoints 5 +NtGdiTransparentBlt 11 +NtGdiUnloadPrinterDriver 2 +NtGdiUnmapMemFont 1 +NtGdiUnrealizeObject 1 +NtGdiUpdateColors 1 +NtGdiWidenPath 1 +NtUserActivateKeyboardLayout 2 +NtUserAlterWindowStyle 3 +NtUserAssociateInputContext 3 +NtUserAttachThreadInput 3 +NtUserBeginPaint 2 +NtUserBitBltSysBmp 8 +NtUserBlockInput 1 +NtUserBuildHimcList 4 +NtUserBuildHwndList 7 +NtUserBuildNameList 4 +NtUserBuildPropList 4 +NtUserCallHwnd 2 +NtUserCallHwndLock 2 +NtUserCallHwndOpt 2 +NtUserCallHwndParam 3 +NtUserCallHwndParamLock 3 +NtUserCallMsgFilter 2 +NtUserCallNextHookEx 4 +NtUserCallNoParam 1 +NtUserCallOneParam 2 +NtUserCallTwoParam 3 +NtUserChangeClipboardChain 2 +NtUserChangeDisplaySettings 5 +NtUserCheckImeHotKey 2 +NtUserCheckMenuItem 3 +NtUserChildWindowFromPointEx 4 +NtUserClipCursor 1 +NtUserCloseClipboard 0 +NtUserCloseDesktop 1 +NtUserCloseWindowStation 1 +NtUserConsoleControl 3 +NtUserConvertMemHandle 2 +NtUserCopyAcceleratorTable 3 +NtUserCountClipboardFormats 0 +NtUserCreateAcceleratorTable 2 +NtUserCreateCaret 4 +NtUserCreateDesktop 5 +NtUserCreateInputContext 1 +NtUserCreateLocalMemHandle 4 +NtUserCreateWindowEx 15 +NtUserCreateWindowStation 7 +NtUserDdeGetQualityOfService 3 +NtUserDdeInitialize 5 +NtUserDdeSetQualityOfService 3 +NtUserDeferWindowPos 8 +NtUserDefSetText 2 +NtUserDeleteMenu 3 +NtUserDestroyAcceleratorTable 1 +NtUserDestroyCursor 2 +NtUserDestroyInputContext 1 +NtUserDestroyMenu 1 +NtUserDestroyWindow 1 +NtUserDisableThreadIme 1 +NtUserDispatchMessage 1 +NtUserDragDetect 3 +NtUserDragObject 5 +NtUserDrawAnimatedRects 4 +NtUserDrawCaption 4 +NtUserDrawCaptionTemp 7 +NtUserDrawIconEx 11 +NtUserDrawMenuBarTemp 5 +NtUserEmptyClipboard 0 +NtUserEnableMenuItem 3 +NtUserEnableScrollBar 3 +NtUserEndDeferWindowPosEx 2 +NtUserEndMenu 0 +NtUserEndPaint 2 +NtUserEnumDisplayDevices 4 +NtUserEnumDisplayMonitors 4 +NtUserEnumDisplaySettings 4 +NtUserEvent 1 +NtUserExcludeUpdateRgn 2 +NtUserFillWindow 4 +NtUserFindExistingCursorIcon 3 +NtUserFindWindowEx 5 +NtUserFlashWindowEx 1 +NtUserGetAltTabInfo 6 +NtUserGetAncestor 2 +NtUserGetAppImeLevel 1 +NtUserGetAsyncKeyState 1 +NtUserGetAtomName 2 +NtUserGetCaretBlinkTime 0 +NtUserGetCaretPos 1 +NtUserGetClassInfo 5 +NtUserGetClassName 3 +NtUserGetClipboardData 2 +NtUserGetClipboardFormatName 3 +NtUserGetClipboardOwner 0 +NtUserGetClipboardSequenceNumber 0 +NtUserGetClipboardViewer 0 +NtUserGetClipCursor 1 +NtUserGetComboBoxInfo 2 +NtUserGetControlBrush 3 +NtUserGetControlColor 4 +NtUserGetCPD 3 +NtUserGetCursorFrameInfo 4 +NtUserGetCursorInfo 1 +NtUserGetDC 1 +NtUserGetDCEx 3 +NtUserGetDoubleClickTime 0 +NtUserGetForegroundWindow 0 +NtUserGetGuiResources 2 +NtUserGetGUIThreadInfo 2 +NtUserGetIconInfo 6 +NtUserGetIconSize 4 +NtUserGetImeHotKey 4 +NtUserGetImeInfoEx 2 +NtUserGetInternalWindowPos 3 +NtUserGetKeyboardLayoutList 2 +NtUserGetKeyboardLayoutName 1 +NtUserGetKeyboardState 1 +NtUserGetKeyNameText 3 +NtUserGetKeyState 1 +NtUserGetListBoxInfo 1 +NtUserGetMenuBarInfo 4 +NtUserGetMenuIndex 2 +NtUserGetMenuItemRect 4 +NtUserGetMessage 4 +NtUserGetMouseMovePointsEx 5 +NtUserGetObjectInformation 5 +NtUserGetOpenClipboardWindow 0 +NtUserGetPriorityClipboardFormat 2 +NtUserGetProcessWindowStation 0 +NtUserGetRawInputBuffer 3 +NtUserGetRawInputData 5 +NtUserGetRawInputDeviceInfo 4 +NtUserGetRawInputDeviceList 3 +NtUserGetRegisteredRawInputDevices 3 +NtUserGetScrollBarInfo 3 +NtUserGetSystemMenu 2 +NtUserGetThreadDesktop 2 +NtUserGetThreadState 1 +NtUserGetTitleBarInfo 2 +NtUserGetUpdateRect 3 +NtUserGetUpdateRgn 3 +NtUserGetWindowDC 1 +NtUserGetWindowPlacement 2 +NtUserGetWOWClass 2 +NtUserHardErrorControl 3 +NtUserHideCaret 1 +NtUserHiliteMenuItem 4 +NtUserImpersonateDdeClientWindow 2 +NtUserInitialize 3 +NtUserInitializeClientPfnArrays 4 +NtUserInitTask 12 +NtUserInternalGetWindowText 3 +NtUserInvalidateRect 3 +NtUserInvalidateRgn 3 +NtUserIsClipboardFormatAvailable 1 +NtUserKillTimer 2 +NtUserLoadKeyboardLayoutEx 7 +NtUserLockWindowStation 1 +NtUserLockWindowUpdate 1 +NtUserLockWorkStation 0 +NtUserMapVirtualKeyEx 4 +NtUserMenuItemFromPoint 4 +NtUserMessageCall 7 +NtUserMinMaximize 3 +NtUserMNDragLeave 0 +NtUserMNDragOver 2 +NtUserModifyUserStartupInfoFlags 2 +NtUserMoveWindow 6 +NtUserNotifyIMEStatus 3 +NtUserNotifyProcessCreate 4 +NtUserNotifyWinEvent 4 +NtUserOpenClipboard 2 +NtUserOpenDesktop 3 +NtUserOpenInputDesktop 3 +NtUserOpenWindowStation 2 +NtUserPaintDesktop 1 +NtUserPeekMessage 5 +NtUserPostMessage 4 +NtUserPostThreadMessage 4 +NtUserPrintWindow 3 +NtUserProcessConnect 3 +NtUserQueryInformationThread 5 +NtUserQueryInputContext 2 +NtUserQuerySendMessage 1 +NtUserQueryUserCounters 5 +NtUserQueryWindow 2 +NtUserRealChildWindowFromPoint 3 +NtUserRealInternalGetMessage 6 +NtUserRealWaitMessageEx 2 +NtUserRedrawWindow 4 +NtUserRegisterClassExWOW 7 +NtUserRegisterUserApiHook 2 +NtUserRegisterHotKey 4 +NtUserRegisterRawInputDevices 3 +NtUserRegisterTasklist 1 +NtUserRegisterWindowMessage 1 +NtUserRemoveMenu 3 +NtUserRemoveProp 2 +NtUserResolveDesktop 4 +NtUserResolveDesktopForWOW 1 +NtUserSBGetParms 4 +NtUserScrollDC 7 +NtUserScrollWindowEx 8 +NtUserSelectPalette 3 +NtUserSendInput 3 +NtUserSetActiveWindow 1 +NtUserSetAppImeLevel 2 +NtUserSetCapture 1 +NtUserSetClassLong 4 +NtUserSetClassWord 3 +NtUserSetClipboardData 3 +NtUserSetClipboardViewer 1 +NtUserSetConsoleReserveKeys 2 +NtUserSetCursor 1 +NtUserSetCursorContents 2 +NtUserSetCursorIconData 4 +NtUserSetDbgTag 2 +NtUserSetFocus 1 +NtUserSetImeHotKey 5 +NtUserSetImeInfoEx 1 +NtUserSetImeOwnerWindow 2 +NtUserSetInformationProcess 4 +NtUserSetInformationThread 4 +NtUserSetInternalWindowPos 4 +NtUserSetKeyboardState 1 +NtUserSetLogonNotifyWindow 1 +NtUserSetMenu 3 +NtUserSetMenuContextHelpId 2 +NtUserSetMenuDefaultItem 3 +NtUserSetMenuFlagRtoL 1 +NtUserSetObjectInformation 4 +NtUserSetParent 2 +NtUserSetProcessWindowStation 1 +NtUserSetProp 3 +NtUserSetRipFlags 2 +NtUserSetScrollInfo 4 +NtUserSetShellWindowEx 2 +NtUserSetSysColors 4 +NtUserSetSystemCursor 2 +NtUserSetSystemMenu 2 +NtUserSetSystemTimer 4 +NtUserSetThreadDesktop 1 +NtUserSetThreadLayoutHandles 2 +NtUserSetThreadState 2 +NtUserSetTimer 4 +NtUserSetWindowFNID 2 +NtUserSetWindowLong 4 +NtUserSetWindowPlacement 2 +NtUserSetWindowPos 7 +NtUserSetWindowRgn 3 +NtUserSetWindowsHookAW 3 +NtUserSetWindowsHookEx 6 +NtUserSetWindowStationUser 4 +NtUserSetWindowWord 3 +NtUserSetWinEventHook 8 +NtUserShowCaret 1 +NtUserShowScrollBar 3 +NtUserShowWindow 2 +NtUserShowWindowAsync 2 +NtUserSoundSentry 0 +NtUserSwitchDesktop 1 +NtUserSystemParametersInfo 4 +NtUserTestForInteractiveUser 1 +NtUserThunkedMenuInfo 2 +NtUserThunkedMenuItemInfo 6 +NtUserToUnicodeEx 7 +NtUserTrackMouseEvent 1 +NtUserTrackPopupMenuEx 6 +NtUserCalcMenuBar 5 +NtUserPaintMenuBar 6 +NtUserTranslateAccelerator 3 +NtUserTranslateMessage 2 +NtUserUnhookWindowsHookEx 1 +NtUserUnhookWinEvent 1 +NtUserUnloadKeyboardLayout 1 +NtUserUnlockWindowStation 1 +NtUserUnregisterClass 3 +NtUserUnregisterUserApiHook 0 +NtUserUnregisterHotKey 2 +NtUserUpdateInputContext 3 +NtUserUpdateInstance 3 +NtUserUpdateLayeredWindow 9 +NtUserGetLayeredWindowAttributes 4 +NtUserSetLayeredWindowAttributes 4 +NtUserUpdatePerUserSystemParameters 2 +NtUserUserHandleGrantAccess 3 +NtUserValidateHandleSecure 1 +NtUserValidateRect 2 +NtUserValidateTimerCallback 3 +NtUserVkKeyScanEx 3 +NtUserWaitForInputIdle 3 +NtUserWaitForMsgAndEvent 1 +NtUserWaitMessage 0 +NtUserWin32PoolAllocationStats 6 +NtUserWindowFromPoint 2 +NtUserYieldTask 0 +NtUserRemoteConnect 3 +NtUserRemoteRedrawRectangle 4 +NtUserRemoteRedrawScreen 0 +NtUserRemoteStopScreenUpdates 0 +NtUserCtxDisplayIOCtl 3 +NtGdiEngAssociateSurface 3 +NtGdiEngCreateBitmap 6 +NtGdiEngCreateDeviceSurface 4 +NtGdiEngCreateDeviceBitmap 4 +NtGdiEngCreatePalette 6 +NtGdiEngComputeGlyphSet 3 +NtGdiEngCopyBits 6 +NtGdiEngDeletePalette 1 +NtGdiEngDeleteSurface 1 +NtGdiEngEraseSurface 3 +NtGdiEngUnlockSurface 1 +NtGdiEngLockSurface 1 +NtGdiEngBitBlt 11 +NtGdiEngStretchBlt 11 +NtGdiEngPlgBlt 11 +NtGdiEngMarkBandingSurface 1 +NtGdiEngStrokePath 8 +NtGdiEngFillPath 7 +NtGdiEngStrokeAndFillPath 10 +NtGdiEngPaint 5 +NtGdiEngLineTo 9 +NtGdiEngAlphaBlend 7 +NtGdiEngGradientFill 10 +NtGdiEngTransparentBlt 8 +NtGdiEngTextOut 10 +NtGdiEngStretchBltROP 13 +NtGdiXLATEOBJ_cGetPalette 4 +NtGdiXLATEOBJ_iXlate 2 +NtGdiXLATEOBJ_hGetColorTransform 1 +NtGdiCLIPOBJ_bEnum 3 +NtGdiCLIPOBJ_cEnumStart 5 +NtGdiCLIPOBJ_ppoGetPath 1 +NtGdiEngDeletePath 1 +NtGdiEngCreateClip 0 +NtGdiEngDeleteClip 1 +NtGdiBRUSHOBJ_ulGetBrushColor 1 +NtGdiBRUSHOBJ_pvAllocRbrush 2 +NtGdiBRUSHOBJ_pvGetRbrush 1 +NtGdiBRUSHOBJ_hGetColorTransform 1 +NtGdiXFORMOBJ_bApplyXform 5 +NtGdiXFORMOBJ_iGetXform 2 +NtGdiFONTOBJ_vGetInfo 3 +NtGdiFONTOBJ_pxoGetXform 1 +NtGdiFONTOBJ_cGetGlyphs 5 +NtGdiFONTOBJ_pifi 1 +NtGdiFONTOBJ_pfdg 1 +NtGdiFONTOBJ_pQueryGlyphAttrs 2 +NtGdiFONTOBJ_pvTrueTypeFontFile 2 +NtGdiFONTOBJ_cGetAllGlyphHandles 2 +NtGdiSTROBJ_bEnum 3 +NtGdiSTROBJ_bEnumPositionsOnly 3 +NtGdiSTROBJ_bGetAdvanceWidths 4 +NtGdiSTROBJ_vEnumStart 1 +NtGdiSTROBJ_dwGetCodePage 1 +NtGdiPATHOBJ_vGetBounds 2 +NtGdiPATHOBJ_bEnum 2 +NtGdiPATHOBJ_vEnumStart 1 +NtGdiPATHOBJ_vEnumStartClipLines 4 +NtGdiPATHOBJ_bEnumClipLines 3 +NtGdiGetDhpdev 1 +NtGdiEngCheckAbort 1 +NtGdiHT_Get8BPPFormatPalette 4 +NtGdiHT_Get8BPPMaskPalette 6 +NtGdiUpdateTransform 1 +NtGdiSetPUMPDOBJ 4 +NtGdiBRUSHOBJ_DeleteRbrush 2 +NtGdiUMPDEngFreeUserMem 1 +NtGdiDrawStream 3 diff --git a/rostests/tests/directory.rbuild b/rostests/tests/directory.rbuild index 24c0acc688a..eea7f430d1f 100644 --- a/rostests/tests/directory.rbuild +++ b/rostests/tests/directory.rbuild @@ -139,6 +139,10 @@ + + + + diff --git a/rostests/tests/mmixer_test/mmixer_test.rbuild b/rostests/tests/mmixer_test/mmixer_test.rbuild new file mode 100644 index 00000000000..5829887158a --- /dev/null +++ b/rostests/tests/mmixer_test/mmixer_test.rbuild @@ -0,0 +1,13 @@ + + + + include/reactos/libs/sound + + advapi32 + setupapi + kernel32 + winmm + mmixer + ksuser + test.c + \ No newline at end of file diff --git a/rostests/tests/mmixer_test/test.c b/rostests/tests/mmixer_test/test.c new file mode 100644 index 00000000000..907b035e41e --- /dev/null +++ b/rostests/tests/mmixer_test/test.c @@ -0,0 +1,386 @@ +#include +#include +#include +#include +#include +#include +#include +#include "mmixer.h" + +MIXER_CONTEXT MixerContext; +GUID CategoryGuid = {STATIC_KSCATEGORY_AUDIO}; + +PVOID Alloc(ULONG NumBytes) +{ + //printf("Alloc: %lu\n", NumBytes); + return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, NumBytes); +} + +MIXER_STATUS +Close(HANDLE hDevice) +{ + //printf("Close: Handle %p\n", hDevice); + if (CloseHandle(hDevice)) + return MM_STATUS_SUCCESS; + else + return MM_STATUS_UNSUCCESSFUL; +} + +VOID +Free(PVOID Block) +{ + //printf("Free: %p\n", Block); + HeapFree(GetProcessHeap(), 0, Block); +} + +VOID +Copy(PVOID Src, PVOID Dst, ULONG NumBytes) +{ + //printf("Copy: Src %p Dst %p NumBytes %lu\n", Src, Dst, NumBytes); + CopyMemory(Src, Dst, NumBytes); +} + +MIXER_STATUS +Open( + IN LPWSTR DevicePath, + OUT PHANDLE hDevice) +{ + DevicePath[1] = L'\\'; + *hDevice = CreateFileW(DevicePath, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + if (*hDevice == INVALID_HANDLE_VALUE) + { + //wprintf(L" Failed to open %s Error %lu\n", DevicePath, GetLastError()); + return MM_STATUS_UNSUCCESSFUL; + } + wprintf(L"Open: %s hDevice %p\n", DevicePath, *hDevice); + + return MM_STATUS_SUCCESS; +} + +MIXER_STATUS +Control( + IN HANDLE hMixer, + IN ULONG dwIoControlCode, + IN PVOID lpInBuffer, + IN ULONG nInBufferSize, + OUT PVOID lpOutBuffer, + ULONG nOutBufferSize, + PULONG lpBytesReturned) +{ + OVERLAPPED Overlapped; + BOOLEAN IoResult; + DWORD Transferred = 0; + + //printf("hMixer %p dwIoControlCode %lx lpInBuffer %p nInBufferSize %lu lpOutBuffer %p nOutBufferSize %lu lpBytesReturned %p\n", + // hMixer, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned); + + /* Overlapped I/O is done here - this is used for waiting for completion */ + ZeroMemory(&Overlapped, sizeof(OVERLAPPED)); + Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + + if ( ! Overlapped.hEvent ) + return MM_STATUS_NO_MEMORY; + + /* Talk to the device */ + IoResult = DeviceIoControl(hMixer, + dwIoControlCode, + lpInBuffer, + nInBufferSize, + lpOutBuffer, + nOutBufferSize, + &Transferred, + &Overlapped); + + /* If failure occurs, make sure it's not just due to the overlapped I/O */ + if ( ! IoResult ) + { + if ( GetLastError() != ERROR_IO_PENDING ) + { + CloseHandle(Overlapped.hEvent); + + //printf("Control: Failed with %lu Transferred %lu\n", GetLastError(), Transferred); + + if (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + if ( lpBytesReturned ) + *lpBytesReturned = Transferred; + return MM_STATUS_MORE_ENTRIES; + } + + return MM_STATUS_UNSUCCESSFUL; + } + } + + /* Wait for the I/O to complete */ + IoResult = GetOverlappedResult(hMixer, + &Overlapped, + &Transferred, + TRUE); + + /* Don't need this any more */ + CloseHandle(Overlapped.hEvent); + + if ( ! IoResult ) + return MM_STATUS_UNSUCCESSFUL; + + //printf("Transferred %lu bytes in Sync overlapped I/O\n", Transferred); + + if ( lpBytesReturned ) + *lpBytesReturned = Transferred; + + return MM_STATUS_SUCCESS; +} + +MIXER_STATUS +Enum( + IN PVOID EnumContext, + IN ULONG DeviceIndex, + OUT LPWSTR * DeviceName, + OUT PHANDLE OutHandle, + OUT PHANDLE OutKey) +{ + SP_DEVICE_INTERFACE_DATA InterfaceData; + SP_DEVINFO_DATA DeviceData; + PSP_DEVICE_INTERFACE_DETAIL_DATA_W DetailData; + BOOL Result; + DWORD Length; + MIXER_STATUS Status; + + //printf("Enum EnumContext %p DeviceIndex %lu OutHandle %p\n", EnumContext, DeviceIndex, OutHandle); + + InterfaceData.cbSize = sizeof(InterfaceData); + InterfaceData.Reserved = 0; + + Result = SetupDiEnumDeviceInterfaces(EnumContext, + NULL, + &CategoryGuid, + DeviceIndex, + &InterfaceData); + + if (!Result) + { + if (GetLastError() == ERROR_NO_MORE_ITEMS) + { + printf("LastDevice\n"); + return MM_STATUS_NO_MORE_DEVICES; + } + printf("SetupDiEnumDeviceInterfaces failed with %lu\n", GetLastError()); + return MM_STATUS_UNSUCCESSFUL; + } + + Length = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + MAX_PATH * sizeof(WCHAR); + DetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(), + 0, + Length); + DetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W); + DeviceData.cbSize = sizeof(DeviceData); + DeviceData.Reserved = 0; + + Result = SetupDiGetDeviceInterfaceDetailW(EnumContext, + &InterfaceData, + DetailData, + Length, + NULL, + &DeviceData); + + if (!Result) + { + printf("SetupDiGetDeviceInterfaceDetailW failed with %lu\n", GetLastError()); + return MM_STATUS_UNSUCCESSFUL; + } + + + *OutKey = SetupDiOpenDeviceInterfaceRegKey(EnumContext, &InterfaceData, 0, KEY_READ); + if ((HKEY)*OutKey == INVALID_HANDLE_VALUE) + { + printf("SetupDiOpenDeviceInterfaceRegKey failed with %lx\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, DetailData); + return MM_STATUS_UNSUCCESSFUL; + } + + Status = Open(DetailData->DevicePath, OutHandle); + + if (Status != MM_STATUS_SUCCESS) + { + RegCloseKey((HKEY)*OutKey); + HeapFree(GetProcessHeap(), 0, DetailData); + return Status; + } + + *DeviceName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(DetailData->DevicePath)+1) * sizeof(WCHAR)); + if (*DeviceName == NULL) + { + CloseHandle(*OutHandle); + RegCloseKey((HKEY)*OutKey); + HeapFree(GetProcessHeap(), 0, DetailData); + return MM_STATUS_NO_MEMORY; + } + + wcscpy(*DeviceName, DetailData->DevicePath); + HeapFree(GetProcessHeap(), 0, DetailData); + + return Status; +} + +MIXER_STATUS +QueryKeyValue( + IN HANDLE hKey, + IN LPWSTR KeyName, + OUT PVOID * ResultBuffer, + OUT PULONG ResultLength, + OUT PULONG KeyType) +{ + if (RegQueryValueExW((HKEY)hKey, KeyName, NULL, KeyType, NULL, ResultLength) == ERROR_FILE_NOT_FOUND) + return MM_STATUS_UNSUCCESSFUL; + + *ResultBuffer = HeapAlloc(GetProcessHeap(), 0, *ResultLength); + if (*ResultBuffer == NULL) + return MM_STATUS_NO_MEMORY; + + if (RegQueryValueExW((HKEY)hKey, KeyName, NULL, KeyType, *ResultBuffer, ResultLength) != ERROR_SUCCESS) + { + HeapFree(GetProcessHeap(), 0, *ResultBuffer); + return MM_STATUS_UNSUCCESSFUL; + } + return MM_STATUS_SUCCESS; +} + +MIXER_STATUS +OpenKey( + IN HANDLE hKey, + IN LPWSTR SubKey, + IN ULONG DesiredAccess, + OUT PHANDLE OutKey) +{ + if (RegOpenKeyExW((HKEY)hKey, SubKey, 0, DesiredAccess, (PHKEY)OutKey) == ERROR_SUCCESS) + return MM_STATUS_SUCCESS; + + return MM_STATUS_UNSUCCESSFUL; +} + +MIXER_STATUS +CloseKey( + IN HANDLE hKey) +{ + RegCloseKey((HKEY)hKey); + return MM_STATUS_SUCCESS; +} + + +int main(int argc, char**argv) +{ + MIXER_STATUS Status; + HDEVINFO DeviceHandle; + MIXERCAPSW MixCaps1, MixCaps2; + ULONG Index, SubIndex; + HANDLE hMixer2; + HMIXER hMixer1; + MIXERLINEW MixerLine1, MixerLine2; + MIXERLINECONTROLSW Controls1, Controls2; + + ZeroMemory(&MixerContext, sizeof(MIXER_CONTEXT)); + + DeviceHandle = SetupDiGetClassDevs(&CategoryGuid, + NULL, + NULL, + DIGCF_DEVICEINTERFACE/*|DIGCF_PRESENT */); + if (DeviceHandle == INVALID_HANDLE_VALUE) + { + printf("SetupDiGetClassDevs failed with %lx\n", GetLastError()); + return 0; + } + + printf("DeviceHandle %p\n", DeviceHandle); + + MixerContext.SizeOfStruct = sizeof(MIXER_CONTEXT); + MixerContext.Alloc = Alloc; + MixerContext.Close = Close; + MixerContext.Control = Control; + MixerContext.Copy = Copy; + MixerContext.Free = Free; + MixerContext.Open = Open; + MixerContext.OpenKey = OpenKey; + MixerContext.CloseKey = CloseKey; + MixerContext.QueryKeyValue = QueryKeyValue; + + Status = MMixerInitialize(&MixerContext, Enum, (PVOID)DeviceHandle); + + printf("Status %x\n", Status); + printf("NumberOfMixers %lu mixerGetNumDevs %u\n", MMixerGetCount(&MixerContext), mixerGetNumDevs()); + + for(Index = 0; Index < MMixerGetCount(&MixerContext); Index++) + { + mixerGetDevCapsW(Index, &MixCaps1, sizeof(MIXERCAPSW)); + wprintf(L"WINM: cDestination %u fdwSupport %lx szPname %s vDriverVersion %u wMid %x wPid %x\n", MixCaps1.cDestinations, MixCaps1.fdwSupport, MixCaps1.szPname, MixCaps1.vDriverVersion, MixCaps1.wMid, MixCaps1.wPid); + MMixerGetCapabilities(&MixerContext, Index, &MixCaps2); + wprintf(L"MMIX: cDestination %u fdwSupport %lx szPname %s vDriverVersion %u wMid %x wPid %x\n", MixCaps2.cDestinations, MixCaps2.fdwSupport, MixCaps2.szPname, MixCaps2.vDriverVersion, MixCaps2.wMid, MixCaps2.wPid); + + mixerOpen(&hMixer1, Index, 0, 0, MIXER_OBJECTF_HMIXER); + MMixerOpen(&MixerContext, Index, NULL, NULL, &hMixer2); + + ZeroMemory(&MixerLine1, sizeof(MIXERLINEW)); + ZeroMemory(&MixerLine2, sizeof(MIXERLINEW)); + MixerLine1.cbStruct = sizeof(MIXERLINEW); + MixerLine2.cbStruct = sizeof(MIXERLINEW); + mixerGetLineInfoW((HMIXEROBJ)hMixer1, &MixerLine1, MIXER_GETLINEINFOF_DESTINATION); + MMixerGetLineInfo(&MixerContext, hMixer2, MIXER_GETLINEINFOF_DESTINATION, &MixerLine2); + + wprintf(L"WINM: dwDestination %lx dwSource %lx dwLineID %lx dwUser %lx dwComponentType %lx cChannels %lx cConnections %lx cControls %lx szShortName %s szName %s\n\n", + MixerLine1.dwDestination, MixerLine1.dwSource, MixerLine1.dwLineID, MixerLine1.dwUser, MixerLine1.dwComponentType, MixerLine1.cChannels, MixerLine1.cConnections, MixerLine1.cControls, MixerLine1.szShortName, MixerLine1.szName); + + wprintf(L"MMIX: dwDestination %lx dwSource %lx dwLineID %lx dwUser %lx dwComponentType %lx cChannels %lx cConnections %lx cControls %lx szShortName %s szName %s\n\n", + MixerLine2.dwDestination, MixerLine2.dwSource, MixerLine2.dwLineID, MixerLine2.dwUser, MixerLine2.dwComponentType, MixerLine2.cChannels, MixerLine2.cConnections, MixerLine2.cControls, MixerLine2.szShortName, MixerLine2.szName); + + Controls1.cbStruct = sizeof(MIXERLINECONTROLSW); + Controls2.cbStruct = sizeof(MIXERLINECONTROLSW); + + Controls1.cbmxctrl = sizeof(MIXERCONTROL); + Controls2.cbmxctrl = sizeof(MIXERCONTROL); + + Controls1.cControls = MixerLine1.cControls; + Controls2.cControls = MixerLine2.cControls; + + Controls1.dwLineID = MixerLine1.dwLineID; + Controls2.dwLineID = MixerLine2.dwLineID; + + + + Controls1.pamxctrl = (LPMIXERCONTROLW)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MIXERCONTROLW) * Controls1.cControls); + Controls2.pamxctrl = (LPMIXERCONTROLW)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MIXERCONTROLW) * Controls2.cControls); + + for(SubIndex = 0; SubIndex < Controls1.cControls; SubIndex++) + Controls1.pamxctrl[SubIndex].cbStruct = sizeof(MIXERCONTROLW); + + for(SubIndex = 0; SubIndex < Controls2.cControls; SubIndex++) + Controls2.pamxctrl[SubIndex].cbStruct = sizeof(MIXERCONTROLW); + + mixerGetLineControlsW((HMIXEROBJ)hMixer1, &Controls1, MIXER_GETLINECONTROLSF_ALL); + MMixerGetLineControls(&MixerContext, hMixer2, MIXER_GETLINECONTROLSF_ALL, &Controls2); + + wprintf(L"----------------------------------------\n"); + for(SubIndex = 0; SubIndex < Controls1.cControls || SubIndex < Controls2.cControls; SubIndex++) + { + if (SubIndex < Controls1.cControls) + { + wprintf(L"WINM: Index %d dwControlID %lx dwControlType %lx fdwControl %lx cMultipleItems %lx szName %s szShortName %s \n", SubIndex, Controls1.pamxctrl[SubIndex].dwControlID, Controls1.pamxctrl[SubIndex].dwControlType, Controls1.pamxctrl[SubIndex].fdwControl, Controls1.pamxctrl[SubIndex].cMultipleItems, Controls1.pamxctrl[SubIndex].szName, Controls1.pamxctrl[SubIndex].szShortName); + } + + if (SubIndex < Controls2.cControls) + { + wprintf(L"MMIX: Index %d dwControlID %lx dwControlType %lx fdwControl %lx cMultipleItems %lx szName %s szShortName %s \n", SubIndex, Controls2.pamxctrl[SubIndex].dwControlID, Controls2.pamxctrl[SubIndex].dwControlType, Controls2.pamxctrl[SubIndex].fdwControl, Controls2.pamxctrl[SubIndex].cMultipleItems, Controls2.pamxctrl[SubIndex].szName, Controls2.pamxctrl[SubIndex].szShortName); + } + + } + wprintf(L"----------------------------------------\n"); + + + wprintf(L"=======================\n"); + } + return 0; +} diff --git a/rostests/winetests/advapi32/advapi32.rbuild b/rostests/winetests/advapi32/advapi32.rbuild index 2b5b5df8e54..09bb15038b2 100644 --- a/rostests/winetests/advapi32/advapi32.rbuild +++ b/rostests/winetests/advapi32/advapi32.rbuild @@ -1,21 +1,22 @@ - . + . - advapi32 - ntdll - uuid - ole32 - cred.c - crypt.c - crypt_lmhash.c - crypt_md4.c - crypt_md5.c - crypt_sha.c - lsa.c - registry.c - security.c - service.c - testlist.c + advapi32 + ntdll + uuid + ole32 + cred.c + crypt.c + crypt_lmhash.c + crypt_md4.c + crypt_md5.c + crypt_sha.c + eventlog.c + lsa.c + registry.c + security.c + service.c + testlist.c diff --git a/rostests/winetests/advapi32/crypt.c b/rostests/winetests/advapi32/crypt.c index f291ae51a0b..2d7235bffc4 100644 --- a/rostests/winetests/advapi32/crypt.c +++ b/rostests/winetests/advapi32/crypt.c @@ -234,6 +234,7 @@ static void test_incorrect_api_usage(void) result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash); ok (result, "%d\n", GetLastError()); if (!result) return; + pCryptDestroyHash(hHash); result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey); ok (result, "%d\n", GetLastError()); @@ -557,6 +558,7 @@ static void test_enum_providers(void) ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider); ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen); + LocalFree(pszProvName); LocalFree(provider); } @@ -844,6 +846,7 @@ static void test_get_default_provider(void) ok(!strcmp(pszProvName, provName), "expected %s, got %s\n", pszProvName, provName); ok(provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize); + LocalFree(pszProvName); LocalFree(provName); } @@ -933,17 +936,156 @@ static void test_machine_guid(void) RegCloseKey(key); } +#define key_length 16 + +static const unsigned char key[key_length] = + { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd, + 0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 }; + +static void test_rc2_keylen(void) +{ + struct KeyBlob + { + BLOBHEADER header; + DWORD key_size; + BYTE key_data[2048]; + } key_blob; + + HCRYPTPROV provider; + HCRYPTKEY hkey = 0; + BOOL ret; + + SetLastError(0xdeadbeef); + ret = pCryptAcquireContextA(&provider, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + ok(ret, "CryptAcquireContext error %u\n", GetLastError()); + if (ret) + { + key_blob.header.bType = PLAINTEXTKEYBLOB; + key_blob.header.bVersion = CUR_BLOB_VERSION; + key_blob.header.reserved = 0; + key_blob.header.aiKeyAlg = CALG_RC2; + key_blob.key_size = sizeof(key); + memcpy(key_blob.key_data, key, key_length); + + /* Importing a 16-byte key works with the default provider. */ + SetLastError(0xdeadbeef); + ret = pCryptImportKey(provider, (BYTE*)&key_blob, + sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size, + 0, CRYPT_IPSEC_HMAC_KEY, &hkey); + /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */ + todo_wine + ok(ret || + broken(!ret && GetLastError() == NTE_BAD_FLAGS), + "CryptImportKey error %08x\n", GetLastError()); + + if (ret) + pCryptDestroyKey(hkey); + pCryptReleaseContext(provider, 0); + } + + SetLastError(0xdeadbeef); + ret = pCryptAcquireContextA(&provider, NULL, MS_DEF_PROV, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + ok(ret, "CryptAcquireContext error %08x\n", GetLastError()); + + if (ret) + { + /* Importing a 16-byte key doesn't work with the base provider.. */ + SetLastError(0xdeadbeef); + ret = pCryptImportKey(provider, (BYTE*)&key_blob, + sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size, + 0, 0, &hkey); + ok(!ret && (GetLastError() == NTE_BAD_DATA || + GetLastError() == NTE_BAD_LEN || /* Win7 */ + GetLastError() == NTE_BAD_TYPE || /* W2K */ + GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */ + "unexpected error %08x\n", GetLastError()); + /* but importing an 56-bit (7-byte) key does.. */ + key_blob.key_size = 7; + SetLastError(0xdeadbeef); + ret = pCryptImportKey(provider, (BYTE*)&key_blob, + sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size, + 0, 0, &hkey); + ok(ret || + broken(!ret && GetLastError() == NTE_BAD_TYPE) || /* W2K */ + broken(!ret && GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */ + "CryptAcquireContext error %08x\n", GetLastError()); + if (ret) + pCryptDestroyKey(hkey); + /* as does importing a 16-byte key with the base provider when + * CRYPT_IPSEC_HMAC_KEY is specified. + */ + key_blob.key_size = sizeof(key); + SetLastError(0xdeadbeef); + ret = pCryptImportKey(provider, (BYTE*)&key_blob, + sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size, + 0, CRYPT_IPSEC_HMAC_KEY, &hkey); + /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */ + todo_wine + ok(ret || + broken(!ret && GetLastError() == NTE_BAD_FLAGS), + "CryptImportKey error %08x\n", GetLastError()); + if (ret) + pCryptDestroyKey(hkey); + + pCryptReleaseContext(provider, 0); + } + + key_blob.key_size = sizeof(key); + SetLastError(0xdeadbeef); + ret = pCryptAcquireContextA(&provider, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + ok(ret, "CryptAcquireContext error %08x\n", GetLastError()); + + if (ret) + { + /* Importing a 16-byte key also works with the default provider when + * CRYPT_IPSEC_HMAC_KEY is specified. + */ + SetLastError(0xdeadbeef); + ret = pCryptImportKey(provider, (BYTE*)&key_blob, + sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size, + 0, CRYPT_IPSEC_HMAC_KEY, &hkey); + todo_wine + ok(ret || + broken(!ret && GetLastError() == NTE_BAD_FLAGS), + "CryptImportKey error %08x\n", GetLastError()); + if (ret) + pCryptDestroyKey(hkey); + + /* There is no apparent limit to the size of the input key when + * CRYPT_IPSEC_HMAC_KEY is specified. + */ + key_blob.key_size = sizeof(key_blob.key_data); + SetLastError(0xdeadbeef); + ret = pCryptImportKey(provider, (BYTE*)&key_blob, + sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size, + 0, CRYPT_IPSEC_HMAC_KEY, &hkey); + todo_wine + ok(ret || + broken(!ret && GetLastError() == NTE_BAD_FLAGS), + "CryptImportKey error %08x\n", GetLastError()); + if (ret) + pCryptDestroyKey(hkey); + + pCryptReleaseContext(provider, 0); + } +} + START_TEST(crypt) { - init_function_pointers(); - if(pCryptAcquireContextA && pCryptReleaseContext) { + init_function_pointers(); + if (pCryptAcquireContextA && pCryptReleaseContext) + { + test_rc2_keylen(); init_environment(); test_acquire_context(); test_incorrect_api_usage(); test_verify_sig(); test_machine_guid(); clean_up_environment(); - } + } test_enum_providers(); test_enum_provider_types(); diff --git a/rostests/winetests/advapi32/eventlog.c b/rostests/winetests/advapi32/eventlog.c new file mode 100644 index 00000000000..c0f516acd6f --- /dev/null +++ b/rostests/winetests/advapi32/eventlog.c @@ -0,0 +1,1144 @@ +/* + * Unit tests for Event Logging functions + * + * Copyright (c) 2009 Paul Vriens + * + * 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 + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winnt.h" +#include "winreg.h" +#include "sddl.h" + +#include "wine/test.h" + +static BOOL (WINAPI *pCreateWellKnownSid)(WELL_KNOWN_SID_TYPE,PSID,PSID,DWORD*); +static BOOL (WINAPI *pGetEventLogInformation)(HANDLE,DWORD,LPVOID,DWORD,LPDWORD); + +static BOOL (WINAPI *pGetComputerNameExA)(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD); +static BOOL (WINAPI *pWow64DisableWow64FsRedirection)(PVOID *); +static BOOL (WINAPI *pWow64RevertWow64FsRedirection)(PVOID); + +static void init_function_pointers(void) +{ + HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); + HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); + + pCreateWellKnownSid = (void*)GetProcAddress(hadvapi32, "CreateWellKnownSid"); + pGetEventLogInformation = (void*)GetProcAddress(hadvapi32, "GetEventLogInformation"); + + pGetComputerNameExA = (void*)GetProcAddress(hkernel32, "GetComputerNameExA"); + pWow64DisableWow64FsRedirection = (void*)GetProcAddress(hkernel32, "Wow64DisableWow64FsRedirection"); + pWow64RevertWow64FsRedirection = (void*)GetProcAddress(hkernel32, "Wow64RevertWow64FsRedirection"); +} + +static void create_backup(const char *filename) +{ + HANDLE handle; + + DeleteFileA(filename); + handle = OpenEventLogA(NULL, "Application"); + BackupEventLogA(handle, filename); + CloseEventLog(handle); + + todo_wine + ok(GetFileAttributesA(filename) != INVALID_FILE_ATTRIBUTES, "Expected a backup file\n"); +} + +static void test_open_close(void) +{ + HANDLE handle; + BOOL ret; + + SetLastError(0xdeadbeef); + ret = CloseEventLog(NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE || + GetLastError() == ERROR_NOACCESS, /* W2K */ + "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + handle = OpenEventLogA(NULL, NULL); + ok(handle == NULL, "Didn't expect a handle\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + handle = OpenEventLogA("IDontExist", NULL); + ok(handle == NULL, "Didn't expect a handle\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + handle = OpenEventLogA("IDontExist", "deadbeef"); + ok(handle == NULL, "Didn't expect a handle\n"); + ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || + GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */ + "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError()); + + /* This one opens the Application log */ + handle = OpenEventLogA(NULL, "deadbeef"); + ok(handle != NULL, "Expected a handle\n"); + ret = CloseEventLog(handle); + ok(ret, "Expected success\n"); + /* Close a second time */ + SetLastError(0xdeadbeef); + ret = CloseEventLog(handle); + todo_wine + { + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + } + + /* Empty servername should be read as local server */ + handle = OpenEventLogA("", "Application"); + ok(handle != NULL, "Expected a handle\n"); + CloseEventLog(handle); + + handle = OpenEventLogA(NULL, "Application"); + ok(handle != NULL, "Expected a handle\n"); + CloseEventLog(handle); +} + +static void test_info(void) +{ + HANDLE handle; + BOOL ret; + DWORD needed; + EVENTLOG_FULL_INFORMATION efi; + + if (!pGetEventLogInformation) + { + /* NT4 */ + win_skip("GetEventLogInformation is not available\n"); + return; + } + SetLastError(0xdeadbeef); + ret = pGetEventLogInformation(NULL, 1, NULL, 0, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_LEVEL, "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = pGetEventLogInformation(NULL, EVENTLOG_FULL_INFO, NULL, 0, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + + handle = OpenEventLogA(NULL, "Application"); + + SetLastError(0xdeadbeef); + ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, NULL, 0, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, NULL, 0, &needed); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, 0, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + needed = 0xdeadbeef; + efi.dwFull = 0xdeadbeef; + ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, 0, &needed); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected sizeof(EVENTLOG_FULL_INFORMATION), got %d\n", needed); + ok(efi.dwFull == 0xdeadbeef, "Expected no change to the dwFull member\n"); + + /* Not that we care, but on success last error is set to ERROR_IO_PENDING */ + efi.dwFull = 0xdeadbeef; + needed *= 2; + ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, needed, &needed); + ok(ret, "Expected success\n"); + ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected sizeof(EVENTLOG_FULL_INFORMATION), got %d\n", needed); + ok(efi.dwFull == 0 || efi.dwFull == 1, "Expected 0 (not full) or 1 (full), got %d\n", efi.dwFull); + + CloseEventLog(handle); +} + +static void test_count(void) +{ + HANDLE handle; + BOOL ret; + DWORD count; + const char backup[] = "backup.evt"; + + SetLastError(0xdeadbeef); + ret = GetNumberOfEventLogRecords(NULL, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + count = 0xdeadbeef; + ret = GetNumberOfEventLogRecords(NULL, &count); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(count == 0xdeadbeef, "Expected count to stay unchanged\n"); + + handle = OpenEventLogA(NULL, "Application"); + + SetLastError(0xdeadbeef); + ret = GetNumberOfEventLogRecords(handle, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + count = 0xdeadbeef; + ret = GetNumberOfEventLogRecords(handle, &count); + ok(ret, "Expected success\n"); + ok(count != 0xdeadbeef, "Expected the number of records\n"); + + CloseEventLog(handle); + + /* Make a backup eventlog to work with */ + create_backup(backup); + + handle = OpenBackupEventLogA(NULL, backup); + todo_wine + ok(handle != NULL, "Expected a handle\n"); + + /* Does GetNumberOfEventLogRecords work with backup eventlogs? */ + count = 0xdeadbeef; + ret = GetNumberOfEventLogRecords(handle, &count); + todo_wine + { + ok(ret, "Expected success\n"); + ok(count != 0xdeadbeef, "Expected the number of records\n"); + } + + CloseEventLog(handle); + DeleteFileA(backup); +} + +static void test_oldest(void) +{ + HANDLE handle; + BOOL ret; + DWORD oldest; + const char backup[] = "backup.evt"; + + SetLastError(0xdeadbeef); + ret = GetOldestEventLogRecord(NULL, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + oldest = 0xdeadbeef; + ret = GetOldestEventLogRecord(NULL, &oldest); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(oldest == 0xdeadbeef, "Expected oldest to stay unchanged\n"); + + handle = OpenEventLogA(NULL, "Application"); + + SetLastError(0xdeadbeef); + ret = GetOldestEventLogRecord(handle, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + oldest = 0xdeadbeef; + ret = GetOldestEventLogRecord(handle, &oldest); + ok(ret, "Expected success\n"); + ok(oldest != 0xdeadbeef, "Expected the number of the oldest record\n"); + + CloseEventLog(handle); + + /* Make a backup eventlog to work with */ + create_backup(backup); + + handle = OpenBackupEventLogA(NULL, backup); + todo_wine + ok(handle != NULL, "Expected a handle\n"); + + /* Does GetOldestEventLogRecord work with backup eventlogs? */ + oldest = 0xdeadbeef; + ret = GetOldestEventLogRecord(handle, &oldest); + todo_wine + { + ok(ret, "Expected success\n"); + ok(oldest != 0xdeadbeef, "Expected the number of the oldest record\n"); + } + + CloseEventLog(handle); + DeleteFileA(backup); +} + +static void test_backup(void) +{ + HANDLE handle; + BOOL ret; + const char backup[] = "backup.evt"; + const char backup2[] = "backup2.evt"; + + SetLastError(0xdeadbeef); + ret = BackupEventLogA(NULL, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = BackupEventLogA(NULL, backup); + ok(!ret, "Expected failure\n"); + ok(GetFileAttributesA(backup) == INVALID_FILE_ATTRIBUTES, "Expected no backup file\n"); + + handle = OpenEventLogA(NULL, "Application"); + + SetLastError(0xdeadbeef); + ret = BackupEventLogA(handle, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + ret = BackupEventLogA(handle, backup); + ok(ret, "Expected success\n"); + todo_wine + ok(GetFileAttributesA(backup) != INVALID_FILE_ATTRIBUTES, "Expected a backup file\n"); + + /* Try to overwrite */ + SetLastError(0xdeadbeef); + ret = BackupEventLogA(handle, backup); + todo_wine + { + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_ALREADY_EXISTS, "Expected ERROR_ALREADY_EXISTS, got %d\n", GetLastError()); + } + + CloseEventLog(handle); + + /* Can we make a backup of a backup? */ + handle = OpenBackupEventLogA(NULL, backup); + todo_wine + ok(handle != NULL, "Expected a handle\n"); + + ret = BackupEventLogA(handle, backup2); + todo_wine + { + ok(ret, "Expected success\n"); + ok(GetFileAttributesA(backup2) != INVALID_FILE_ATTRIBUTES, "Expected a backup file\n"); + } + + CloseEventLog(handle); + DeleteFileA(backup); + DeleteFileA(backup2); +} + +static void test_read(void) +{ + HANDLE handle; + BOOL ret; + DWORD count, toread, read, needed; + void *buf; + + SetLastError(0xdeadbeef); + ret = ReadEventLogA(NULL, 0, 0, NULL, 0, NULL, NULL); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + read = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = ReadEventLogA(NULL, 0, 0, NULL, 0, &read, NULL); + ok(!ret, "Expected failure\n"); + ok(read == 0xdeadbeef, "Expected 'read' parameter to remain unchanged\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + needed = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = ReadEventLogA(NULL, 0, 0, NULL, 0, NULL, &needed); + ok(!ret, "Expected failure\n"); + ok(needed == 0xdeadbeef, "Expected 'needed' parameter to remain unchanged\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + /* 'read' and 'needed' are only filled when the needed buffer size is passed back or when the call succeeds */ + SetLastError(0xdeadbeef); + ret = ReadEventLogA(NULL, 0, 0, NULL, 0, &read, &needed); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, NULL, 0, NULL, NULL); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, NULL, 0, &read, &needed); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + buf = NULL; + SetLastError(0xdeadbeef); + ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, + 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD)); + SetLastError(0xdeadbeef); + ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, + 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, buf); + + handle = OpenEventLogA(NULL, "Application"); + + /* Show that we need the proper dwFlags with a (for the rest) proper call */ + buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD)); + + SetLastError(0xdeadbeef); + ret = ReadEventLogA(handle, 0, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ, + 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ, + 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ | EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, + 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + HeapFree(GetProcessHeap(), 0, buf); + + /* First check if there are any records (in practice only on Wine: FIXME) */ + count = 0; + GetNumberOfEventLogRecords(handle, &count); + if (!count) + { + skip("No records in the 'Application' log\n"); + CloseEventLog(handle); + return; + } + + /* Get the buffer size for the first record */ + buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD)); + read = needed = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, + 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); + ok(!ret, "Expected failure\n"); + ok(read == 0, "Expected no bytes read\n"); + ok(needed > sizeof(EVENTLOGRECORD), "Expected the needed buffersize to be bigger than sizeof(EVENTLOGRECORD)\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + /* Read the first record */ + toread = needed; + buf = HeapReAlloc(GetProcessHeap(), 0, buf, toread); + read = needed = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, buf, toread, &read, &needed); + ok(ret, "Expected success\n"); + ok(read == toread || + broken(read < toread), /* NT4 wants a buffer size way bigger than just 1 record */ + "Expected the requested size to be read\n"); + ok(needed == 0, "Expected no extra bytes to be read\n"); + HeapFree(GetProcessHeap(), 0, buf); + + CloseEventLog(handle); +} + +static void test_openbackup(void) +{ + HANDLE handle, handle2, file; + DWORD written; + const char backup[] = "backup.evt"; + const char text[] = "Just some text"; + + SetLastError(0xdeadbeef); + handle = OpenBackupEventLogA(NULL, NULL); + ok(handle == NULL, "Didn't expect a handle\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + handle = OpenBackupEventLogA(NULL, "idontexist.evt"); + ok(handle == NULL, "Didn't expect a handle\n"); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + handle = OpenBackupEventLogA("IDontExist", NULL); + ok(handle == NULL, "Didn't expect a handle\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + handle = OpenBackupEventLogA("IDontExist", "idontexist.evt"); + ok(handle == NULL, "Didn't expect a handle\n"); + ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || + GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */ + "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError()); + + /* Make a backup eventlog to work with */ + create_backup(backup); + + /* FIXME: Wine stops here */ + if (GetFileAttributesA(backup) == INVALID_FILE_ATTRIBUTES) + { + skip("We don't have a backup eventlog to work with\n"); + return; + } + + SetLastError(0xdeadbeef); + handle = OpenBackupEventLogA("IDontExist", backup); + ok(handle == NULL, "Didn't expect a handle\n"); + ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || + GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */ + "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError()); + + /* Empty servername should be read as local server */ + handle = OpenBackupEventLogA("", backup); + ok(handle != NULL, "Expected a handle\n"); + CloseEventLog(handle); + + handle = OpenBackupEventLogA(NULL, backup); + ok(handle != NULL, "Expected a handle\n"); + + /* Can we open that same backup eventlog more than once? */ + handle2 = OpenBackupEventLogA(NULL, backup); + ok(handle2 != NULL, "Expected a handle\n"); + ok(handle2 != handle, "Didn't expect the same handle\n"); + CloseEventLog(handle2); + + CloseEventLog(handle); + DeleteFileA(backup); + + /* Is there any content checking done? */ + file = CreateFileA(backup, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL); + CloseHandle(file); + SetLastError(0xdeadbeef); + handle = OpenBackupEventLogA(NULL, backup); + ok(handle == NULL, "Didn't expect a handle\n"); + ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY || + GetLastError() == ERROR_EVENTLOG_FILE_CORRUPT, /* Vista and Win7 */ + "Expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError()); + CloseEventLog(handle); + DeleteFileA(backup); + + file = CreateFileA(backup, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL); + WriteFile(file, text, sizeof(text), &written, NULL); + CloseHandle(file); + SetLastError(0xdeadbeef); + handle = OpenBackupEventLogA(NULL, backup); + ok(handle == NULL, "Didn't expect a handle\n"); + ok(GetLastError() == ERROR_EVENTLOG_FILE_CORRUPT, "Expected ERROR_EVENTLOG_FILE_CORRUPT, got %d\n", GetLastError()); + CloseEventLog(handle); + DeleteFileA(backup); +} + +static void test_clear(void) +{ + HANDLE handle; + BOOL ret; + const char backup[] = "backup.evt"; + const char backup2[] = "backup2.evt"; + + SetLastError(0xdeadbeef); + ret = ClearEventLogA(NULL, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + + /* Make a backup eventlog to work with */ + create_backup(backup); + + SetLastError(0xdeadbeef); + ret = ClearEventLogA(NULL, backup); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + + handle = OpenBackupEventLogA(NULL, backup); + todo_wine + ok(handle != NULL, "Expected a handle\n"); + + /* A real eventlog would fail with ERROR_ALREADY_EXISTS */ + SetLastError(0xdeadbeef); + ret = ClearEventLogA(handle, backup); + ok(!ret, "Expected failure\n"); + /* The eventlog service runs under an account that doesn't have the necessary + * permissions on the users home directory on a default Vista+ system. + */ + ok(GetLastError() == ERROR_INVALID_HANDLE || + GetLastError() == ERROR_ACCESS_DENIED, /* Vista+ */ + "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + + /* Show that ClearEventLog only works for real eventlogs. */ + SetLastError(0xdeadbeef); + ret = ClearEventLogA(handle, backup2); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(GetFileAttributesA(backup2) == INVALID_FILE_ATTRIBUTES, "Expected no backup file\n"); + + SetLastError(0xdeadbeef); + ret = ClearEventLogA(handle, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + + CloseEventLog(handle); + todo_wine + ok(DeleteFileA(backup), "Could not delete the backup file\n"); +} + +static const char eventlogsvc[] = "SYSTEM\\CurrentControlSet\\Services\\Eventlog"; +static const char eventlogname[] = "Wine"; +static const char eventsources[][11] = { "WineSrc", "WineSrc1", "WineSrc20", "WineSrc300" }; + +static BOOL create_new_eventlog(void) +{ + HKEY key, eventkey; + BOOL bret = FALSE; + LONG lret; + int i; + + /* First create our eventlog */ + lret = RegOpenKeyA(HKEY_LOCAL_MACHINE, eventlogsvc, &key); + /* FIXME: Wine stops here */ + if (lret != ERROR_SUCCESS) + { + skip("Could not open the EventLog service registry key\n"); + return FALSE; + } + lret = RegCreateKeyA(key, eventlogname, &eventkey); + if (lret != ERROR_SUCCESS) + { + skip("Could not create the eventlog '%s' registry key\n", eventlogname); + goto cleanup; + } + + /* Create some event sources, the registry value 'Sources' is updated automatically */ + for (i = 0; i < sizeof(eventsources)/sizeof(eventsources[0]); i++) + { + HKEY srckey; + + lret = RegCreateKeyA(eventkey, eventsources[i], &srckey); + if (lret != ERROR_SUCCESS) + { + skip("Could not create the eventsource '%s' registry key\n", eventsources[i]); + goto cleanup; + } + RegFlushKey(srckey); + RegCloseKey(srckey); + } + + bret = TRUE; + + /* The flushing of the registry (here and above) gives us some assurance + * that we are not to quickly writing events as 'Sources' could still be + * not updated. + */ + RegFlushKey(eventkey); +cleanup: + RegCloseKey(eventkey); + RegCloseKey(key); + + return bret; +} + +static const char *one_string[] = { "First string" }; +static const char *two_strings[] = { "First string", "Second string" }; +static const struct +{ + const char *evt_src; + WORD evt_type; + WORD evt_cat; + DWORD evt_id; + BOOL evt_sid; + WORD evt_numstrings; + const char **evt_strings; +} read_write [] = +{ + { eventlogname, EVENTLOG_INFORMATION_TYPE, 1, 1, FALSE, 1, one_string }, + { eventsources[0], EVENTLOG_WARNING_TYPE, 1, 2, FALSE, 0, NULL }, + { eventsources[1], EVENTLOG_AUDIT_FAILURE, 1, 3, FALSE, 2, two_strings }, + { eventsources[2], EVENTLOG_ERROR_TYPE, 1, 4, FALSE, 0, NULL }, + { eventsources[3], EVENTLOG_WARNING_TYPE, 1, 5, FALSE, 1, one_string }, + { eventlogname, EVENTLOG_SUCCESS, 2, 6, TRUE, 2, two_strings }, + { eventsources[0], EVENTLOG_AUDIT_FAILURE, 2, 7, TRUE, 0, NULL }, + { eventsources[1], EVENTLOG_AUDIT_SUCCESS, 2, 8, TRUE, 2, two_strings }, + { eventsources[2], EVENTLOG_WARNING_TYPE, 2, 9, TRUE, 0, NULL }, + { eventsources[3], EVENTLOG_ERROR_TYPE, 2, 10, TRUE, 1, one_string } +}; + +static void test_readwrite(void) +{ + HANDLE handle; + PSID user; + DWORD sidsize, count; + BOOL ret, sidavailable; + BOOL on_vista = FALSE; /* Used to indicate Vista, W2K8 or Win7 */ + int i; + char *localcomputer = NULL; + DWORD size; + + if (pCreateWellKnownSid) + { + sidsize = SECURITY_MAX_SID_SIZE; + user = HeapAlloc(GetProcessHeap(), 0, sidsize); + SetLastError(0xdeadbeef); + pCreateWellKnownSid(WinInteractiveSid, NULL, user, &sidsize); + sidavailable = TRUE; + } + else + { + win_skip("Skipping some SID related tests\n"); + sidavailable = FALSE; + user = NULL; + } + + /* Write an event with an incorrect event type. This will fail on Windows 7 + * but succeed on all others, hence it's not part of the struct. + */ + handle = OpenEventLogA(NULL, eventlogname); + if (!handle) + { + /* Intermittently seen on NT4 when tests are run immediately after boot */ + win_skip("Could not get a handle to the eventlog\n"); + goto cleanup; + } + + count = 0xdeadbeef; + GetNumberOfEventLogRecords(handle, &count); + if (count != 0) + { + /* Needed for W2K3 without a service pack */ + win_skip("We most likely opened the Application eventlog\n"); + CloseEventLog(handle); + Sleep(2000); + + handle = OpenEventLogA(NULL, eventlogname); + count = 0xdeadbeef; + GetNumberOfEventLogRecords(handle, &count); + if (count != 0) + { + win_skip("We didn't open our new eventlog\n"); + CloseEventLog(handle); + goto cleanup; + } + } + + SetLastError(0xdeadbeef); + ret = ReportEvent(handle, 0x20, 0, 0, NULL, 0, 0, NULL, NULL); + if (!ret && GetLastError() == ERROR_CRC) + { + win_skip("Win7 fails when using incorrect event types\n"); + ret = ReportEvent(handle, 0, 0, 0, NULL, 0, 0, NULL, NULL); + } + else + { + void *buf; + DWORD read, needed; + EVENTLOGRECORD *record; + + /* Needed to catch earlier Vista (with no ServicePack for example) */ + buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD)); + ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, + 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); + + buf = HeapReAlloc(GetProcessHeap(), 0, buf, needed); + ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, + 0, buf, needed, &read, &needed); + + record = (EVENTLOGRECORD *)buf; + + /* Vista and W2K8 return EVENTLOG_SUCCESS, Windows versions before return + * the written eventtype (0x20 in this case). + */ + if (record->EventType == EVENTLOG_SUCCESS) + on_vista = TRUE; + + HeapFree(GetProcessHeap(), 0, buf); + } + ok(ret, "Expected success : %d\n", GetLastError()); + + /* This will clear the eventlog. The record numbering for new + * events however differs on Vista SP1+. Before Vista the first + * event would be numbered 1, on Vista SP1+ it's higher as we already + * had at least one event (more in case of multiple test runs without + * a reboot). + */ + ClearEventLogA(handle, NULL); + CloseEventLog(handle); + + /* Write a bunch of events while using different event sources */ + for (i = 0; i < sizeof(read_write)/sizeof(read_write[0]); i++) + { + DWORD oldest; + BOOL run_sidtests = read_write[i].evt_sid & sidavailable; + + /* We don't need to use RegisterEventSource to report events */ + if (i % 2) + handle = OpenEventLogA(NULL, read_write[i].evt_src); + else + handle = RegisterEventSourceA(NULL, read_write[i].evt_src); + ok(handle != NULL, "Expected a handle\n"); + + SetLastError(0xdeadbeef); + ret = ReportEvent(handle, read_write[i].evt_type, read_write[i].evt_cat, + read_write[i].evt_id, run_sidtests ? user : NULL, + read_write[i].evt_numstrings, 0, read_write[i].evt_strings, NULL); + + count = 0xdeadbeef; + ret = GetNumberOfEventLogRecords(handle, &count); + ok(ret, "Expected success\n"); + ok(count == (i + 1), "Expected %d records, got %d\n", i + 1, count); + + oldest = 0xdeadbeef; + ret = GetOldestEventLogRecord(handle, &oldest); + ok(ret, "Expected success\n"); + ok(oldest == 1 || + (oldest > 1 && oldest != 0xdeadbeef), /* Vista SP1+, W2K8 and Win7 */ + "Expected oldest to be 1 or higher, got %d\n", oldest); + if (oldest > 1 && oldest != 0xdeadbeef) + on_vista = TRUE; + + if (i % 2) + ret = CloseEventLog(handle); + else + ret = DeregisterEventSource(handle); + ok(ret, "Expected success : %d\n", GetLastError()); + } + + handle = OpenEventLogA(NULL, eventlogname); + count = 0xdeadbeef; + ret = GetNumberOfEventLogRecords(handle, &count); + ok(ret, "Expected success\n"); + ok(count == i, "Expected %d records, got %d\n", i, count); + CloseEventLog(handle); + + if (count == 0) + { + skip("No events were written to the eventlog\n"); + goto cleanup; + } + + /* Report only once */ + if (on_vista) + skip("There is no DWORD alignment enforced for UserSid on Vista, W2K8 or Win7\n"); + + if (on_vista && pGetComputerNameExA) + { + /* New Vista+ behavior */ + size = 0; + SetLastError(0xdeadbeef); + pGetComputerNameExA(ComputerNameDnsFullyQualified, NULL, &size); + localcomputer = HeapAlloc(GetProcessHeap(), 0, size); + pGetComputerNameExA(ComputerNameDnsFullyQualified, localcomputer, &size); + } + else + { + size = MAX_COMPUTERNAME_LENGTH + 1; + localcomputer = HeapAlloc(GetProcessHeap(), 0, size); + GetComputerNameA(localcomputer, &size); + } + + /* Read all events from our created eventlog, one by one */ + handle = OpenEventLogA(NULL, eventlogname); + i = 0; + for (;;) + { + void *buf; + DWORD read, needed; + EVENTLOGRECORD *record; + char *sourcename, *computername; + int k; + char *ptr; + BOOL run_sidtests = read_write[i].evt_sid & sidavailable; + + buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD)); + SetLastError(0xdeadbeef); + ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, + 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); + if (!ret && GetLastError() == ERROR_HANDLE_EOF) + { + HeapFree(GetProcessHeap(), 0, buf); + break; + } + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected ERROR_INVALID_PARAMETER, got %d\n",GetLastError()); + + buf = HeapReAlloc(GetProcessHeap(), 0, buf, needed); + ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, + 0, buf, needed, &read, &needed); + ok(ret, "Expected success: %d\n", GetLastError()); + + record = (EVENTLOGRECORD *)buf; + + ok(record->Length == read, + "Expected %d, got %d\n", read, record->Length); + ok(record->Reserved == 0x654c664c, + "Expected 0x654c664c, got %d\n", record->Reserved); + ok(record->RecordNumber == i + 1 || + (on_vista && (record->RecordNumber > i + 1)), + "Expected %d or higher, got %d\n", i + 1, record->RecordNumber); + ok(record->EventID == read_write[i].evt_id, + "Expected %d, got %d\n", read_write[i].evt_id, record->EventID); + ok(record->EventType == read_write[i].evt_type, + "Expected %d, got %d\n", read_write[i].evt_type, record->EventType); + ok(record->NumStrings == read_write[i].evt_numstrings, + "Expected %d, got %d\n", read_write[i].evt_numstrings, record->NumStrings); + ok(record->EventCategory == read_write[i].evt_cat, + "Expected %d, got %d\n", read_write[i].evt_cat, record->EventCategory); + + sourcename = (char *)((BYTE *)buf + sizeof(EVENTLOGRECORD)); + ok(!lstrcmpA(sourcename, read_write[i].evt_src), "Expected '%s', got '%s'\n", + read_write[i].evt_src, sourcename); + + computername = (char *)((BYTE *)buf + sizeof(EVENTLOGRECORD) + lstrlenA(sourcename) + 1); + ok(!lstrcmpiA(computername, localcomputer), "Expected '%s', got '%s'\n", + localcomputer, computername); + + /* Before Vista, UserSid was aligned on a DWORD boundary. Next to that if + * no padding was actually required a 0 DWORD was still used for padding. No + * application should be relying on the padding as we are working with offsets + * anyway. + */ + + if (!on_vista) + { + DWORD calculated_sidoffset = sizeof(EVENTLOGRECORD) + lstrlenA(sourcename) + 1 + lstrlenA(computername) + 1; + + /* We are already DWORD aligned, there should still be some padding */ + if ((((UINT_PTR)buf + calculated_sidoffset) % sizeof(DWORD)) == 0) + ok(*(DWORD *)((BYTE *)buf + calculated_sidoffset) == 0, "Expected 0\n"); + + ok((((UINT_PTR)buf + record->UserSidOffset) % sizeof(DWORD)) == 0, "Expected DWORD alignment\n"); + } + + if (run_sidtests) + { + ok(record->UserSidLength == sidsize, "Expected %d, got %d\n", sidsize, record->UserSidLength); + } + else + { + ok(record->StringOffset == record->UserSidOffset, "Expected offsets to be the same\n"); + ok(record->UserSidLength == 0, "Expected 0, got %d\n", record->UserSidLength); + } + + ok(record->DataLength == 0, "Expected 0, got %d\n", record->DataLength); + + ptr = (char *)((BYTE *)buf + record->StringOffset); + for (k = 0; k < record->NumStrings; k++) + { + ok(!lstrcmpA(ptr, two_strings[k]), "Expected '%s', got '%s'\n", two_strings[k], ptr); + ptr += lstrlenA(ptr) + 1; + } + + ok(record->Length == *(DWORD *)((BYTE *)buf + record->Length - sizeof(DWORD)), + "Expected the closing DWORD to contain the length of the record\n"); + + HeapFree(GetProcessHeap(), 0, buf); + i++; + } + CloseEventLog(handle); + + /* Test clearing a real eventlog */ + handle = OpenEventLogA(NULL, eventlogname); + + SetLastError(0xdeadbeef); + ret = ClearEventLogA(handle, NULL); + ok(ret, "Expected success\n"); + + count = 0xdeadbeef; + ret = GetNumberOfEventLogRecords(handle, &count); + ok(ret, "Expected success\n"); + ok(count == 0, "Expected an empty eventlog, got %d records\n", count); + + CloseEventLog(handle); + +cleanup: + HeapFree(GetProcessHeap(), 0, localcomputer); + HeapFree(GetProcessHeap(), 0, user); +} + +/* Before Vista: + * + * Creating an eventlog on Windows (via the registry) automatically leads + * to creation of a REG_MULTI_SZ named 'Sources'. This value lists all the + * potential event sources for this eventlog. 'Sources' is automatically + * updated when a new key (aka event source) is created. + * + * Although the updating of registry keys is almost instantaneously, we + * check it after some other tests to assure we are not querying the + * registry or file system to quickly. + * + * NT4 and higher: + * + * The eventlog file itself is also automatically created, even before we + * start writing events. + */ +static char eventlogfile[MAX_PATH]; +static void test_autocreation(void) +{ + HKEY key, eventkey; + DWORD type, size; + LONG ret; + int i; + char *p; + char sources[sizeof(eventsources)]; + char sysdir[MAX_PATH]; + void *redir = 0; + + RegOpenKeyA(HKEY_LOCAL_MACHINE, eventlogsvc, &key); + RegOpenKeyA(key, eventlogname, &eventkey); + + size = sizeof(sources); + sources[0] = 0; + ret = RegQueryValueExA(eventkey, "Sources", NULL, &type, (LPBYTE)sources, &size); + if (ret == ERROR_SUCCESS) + { + char sources_verify[sizeof(eventsources)]; + + ok(type == REG_MULTI_SZ, "Expected a REG_MULTI_SZ, got %d\n", type); + + /* Build the expected string */ + memset(sources_verify, 0, sizeof(sources_verify)); + p = sources_verify; + for (i = sizeof(eventsources)/sizeof(eventsources[0]); i > 0; i--) + { + lstrcpyA(p, eventsources[i - 1]); + p += (lstrlenA(eventsources[i - 1]) + 1); + } + lstrcpyA(p, eventlogname); + + ok(!memcmp(sources, sources_verify, size), + "Expected a correct 'Sources' value (size : %d)\n", size); + } + + RegCloseKey(eventkey); + RegCloseKey(key); + + /* The directory that holds the eventlog files could be redirected */ + if (pWow64DisableWow64FsRedirection) + pWow64DisableWow64FsRedirection(&redir); + + /* On Windows we also automatically get an eventlog file */ + GetSystemDirectoryA(sysdir, sizeof(sysdir)); + + /* NT4 - W2K3 */ + lstrcpyA(eventlogfile, sysdir); + lstrcatA(eventlogfile, "\\config\\"); + lstrcatA(eventlogfile, eventlogname); + lstrcatA(eventlogfile, ".evt"); + + if (GetFileAttributesA(eventlogfile) == INVALID_FILE_ATTRIBUTES) + { + /* Vista+ */ + lstrcpyA(eventlogfile, sysdir); + lstrcatA(eventlogfile, "\\winevt\\Logs\\"); + lstrcatA(eventlogfile, eventlogname); + lstrcatA(eventlogfile, ".evtx"); + } + + ok(GetFileAttributesA(eventlogfile) != INVALID_FILE_ATTRIBUTES, + "Expected an eventlog file\n"); + + if (pWow64RevertWow64FsRedirection) + pWow64RevertWow64FsRedirection(redir); +} + +static void cleanup_eventlog(void) +{ + BOOL bret; + LONG lret; + HKEY key; + int i; + char winesvc[MAX_PATH]; + + /* Delete the registry tree */ + lstrcpyA(winesvc, eventlogsvc); + lstrcatA(winesvc, "\\"); + lstrcatA(winesvc, eventlogname); + + RegOpenKeyA(HKEY_LOCAL_MACHINE, winesvc, &key); + for (i = 0; i < sizeof(eventsources)/sizeof(eventsources[0]); i++) + RegDeleteKeyA(key, eventsources[i]); + RegDeleteValueA(key, "Sources"); + RegCloseKey(key); + lret = RegDeleteKeyA(HKEY_LOCAL_MACHINE, winesvc); + todo_wine + ok(lret == ERROR_SUCCESS, "Could not delete the registry tree : %d\n", lret); + + /* A handle to the eventlog is locked by services.exe. We can only + * delete the eventlog file after reboot. + */ + bret = MoveFileExA(eventlogfile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); + todo_wine + ok(bret, "Expected MoveFileEx to succeed: %d\n", GetLastError()); +} + +START_TEST(eventlog) +{ + SetLastError(0xdeadbeef); + CloseEventLog(NULL); + if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + { + win_skip("Event log functions are not implemented\n"); + return; + } + + init_function_pointers(); + + /* Parameters only */ + test_open_close(); + test_info(); + test_count(); + test_oldest(); + test_backup(); + test_openbackup(); + test_read(); + test_clear(); + + /* Functional tests */ + if (create_new_eventlog()) + { + test_readwrite(); + test_autocreation(); + } + cleanup_eventlog(); +} diff --git a/rostests/winetests/advapi32/registry.c b/rostests/winetests/advapi32/registry.c index abc2eb4aeb6..dee7664ce27 100644 --- a/rostests/winetests/advapi32/registry.c +++ b/rostests/winetests/advapi32/registry.c @@ -956,6 +956,28 @@ static void test_reg_create_key(void) /* clean up */ RegDeleteKey(hkey2, ""); RegDeleteKey(hkey1, ""); + RegCloseKey(hkey2); + RegCloseKey(hkey1); + + /* test creation of volatile keys */ + ret = RegCreateKeyExA(hkey_main, "Volatile", 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey1, NULL); + ok(!ret, "RegCreateKeyExA failed with error %d\n", ret); + ret = RegCreateKeyExA(hkey1, "Subkey2", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey2, NULL); + ok(ret == ERROR_CHILD_MUST_BE_VOLATILE || broken(!ret), /* win9x */ + "RegCreateKeyExA failed with error %d\n", ret); + if (!ret) RegCloseKey( hkey2 ); + ret = RegCreateKeyExA(hkey1, "Subkey2", 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey2, NULL); + ok(!ret, "RegCreateKeyExA failed with error %d\n", ret); + RegCloseKey(hkey2); + /* should succeed if the key already exists */ + ret = RegCreateKeyExA(hkey1, "Subkey2", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey2, NULL); + ok(!ret, "RegCreateKeyExA failed with error %d\n", ret); + + /* clean up */ + RegDeleteKey(hkey2, ""); + RegDeleteKey(hkey1, ""); + RegCloseKey(hkey2); + RegCloseKey(hkey1); /* beginning backslash character */ ret = RegCreateKeyExA(hkey_main, "\\Subkey3", 0, NULL, 0, KEY_NOTIFY, NULL, &hkey1, NULL); @@ -964,6 +986,7 @@ static void test_reg_create_key(void) else { ok(!ret, "RegCreateKeyExA failed with error %d\n", ret); RegDeleteKey(hkey1, NULL); + RegCloseKey(hkey1); } /* WOW64 flags - open an existing key */ diff --git a/rostests/winetests/advapi32/security.c b/rostests/winetests/advapi32/security.c index 7d91ebe7de2..33f0188a7ac 100644 --- a/rostests/winetests/advapi32/security.c +++ b/rostests/winetests/advapi32/security.c @@ -79,6 +79,7 @@ typedef LPSTR (WINAPI *fnGetTrusteeNameA)( PTRUSTEEA pTrustee ); typedef BOOL (WINAPI *fnMakeSelfRelativeSD)( PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR, LPDWORD ); typedef BOOL (WINAPI *fnConvertSidToStringSidA)( PSID pSid, LPSTR *str ); typedef BOOL (WINAPI *fnConvertStringSidToSidA)( LPCSTR str, PSID pSid ); +static BOOL (WINAPI *pCheckTokenMembership)(HANDLE, PSID, PBOOL); static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorA)(LPCSTR, DWORD, PSECURITY_DESCRIPTOR*, PULONG ); static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorW)(LPCWSTR, DWORD, @@ -153,6 +154,7 @@ static void init(void) pAddAccessAllowedAceEx = (void *)GetProcAddress(hmod, "AddAccessAllowedAceEx"); pAddAccessDeniedAceEx = (void *)GetProcAddress(hmod, "AddAccessDeniedAceEx"); pAddAuditAccessAceEx = (void *)GetProcAddress(hmod, "AddAuditAccessAceEx"); + pCheckTokenMembership = (void *)GetProcAddress(hmod, "CheckTokenMembership"); pConvertStringSecurityDescriptorToSecurityDescriptorA = (void *)GetProcAddress(hmod, "ConvertStringSecurityDescriptorToSecurityDescriptorA" ); pConvertStringSecurityDescriptorToSecurityDescriptorW = @@ -254,6 +256,7 @@ static void test_sid(void) ok(pisid->SubAuthority[0] == 21, "Invalid subauthority 0 - expceted 21, got %d\n", pisid->SubAuthority[0]); ok(pisid->SubAuthority[3] == 4576, "Invalid subauthority 0 - expceted 4576, got %d\n", pisid->SubAuthority[3]); LocalFree(str); + LocalFree(psid); for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ ) { @@ -1226,10 +1229,18 @@ static void test_token_attr(void) ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); /* groups */ + SetLastError(0xdeadbeef); ret = GetTokenInformation(Token, TokenGroups, NULL, 0, &Size); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "GetTokenInformation(TokenGroups) %s with error %d\n", + ret ? "succeeded" : "failed", GetLastError()); Groups = HeapAlloc(GetProcessHeap(), 0, Size); + SetLastError(0xdeadbeef); ret = GetTokenInformation(Token, TokenGroups, Groups, Size, &Size); ok(ret, "GetTokenInformation(TokenGroups) failed with error %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, + "GetTokenInformation shouldn't have set last error to %d\n", + GetLastError()); trace("TokenGroups:\n"); for (i = 0; i < Groups->GroupCount; i++) { @@ -1238,12 +1249,12 @@ static void test_token_attr(void) DWORD DomainLength = 255; TCHAR Domain[255]; SID_NAME_USE SidNameUse; - pConvertSidToStringSidA(Groups->Groups[i].Sid, &SidString); Name[0] = '\0'; Domain[0] = '\0'; ret = LookupAccountSid(NULL, Groups->Groups[i].Sid, Name, &NameLength, Domain, &DomainLength, &SidNameUse); if (ret) { + pConvertSidToStringSidA(Groups->Groups[i].Sid, &SidString); trace("%s, %s\\%s use: %d attr: 0x%08x\n", SidString, Domain, Name, SidNameUse, Groups->Groups[i].Attributes); LocalFree(SidString); } @@ -1478,6 +1489,8 @@ static void test_CreateWellKnownSid(void) ok(memcmp(buf2, sid_buffer, cb) == 0, "SID create with domain is different than without (%d)\n", i); } } + + LocalFree(domainsid); } static void test_LookupAccountSid(void) @@ -2047,7 +2060,8 @@ static void test_LookupAccountName(void) domain = HeapAlloc(GetProcessHeap(), 0, domain_size); ret = LookupAccountNameA(NULL, computer_name, psid, &sid_size, domain, &domain_size, &sid_use); ok(ret, "LookupAccountNameA failed: %d\n", GetLastError()); - ok(sid_use == SidTypeDomain, "expected SidTypeDomain, got %d\n", sid_use); + ok(sid_use == SidTypeDomain || + (sid_use == SidTypeUser && ! strcmp(computer_name, user_name)), "expected SidTypeDomain for %s, got %d\n", computer_name, sid_use); HeapFree(GetProcessHeap(), 0, domain); HeapFree(GetProcessHeap(), 0, psid); } @@ -2528,11 +2542,19 @@ static void test_SetEntriesInAcl(void) ExplicitAccess.grfAccessPermissions = KEY_WRITE; ExplicitAccess.grfAccessMode = GRANT_ACCESS; ExplicitAccess.grfInheritance = NO_INHERITANCE; + ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; + ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID; + ExplicitAccess.Trustee.ptstrName = EveryoneSid; + ExplicitAccess.Trustee.MultipleTrusteeOperation = 0xDEADBEEF; + ExplicitAccess.Trustee.pMultipleTrustee = (PVOID)0xDEADBEEF; + res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); + ok(NewAcl != NULL, "returned acl was NULL\n"); + LocalFree(NewAcl); + + ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; ExplicitAccess.Trustee.pMultipleTrustee = NULL; ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; - ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID; - ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; - ExplicitAccess.Trustee.ptstrName = EveryoneSid; res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); ok(NewAcl != NULL, "returned acl was NULL\n"); @@ -2651,6 +2673,50 @@ static void test_ConvertStringSecurityDescriptor(void) BOOL ret; PSECURITY_DESCRIPTOR pSD; static const WCHAR Blank[] = { 0 }; + int i; + static const struct + { + const char *sidstring; + DWORD revision; + BOOL ret; + DWORD GLE; + DWORD altGLE; + } cssd[] = + { + { "D:(A;;GA;;;WD)", 0xdeadbeef, FALSE, ERROR_UNKNOWN_REVISION }, + /* test ACE string type */ + { "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE }, + { "D:(D;;GA;;;WD)", SDDL_REVISION_1, TRUE }, + { "ERROR:(D;;GA;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_PARAMETER }, + /* test ACE string with spaces */ + { " D:(D;;GA;;;WD)", SDDL_REVISION_1, TRUE }, + { "D: (D;;GA;;;WD)", SDDL_REVISION_1, TRUE }, + { "D:( D;;GA;;;WD)", SDDL_REVISION_1, TRUE }, + { "D:(D ;;GA;;;WD)", SDDL_REVISION_1, FALSE, RPC_S_INVALID_STRING_UUID, ERROR_INVALID_ACL }, /* Vista+ */ + { "D:(D; ;GA;;;WD)", SDDL_REVISION_1, TRUE }, + { "D:(D;; GA;;;WD)", SDDL_REVISION_1, TRUE }, + { "D:(D;;GA ;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL }, + { "D:(D;;GA; ;;WD)", SDDL_REVISION_1, TRUE }, + { "D:(D;;GA;; ;WD)", SDDL_REVISION_1, TRUE }, + { "D:(D;;GA;;; WD)", SDDL_REVISION_1, TRUE }, + { "D:(D;;GA;;;WD )", SDDL_REVISION_1, TRUE }, + /* test ACE string access rights */ + { "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE }, + { "D:(A;;GRGWGX;;;WD)", SDDL_REVISION_1, TRUE }, + { "D:(A;;RCSDWDWO;;;WD)", SDDL_REVISION_1, TRUE }, + { "D:(A;;RPWPCCDCLCSWLODTCR;;;WD)", SDDL_REVISION_1, TRUE }, + { "D:(A;;FAFRFWFX;;;WD)", SDDL_REVISION_1, TRUE }, + { "D:(A;;KAKRKWKX;;;WD)", SDDL_REVISION_1, TRUE }, + { "D:(A;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE }, + { "S:(AU;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE }, + /* test ACE string access right error case */ + { "D:(A;;ROB;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL }, + /* test behaviour with empty strings */ + { "", SDDL_REVISION_1, TRUE }, + /* test ACE string SID */ + { "D:(D;;GA;;;S-1-0-0)", SDDL_REVISION_1, TRUE }, + { "D:(D;;GA;;;Nonexistent account)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL, ERROR_INVALID_SID } /* W2K */ + }; if (!pConvertStringSecurityDescriptorToSecurityDescriptorA) { @@ -2658,82 +2724,22 @@ static void test_ConvertStringSecurityDescriptor(void) return; } - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:(A;;GA;;;WD)", 0xdeadbeef, &pSD, NULL); - ok(!ret && GetLastError() == ERROR_UNKNOWN_REVISION, - "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_UNKNOWN_REVISION instead of %d\n", - GetLastError()); + for (i = 0; i < sizeof(cssd)/sizeof(cssd[0]); i++) + { + DWORD GLE; - /* test ACE string type */ - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:(A;;GA;;;WD)", SDDL_REVISION_1, &pSD, NULL); - ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); - LocalFree(pSD); - - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:(D;;GA;;;WD)", SDDL_REVISION_1, &pSD, NULL); - ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); - LocalFree(pSD); - - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "ERROR:(D;;GA;;;WD)", SDDL_REVISION_1, &pSD, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d\n", - GetLastError()); - - /* test ACE string access rights */ - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:(A;;GA;;;WD)", SDDL_REVISION_1, &pSD, NULL); - ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); - LocalFree(pSD); - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:(A;;GRGWGX;;;WD)", SDDL_REVISION_1, &pSD, NULL); - ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); - LocalFree(pSD); - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:(A;;RCSDWDWO;;;WD)", SDDL_REVISION_1, &pSD, NULL); - ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); - LocalFree(pSD); - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:(A;;RPWPCCDCLCSWLODTCR;;;WD)", SDDL_REVISION_1, &pSD, NULL); - ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); - LocalFree(pSD); - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:(A;;FAFRFWFX;;;WD)", SDDL_REVISION_1, &pSD, NULL); - ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); - LocalFree(pSD); - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:(A;;KAKRKWKX;;;WD)", SDDL_REVISION_1, &pSD, NULL); - ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); - LocalFree(pSD); - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:(A;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, &pSD, NULL); - ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); - LocalFree(pSD); - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "S:(AU;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, &pSD, NULL); - ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); - LocalFree(pSD); - - /* test ACE string access right error case */ - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:(A;;ROB;;;WD)", SDDL_REVISION_1, &pSD, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_ACL, - "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_ACL instead of %d\n", - GetLastError()); + SetLastError(0xdeadbeef); + ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( + cssd[i].sidstring, cssd[i].revision, &pSD, NULL); + GLE = GetLastError(); + ok(ret == cssd[i].ret, "(%02d) Expected %s (%d)\n", i, cssd[i].ret ? "success" : "failure", GLE); + if (!cssd[i].ret) + ok(GLE == cssd[i].GLE || + (cssd[i].altGLE && GLE == cssd[i].altGLE), + "(%02d) Unexpected last error %d\n", i, GLE); + if (ret) + LocalFree(pSD); + } /* test behaviour with NULL parameters */ SetLastError(0xdeadbeef); @@ -2766,29 +2772,11 @@ static void test_ConvertStringSecurityDescriptor(void) GetLastError()); /* test behaviour with empty strings */ - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "", SDDL_REVISION_1, &pSD, NULL); - ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); - SetLastError(0xdeadbeef); ret = pConvertStringSecurityDescriptorToSecurityDescriptorW( Blank, SDDL_REVISION_1, &pSD, NULL); ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); - - /* test ACE string SID */ - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:(D;;GA;;;S-1-0-0)", SDDL_REVISION_1, &pSD, NULL); - ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); LocalFree(pSD); - - SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:(D;;GA;;;Nonexistent account)", SDDL_REVISION_1, &pSD, NULL); - ok(!ret, "Expected failure, got %d\n", ret); - ok(GetLastError() == ERROR_INVALID_ACL || GetLastError() == ERROR_INVALID_SID, - "Expected ERROR_INVALID_ACL or ERROR_INVALID_SID, got %d\n", GetLastError()); } static void test_ConvertSecurityDescriptorToString(void) @@ -2900,6 +2888,9 @@ static void test_ConvertSecurityDescriptorToString(void) CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", /* XP */ "O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)" /* Vista */); } + + LocalFree(psid2); + LocalFree(psid); } static void test_SetSecurityDescriptorControl (PSECURITY_DESCRIPTOR sec) @@ -3171,8 +3162,10 @@ static void test_GetSecurityInfo(void) ok(sd != NULL, "GetSecurityInfo\n"); ok(owner != NULL, "GetSecurityInfo\n"); ok(group != NULL, "GetSecurityInfo\n"); - ok(dacl != NULL, "GetSecurityInfo\n"); - ok(IsValidAcl(dacl), "GetSecurityInfo\n"); + if (dacl != NULL) + ok(IsValidAcl(dacl), "GetSecurityInfo\n"); + else + win_skip("No ACL information returned\n"); LocalFree(sd); @@ -3191,8 +3184,10 @@ static void test_GetSecurityInfo(void) ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret); ok(owner != NULL, "GetSecurityInfo\n"); ok(group != NULL, "GetSecurityInfo\n"); - ok(dacl != NULL, "GetSecurityInfo\n"); - ok(IsValidAcl(dacl), "GetSecurityInfo\n"); + if (dacl != NULL) + ok(IsValidAcl(dacl), "GetSecurityInfo\n"); + else + win_skip("No ACL information returned\n"); CloseHandle(obj); } @@ -3220,11 +3215,140 @@ static void test_GetSidSubAuthority(void) ok(*pGetSidSubAuthority(psid,1) == 93476,"GetSidSubAuthority gave %d expected 93476\n",*pGetSidSubAuthority(psid,1)); ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError()); SetLastError(0xbebecaca); - todo_wine ok(*pGetSidSubAuthority(psid,4) == 0,"GetSidSubAuthority gave %d,expected 0\n",*pGetSidSubAuthority(psid,4)); + ok(pGetSidSubAuthority(psid,4) != NULL,"Expected out of bounds GetSidSubAuthority to return a non-NULL pointer\n"); ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError()); LocalFree(psid); } +static void test_CheckTokenMembership(void) +{ + PTOKEN_GROUPS token_groups; + DWORD size; + HANDLE process_token, token; + BOOL is_member; + BOOL ret; + DWORD i; + + if (!pCheckTokenMembership) + { + win_skip("CheckTokenMembership is not available\n"); + return; + } + ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &process_token); + ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); + + ret = DuplicateToken(process_token, SecurityImpersonation, &token); + ok(ret, "DuplicateToken failed with error %d\n", GetLastError()); + + /* groups */ + ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "GetTokenInformation(TokenGroups) %s with error %d\n", + ret ? "succeeded" : "failed", GetLastError()); + token_groups = HeapAlloc(GetProcessHeap(), 0, size); + ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size); + ok(ret, "GetTokenInformation(TokenGroups) failed with error %d\n", GetLastError()); + + for (i = 0; i < token_groups->GroupCount; i++) + { + if (token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) + break; + } + + if (i == token_groups->GroupCount) + { + HeapFree(GetProcessHeap(), 0, token_groups); + CloseHandle(token); + skip("user not a member of any group\n"); + return; + } + + ret = pCheckTokenMembership(token, token_groups->Groups[i].Sid, &is_member); + ok(ret, "CheckTokenMembership failed with error %d\n", GetLastError()); + ok(is_member, "CheckTokenMembership should have detected sid as member\n"); + + ret = pCheckTokenMembership(NULL, token_groups->Groups[i].Sid, &is_member); + ok(ret, "CheckTokenMembership failed with error %d\n", GetLastError()); + ok(is_member, "CheckTokenMembership should have detected sid as member\n"); + + ret = pCheckTokenMembership(process_token, token_groups->Groups[i].Sid, &is_member); +todo_wine { + ok(!ret && GetLastError() == ERROR_NO_IMPERSONATION_TOKEN, + "CheckTokenMembership with process token %s with error %d\n", + ret ? "succeeded" : "failed", GetLastError()); + ok(!is_member, "CheckTokenMembership should have cleared is_member\n"); +} + + HeapFree(GetProcessHeap(), 0, token_groups); + CloseHandle(token); + CloseHandle(process_token); +} + +static void test_EqualSid(void) +{ + PSID sid1, sid2; + BOOL ret; + SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY }; + SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY }; + + SetLastError(0xdeadbeef); + ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid1); + if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + { + win_skip("AllocateAndInitializeSid is not implemented\n"); + return; + } + ok(ret, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, + "AllocateAndInitializeSid shouldn't have set last error to %d\n", + GetLastError()); + + ret = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, + 0, 0, 0, 0, 0, 0, 0, &sid2); + ok(ret, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = EqualSid(sid1, sid2); + ok(!ret, "World and domain admins sids shouldn't have been equal\n"); + ok(GetLastError() == ERROR_SUCCESS || + broken(GetLastError() == 0xdeadbeef), /* NT4 */ + "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n", + GetLastError()); + + SetLastError(0xdeadbeef); + sid2 = FreeSid(sid2); + ok(!sid2, "FreeSid should have returned NULL instead of %p\n", sid2); + ok(GetLastError() == 0xdeadbeef, + "FreeSid shouldn't have set last error to %d\n", + GetLastError()); + + ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid2); + ok(ret, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = EqualSid(sid1, sid2); + ok(ret, "Same sids should have been equal\n"); + ok(GetLastError() == ERROR_SUCCESS || + broken(GetLastError() == 0xdeadbeef), /* NT4 */ + "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n", + GetLastError()); + + ((SID *)sid2)->Revision = 2; + SetLastError(0xdeadbeef); + ret = EqualSid(sid1, sid2); + ok(!ret, "EqualSid with invalid sid should have returned FALSE\n"); + ok(GetLastError() == ERROR_SUCCESS || + broken(GetLastError() == 0xdeadbeef), /* NT4 */ + "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n", + GetLastError()); + ((SID *)sid2)->Revision = SID_REVISION; + + FreeSid(sid1); + FreeSid(sid2); +} + START_TEST(security) { init(); @@ -3255,4 +3379,6 @@ START_TEST(security) test_acls(); test_GetSecurityInfo(); test_GetSidSubAuthority(); + test_CheckTokenMembership(); + test_EqualSid(); } diff --git a/rostests/winetests/advapi32/service.c b/rostests/winetests/advapi32/service.c index 0851384b70b..17f89d182a3 100644 --- a/rostests/winetests/advapi32/service.c +++ b/rostests/winetests/advapi32/service.c @@ -38,6 +38,9 @@ static BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID); static BOOL (WINAPI *pEnumServicesStatusExA)(SC_HANDLE, SC_ENUM_TYPE, DWORD, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD, LPDWORD, LPCSTR); +static BOOL (WINAPI *pEnumServicesStatusExW)(SC_HANDLE, SC_ENUM_TYPE, DWORD, + DWORD, LPBYTE, DWORD, LPDWORD, + LPDWORD, LPDWORD, LPCWSTR); static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION, PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*); static BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD); @@ -51,6 +54,7 @@ static void init_function_pointers(void) pChangeServiceConfig2A = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2A"); pEnumServicesStatusExA= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExA"); + pEnumServicesStatusExW= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExW"); pGetSecurityInfo = (void *)GetProcAddress(hadvapi32, "GetSecurityInfo"); pQueryServiceConfig2A= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2A"); pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W"); @@ -1030,6 +1034,7 @@ static void test_enum_svc(void) SC_HANDLE scm_handle; BOOL ret; DWORD bufsize, needed, returned, resume; + DWORD neededW, returnedW; DWORD tempneeded, tempreturned, missing; DWORD servicecountactive, servicecountinactive; ENUM_SERVICE_STATUS *services; @@ -1160,6 +1165,12 @@ static void test_enum_svc(void) "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); } + /* Test to show we get the same needed buffer size for the W-call */ + neededW = 0xdeadbeef; + ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, + &neededW, &returnedW, NULL); + ok(neededW == needed, "Expected needed buffersize to be the same for A- and W-calls\n"); + /* Store the needed bytes */ tempneeded = needed; @@ -1506,6 +1517,12 @@ static void test_enum_svc(void) "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); } + /* Test to show we get the same needed buffer size for the W-call */ + neededW = 0xdeadbeef; + ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, + NULL, 0, &neededW, &returnedW, NULL, NULL); + ok(neededW == needed, "Expected needed buffersize to be the same for A- and W-calls\n"); + /* Store the needed bytes */ tempneeded = needed; diff --git a/rostests/winetests/advapi32/testlist.c b/rostests/winetests/advapi32/testlist.c index c7fbee87c66..9722479c9be 100644 --- a/rostests/winetests/advapi32/testlist.c +++ b/rostests/winetests/advapi32/testlist.c @@ -12,6 +12,7 @@ extern void func_crypt_lmhash(void); extern void func_crypt_md4(void); extern void func_crypt_md5(void); extern void func_crypt_sha(void); +extern void func_eventlog(void); extern void func_lsa(void); extern void func_registry(void); extern void func_security(void); @@ -25,6 +26,7 @@ const struct test winetest_testlist[] = { "crypt_md4", func_crypt_md4 }, { "crypt_md5", func_crypt_md5 }, { "crypt_sha", func_crypt_sha }, + { "eventlog", func_eventlog }, { "lsa", func_lsa }, { "registry", func_registry }, { "security", func_security }, diff --git a/rostests/winetests/fusion/asmenum.c b/rostests/winetests/fusion/asmenum.c index 48f7b2a97b1..cb6ea3dfdeb 100644 --- a/rostests/winetests/fusion/asmenum.c +++ b/rostests/winetests/fusion/asmenum.c @@ -209,6 +209,8 @@ static void test_CreateAssemblyEnum(void) ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); ok(asmenum == (IAssemblyEnum *)0xdeadbeef, "Expected asmenum to be unchanged, got %p\n", asmenum); + + IAssemblyName_Release(asmname); } typedef struct _tagASMNAME diff --git a/rostests/winetests/fusion/asmname.c b/rostests/winetests/fusion/asmname.c index 442f00f7c45..824837b25fc 100644 --- a/rostests/winetests/fusion/asmname.c +++ b/rostests/winetests/fusion/asmname.c @@ -726,6 +726,7 @@ static void test_CreateAssemblyNameObject(void) ok(name != NULL, "Expected non-NULL name\n"); size = MAX_PATH; + str[0] = '\0'; hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); todo_wine @@ -786,6 +787,7 @@ static void test_CreateAssemblyNameObject(void) "Expected FUSION_E_INVALID_NAME, got %08x\n", hr); ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name); } + if(SUCCEEDED(hr)) IAssemblyName_Release(name); /* no '=' */ to_widechar(namestr, "wine, PublicKeyToken"); diff --git a/rostests/winetests/hlink/hlink.c b/rostests/winetests/hlink/hlink.c index 5e07359fdf5..1a7536fee93 100644 --- a/rostests/winetests/hlink/hlink.c +++ b/rostests/winetests/hlink/hlink.c @@ -57,15 +57,6 @@ DEFINE_EXPECT(IsSystemMoniker); DEFINE_EXPECT(BindToStorage); DEFINE_EXPECT(GetDisplayName); -static const char *debugstr_w(LPCWSTR str) -{ - static char buf[1024]; - if(!str) - return "(null)"; - WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL); - return buf; -} - static const char *debugstr_guid(REFIID riid) { static char buf[50]; @@ -80,7 +71,7 @@ static const char *debugstr_guid(REFIID riid) static void test_HlinkIsShortcut(void) { - int i; + UINT i; HRESULT hres; static const WCHAR file0[] = {'f','i','l','e',0}; @@ -597,13 +588,13 @@ static void test_HlinkCreateExtensionServices(void) hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef, 0, &headers); ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres); - ok(!lstrcmpW(headers, headersexW), "unexpected headers \"%s\"\n", debugstr_w(headers)); + ok(!lstrcmpW(headers, headersexW), "unexpected headers %s\n", wine_dbgstr_w(headers)); CoTaskMemFree(headers); headers = (void*)0xdeadbeef; hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers); ok(hres == S_OK, "OnResponse failed: %08x\n", hres); - ok(headers == NULL, "unexpected headers \"%s\"\n", debugstr_w(headers)); + ok(headers == NULL, "unexpected headers %s\n", wine_dbgstr_w(headers)); IHttpNegotiate_Release(http_negotiate); IAuthenticate_Release(authenticate); @@ -635,7 +626,7 @@ static void test_HlinkParseDisplayName(void) hres = IMoniker_GetDisplayName(mon, bctx, 0, &name); ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres); - ok(!lstrcmpW(name, winehq_urlW), "wrong display name %s\n", debugstr_w(name)); + ok(!lstrcmpW(name, winehq_urlW), "wrong display name %s\n", wine_dbgstr_w(name)); CoTaskMemFree(name); hres = IMoniker_IsSystemMoniker(mon, &issys); @@ -662,13 +653,14 @@ static void test_HlinkParseDisplayName(void) hres = IMoniker_GetDisplayName(mon, bctx, 0, &name); ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres); - ok(!lstrcmpW(name, invalid_urlW), "wrong display name %s\n", debugstr_w(name)); + ok(!lstrcmpW(name, invalid_urlW), "wrong display name %s\n", wine_dbgstr_w(name)); CoTaskMemFree(name); hres = IMoniker_IsSystemMoniker(mon, &issys); ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres); ok(issys == MKSYS_FILEMONIKER, "issys=%x\n", issys); + IMoniker_Release(mon); IBindCtx_Release(bctx); } @@ -1025,6 +1017,110 @@ static void test_HlinkResolveMonikerForData(void) IBindCtx_Release(bctx); } +static void test_HlinkGetSetMonikerReference(void) +{ + IMoniker *found_trgt, *dummy, *dummy2; + IHlink *hlink; + HRESULT hres; + const WCHAR one[] = {'1',0}; + const WCHAR two[] = {'2',0}; + const WCHAR name[] = {'a',0}; + WCHAR *found_loc; + + /* create two dummy monikers to use as targets */ + hres = CreateItemMoniker(one, one, &dummy); + ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres); + + hres = CreateItemMoniker(two, two, &dummy2); + ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres); + + /* create a new hlink: target => dummy, location => one */ + hres = HlinkCreateFromMoniker(dummy, one, name, NULL, 0, NULL, &IID_IHlink, (void**)&hlink); + ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres); + + /* validate the target and location */ + hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc); + ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres); + ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt); + ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc)); + IMoniker_Release(found_trgt); + CoTaskMemFree(found_loc); + + /* set location => two */ + hres = IHlink_SetMonikerReference(hlink, HLINKSETF_LOCATION, dummy2, two); + ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres); + + hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc); + ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt); + ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc)); + IMoniker_Release(found_trgt); + CoTaskMemFree(found_loc); + + /* set target => dummy2 */ + hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET, dummy2, one); + ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres); + + hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc); + ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt); + ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc)); + IMoniker_Release(found_trgt); + CoTaskMemFree(found_loc); + + /* set target => dummy, location => one */ + hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, dummy, one); + ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres); + + hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc); + ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt); + ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc)); + IMoniker_Release(found_trgt); + CoTaskMemFree(found_loc); + + /* no HLINKSETF flags */ + hres = IHlink_SetMonikerReference(hlink, 0, dummy2, two); + ok(hres == E_INVALIDARG, "IHlink_SetMonikerReference should've failed with E_INVALIDARG (0x%08x), failed with 0x%08x\n", E_INVALIDARG, hres); + + hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc); + ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt); + ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc)); + IMoniker_Release(found_trgt); + CoTaskMemFree(found_loc); + + /* invalid HLINKSETF flags */ + hres = IHlink_SetMonikerReference(hlink, 12, dummy2, two); + ok(hres == 12, "IHlink_SetMonikerReference should've failed with 0x%08x, failed with 0x%08x\n", 12, hres); + + hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc); + ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt); + ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc)); + IMoniker_Release(found_trgt); + CoTaskMemFree(found_loc); + + /* valid & invalid HLINKSETF flags */ + hres = IHlink_SetMonikerReference(hlink, 12 | HLINKSETF_TARGET, dummy2, two); + ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres); + + hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc); + ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt); + ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc)); + IMoniker_Release(found_trgt); + CoTaskMemFree(found_loc); + + /* NULL args */ + hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, NULL, NULL); + ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres); + + hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc); + ok(found_trgt == NULL, "Found target should've been %p, was: %p\n", NULL, found_trgt); + ok(found_loc == NULL, "Found location should've been %s, was: %s\n", wine_dbgstr_w(NULL), wine_dbgstr_w(found_loc)); + if(found_trgt) + IMoniker_Release(found_trgt); + + IHlink_Release(hlink); + IMoniker_Release(dummy2); + IMoniker_Release(dummy); +} + START_TEST(hlink) { CoInitialize(NULL); @@ -1036,6 +1132,7 @@ START_TEST(hlink) test_HlinkCreateExtensionServices(); test_HlinkParseDisplayName(); test_HlinkResolveMonikerForData(); + test_HlinkGetSetMonikerReference(); CoUninitialize(); } diff --git a/rostests/winetests/kernel32/actctx.c b/rostests/winetests/kernel32/actctx.c index 8a8d03e224e..8f51dfb1d96 100644 --- a/rostests/winetests/kernel32/actctx.c +++ b/rostests/winetests/kernel32/actctx.c @@ -869,7 +869,7 @@ static void test_basic_info(HANDLE handle) SIZE_T size; BOOL b; - b = pQueryActCtxW(0, handle, NULL, + b = pQueryActCtxW(QUERY_ACTCTX_FLAG_NO_ADDREF, handle, NULL, ActivationContextBasicInformation, &basic, sizeof(basic), &size); @@ -878,7 +878,8 @@ static void test_basic_info(HANDLE handle) ok (basic.dwFlags == 0, "unexpected flags %x\n",basic.dwFlags); ok (basic.hActCtx == handle, "unexpected handle\n"); - b = pQueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, handle, NULL, + b = pQueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX | + QUERY_ACTCTX_FLAG_NO_ADDREF, handle, NULL, ActivationContextBasicInformation, &basic, sizeof(basic), &size); if (handle) @@ -960,15 +961,15 @@ static void test_actctx(void) pReleaseActCtx(handle); } - if(!create_manifest_file("test3.manifest", manifest2, -1, "testdep.manifest", testdep_manifest2)) { + if(!create_manifest_file("test2-2.manifest", manifest2, -1, "testdep.manifest", testdep_manifest2)) { skip("Could not create manifest file\n"); return; } trace("manifest2 depmanifest2\n"); - handle = test_create("test3.manifest", manifest2); - DeleteFileA("test3.manifest"); + handle = test_create("test2-2.manifest", manifest2); + DeleteFileA("test2-2.manifest"); DeleteFileA("testdep.manifest"); if(handle != INVALID_HANDLE_VALUE) { test_basic_info(handle); diff --git a/rostests/winetests/kernel32/environ.c b/rostests/winetests/kernel32/environ.c index b3526675b20..19d11b599a2 100755 --- a/rostests/winetests/kernel32/environ.c +++ b/rostests/winetests/kernel32/environ.c @@ -395,7 +395,11 @@ static void test_GetComputerNameExA(void) ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error); /* size is not set in win2k */ - size = MAX_COMP_NAME; + if (size == 0) + { + win_skip("Win2k doesn't set the size\n"); + size = MAX_COMP_NAME; + } name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0])); ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError()); ret = pGetComputerNameExA(ComputerNameDnsDomain, name, &size); @@ -410,7 +414,8 @@ static void test_GetComputerNameExA(void) ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error); /* size is not set in win2k */ - size = MAX_COMP_NAME; + if (size == 0) + size = MAX_COMP_NAME; name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0])); ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError()); ret = pGetComputerNameExA(ComputerNameDnsFullyQualified, name, &size); @@ -425,7 +430,8 @@ static void test_GetComputerNameExA(void) ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error); /* size is not set in win2k */ - size = MAX_COMP_NAME; + if (size == 0) + size = MAX_COMP_NAME; name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0])); ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError()); ret = pGetComputerNameExA(ComputerNameDnsHostname, name, &size); @@ -440,7 +446,8 @@ static void test_GetComputerNameExA(void) ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error); /* size is not set in win2k */ - size = MAX_COMP_NAME; + if (size == 0) + size = MAX_COMP_NAME; name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0])); ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError()); ret = pGetComputerNameExA(ComputerNameNetBIOS, name, &size); diff --git a/rostests/winetests/kernel32/file.c b/rostests/winetests/kernel32/file.c index f53e65df4b8..8b1d667fa78 100755 --- a/rostests/winetests/kernel32/file.c +++ b/rostests/winetests/kernel32/file.c @@ -649,12 +649,10 @@ static void test_CopyFileA(void) ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError()); ret = CopyFileA(source, dest, FALSE); - todo_wine { - ok(!ret, "CopyFileA: expected failure\n"); - ok(GetLastError() == ERROR_USER_MAPPED_FILE || - broken(GetLastError() == ERROR_SHARING_VIOLATION), /* Win9x and WinMe */ - "CopyFileA with mapped dest file: expected ERROR_USER_MAPPED_FILE, got %d\n", GetLastError()); - } + ok(!ret, "CopyFileA: expected failure\n"); + ok(GetLastError() == ERROR_USER_MAPPED_FILE || + broken(GetLastError() == ERROR_SHARING_VIOLATION), /* Win9x */ + "CopyFileA with mapped dest file: expected ERROR_USER_MAPPED_FILE, got %d\n", GetLastError()); CloseHandle(hmapfile); CloseHandle(hfile); @@ -1616,7 +1614,80 @@ static void test_LockFile(void) DeleteFileA( filename ); } -static inline int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2, BOOL is_win9x ) +static BOOL create_fake_dll( LPCSTR filename ) +{ + IMAGE_DOS_HEADER *dos; + IMAGE_NT_HEADERS *nt; + IMAGE_SECTION_HEADER *sec; + BYTE *buffer; + DWORD lfanew = sizeof(*dos); + DWORD size = lfanew + sizeof(*nt) + sizeof(*sec); + DWORD written; + BOOL ret; + + HANDLE file = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); + if (file == INVALID_HANDLE_VALUE) return FALSE; + + buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size ); + + dos = (IMAGE_DOS_HEADER *)buffer; + dos->e_magic = IMAGE_DOS_SIGNATURE; + dos->e_cblp = sizeof(*dos); + dos->e_cp = 1; + dos->e_cparhdr = lfanew / 16; + dos->e_minalloc = 0; + dos->e_maxalloc = 0xffff; + dos->e_ss = 0x0000; + dos->e_sp = 0x00b8; + dos->e_lfarlc = lfanew; + dos->e_lfanew = lfanew; + + nt = (IMAGE_NT_HEADERS *)(buffer + lfanew); + nt->Signature = IMAGE_NT_SIGNATURE; +#if defined __i386__ + nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386; +#elif defined __x86_64__ + nt->FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64; +#elif defined __powerpc__ + nt->FileHeader.Machine = IMAGE_FILE_MACHINE_POWERPC; +#else +# error You must specify the machine type +#endif + nt->FileHeader.NumberOfSections = 1; + nt->FileHeader.SizeOfOptionalHeader = IMAGE_SIZEOF_NT_OPTIONAL_HEADER; + nt->FileHeader.Characteristics = IMAGE_FILE_DLL | IMAGE_FILE_EXECUTABLE_IMAGE; + nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; + nt->OptionalHeader.MajorLinkerVersion = 1; + nt->OptionalHeader.MinorLinkerVersion = 0; + nt->OptionalHeader.ImageBase = 0x10000000; + nt->OptionalHeader.SectionAlignment = 0x1000; + nt->OptionalHeader.FileAlignment = 0x1000; + nt->OptionalHeader.MajorOperatingSystemVersion = 1; + nt->OptionalHeader.MinorOperatingSystemVersion = 0; + nt->OptionalHeader.MajorImageVersion = 1; + nt->OptionalHeader.MinorImageVersion = 0; + nt->OptionalHeader.MajorSubsystemVersion = 4; + nt->OptionalHeader.MinorSubsystemVersion = 0; + nt->OptionalHeader.SizeOfImage = 0x2000; + nt->OptionalHeader.SizeOfHeaders = size; + nt->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI; + nt->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; + + sec = (IMAGE_SECTION_HEADER *)(nt + 1); + memcpy( sec->Name, ".rodata", sizeof(".rodata") ); + sec->Misc.VirtualSize = 0x1000; + sec->VirtualAddress = 0x1000; + sec->SizeOfRawData = 0; + sec->PointerToRawData = 0; + sec->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; + + ret = WriteFile( file, buffer, size, &written, NULL ) && written == size; + HeapFree( GetProcessHeap(), 0, buffer ); + CloseHandle( file ); + return ret; +} + +static int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2, BOOL is_win9x ) { if (!is_win9x) { @@ -1641,6 +1712,14 @@ static inline int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD ac return 1; } +static int is_sharing_map_compatible( DWORD map_access, DWORD access2, DWORD sharing2 ) +{ + if ((map_access == PAGE_READWRITE || map_access == PAGE_EXECUTE_READWRITE) && + !(sharing2 & FILE_SHARE_WRITE)) return 0; + if ((map_access & SEC_IMAGE) && (access2 & GENERIC_WRITE)) return 0; + return 1; +} + static void test_file_sharing(void) { static const DWORD access_modes[] = @@ -1651,20 +1730,20 @@ static void test_file_sharing(void) FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE }; + static const DWORD mapping_modes[] = + { PAGE_READONLY, PAGE_WRITECOPY, PAGE_READWRITE, SEC_IMAGE | PAGE_WRITECOPY }; int a1, s1, a2, s2; int ret; HANDLE h, h2; BOOL is_win9x = FALSE; /* make sure the file exists */ - h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); - if (h == INVALID_HANDLE_VALUE) + if (!create_fake_dll( filename )) { ok(0, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError()); return; } is_win9x = GetFileAttributesW(filenameW) == INVALID_FILE_ATTRIBUTES; - CloseHandle( h ); for (a1 = 0; a1 < sizeof(access_modes)/sizeof(access_modes[0]); a1++) { @@ -1693,12 +1772,10 @@ static void test_file_sharing(void) SetLastError(0xdeadbeef); h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2], NULL, OPEN_EXISTING, 0, 0 ); - + ret = GetLastError(); if (is_sharing_compatible( access_modes[a1], sharing_modes[s1], access_modes[a2], sharing_modes[s2], is_win9x )) { - ret = GetLastError(); - ok( h2 != INVALID_HANDLE_VALUE, "open failed for modes %x/%x/%x/%x\n", access_modes[a1], sharing_modes[s1], @@ -1706,13 +1783,9 @@ static void test_file_sharing(void) ok( ret == 0xdeadbeef /* Win9x */ || ret == 0, /* XP */ "wrong error code %d\n", ret ); - - CloseHandle( h2 ); } else { - ret = GetLastError(); - ok( h2 == INVALID_HANDLE_VALUE, "open succeeded for modes %x/%x/%x/%x\n", access_modes[a1], sharing_modes[s1], @@ -1720,12 +1793,107 @@ static void test_file_sharing(void) ok( ret == ERROR_SHARING_VIOLATION, "wrong error code %d\n", ret ); } + if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 ); } } CloseHandle( h ); } } + for (a1 = 0; a1 < sizeof(mapping_modes)/sizeof(mapping_modes[0]); a1++) + { + HANDLE m; + + create_fake_dll( filename ); + SetLastError(0xdeadbeef); + h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 ); + if (h == INVALID_HANDLE_VALUE) + { + ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError()); + return; + } + m = CreateFileMappingA( h, NULL, mapping_modes[a1], 0, 0, NULL ); + ok( m != 0, "failed to create mapping %x err %u\n", mapping_modes[a1], GetLastError() ); + CloseHandle( h ); + if (!m) continue; + + for (a2 = 0; a2 < sizeof(access_modes)/sizeof(access_modes[0]); a2++) + { + for (s2 = 0; s2 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s2++) + { + /* Win9x doesn't support FILE_SHARE_DELETE */ + if (is_win9x && (sharing_modes[s2] & FILE_SHARE_DELETE)) + continue; + + SetLastError(0xdeadbeef); + h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2], + NULL, OPEN_EXISTING, 0, 0 ); + + ret = GetLastError(); + if (h2 == INVALID_HANDLE_VALUE) + { + if (is_sharing_map_compatible(mapping_modes[a1], access_modes[a2], sharing_modes[s2])) + ok( is_win9x, /* there's no sharing at all with a mapping on win9x */ + "open failed for modes map %x/%x/%x\n", + mapping_modes[a1], access_modes[a2], sharing_modes[s2] ); + ok( ret == ERROR_SHARING_VIOLATION, + "wrong error code %d\n", ret ); + } + else + { + if (!is_sharing_map_compatible(mapping_modes[a1], access_modes[a2], sharing_modes[s2])) + ok( broken(1), /* no checking on nt4 */ + "open succeeded for modes map %x/%x/%x\n", + mapping_modes[a1], access_modes[a2], sharing_modes[s2] ); + ok( ret == 0xdeadbeef /* Win9x */ || + ret == 0, /* XP */ + "wrong error code %d\n", ret ); + CloseHandle( h2 ); + } + } + } + + /* try CREATE_ALWAYS over an existing mapping */ + SetLastError(0xdeadbeef); + h2 = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, CREATE_ALWAYS, 0, 0 ); + ret = GetLastError(); + if ((mapping_modes[a1] & SEC_IMAGE) || is_win9x) + { + ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] ); + ok( ret == ERROR_SHARING_VIOLATION, "wrong error code %d for %x\n", ret, mapping_modes[a1] ); + } + else + { + ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] ); + ok( ret == ERROR_USER_MAPPED_FILE, "wrong error code %d for %x\n", ret, mapping_modes[a1] ); + } + if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 ); + + /* try DELETE_ON_CLOSE over an existing mapping */ + SetLastError(0xdeadbeef); + h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0 ); + ret = GetLastError(); + if (is_win9x) + { + ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] ); + ok( ret == ERROR_SHARING_VIOLATION, "wrong error code %d for %x\n", ret, mapping_modes[a1] ); + } + else if (mapping_modes[a1] & SEC_IMAGE) + { + ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] ); + ok( ret == ERROR_ACCESS_DENIED, "wrong error code %d for %x\n", ret, mapping_modes[a1] ); + } + else + { + ok( h2 != INVALID_HANDLE_VALUE, "open failed for map %x err %u\n", mapping_modes[a1], ret ); + } + if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 ); + + CloseHandle( m ); + } + SetLastError(0xdeadbeef); h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, 0 ); ok( h != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError() ); diff --git a/rostests/winetests/kernel32/locale.c b/rostests/winetests/kernel32/locale.c index a5b7173aa85..4fdb222c96e 100755 --- a/rostests/winetests/kernel32/locale.c +++ b/rostests/winetests/kernel32/locale.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "wine/test.h" #include "windef.h" @@ -466,7 +467,10 @@ static void test_GetDateFormatA(void) int ret; SYSTEMTIME curtime; LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); + LCID lcid_ru = MAKELCID(MAKELANGID(LANG_RUSSIAN, SUBLANG_NEUTRAL), SORT_DEFAULT); char buffer[BUFFER_SIZE], input[BUFFER_SIZE], Expected[BUFFER_SIZE]; + char Broken[BUFFER_SIZE]; + char short_day[10], month[10], genitive_month[10]; memset(&curtime, 2, sizeof(SYSTEMTIME)); /* Invalid time */ STRINGSA("ddd',' MMM dd yy",""); @@ -542,7 +546,85 @@ static void test_GetDateFormatA(void) &curtime, input, buffer, COUNTOF(buffer)); ok(!ret && GetLastError() == ERROR_INVALID_FLAGS, "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError()); + + ret = GetDateFormat(lcid_ru, 0, &curtime, "ddMMMM", buffer, COUNTOF(buffer)); + if (!ret) + { + win_skip("LANG_RUSSIAN locale data unavailable\n"); + return; + } + + /* month part should be in genitive form */ + strcpy(genitive_month, buffer + 2); + ret = GetDateFormat(lcid_ru, 0, &curtime, "MMMM", buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + strcpy(month, buffer); + ok(strcmp(genitive_month, month) != 0, "Expected different month forms\n"); + + ret = GetDateFormat(lcid_ru, 0, &curtime, "ddd", buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + strcpy(short_day, buffer); + + STRINGSA("dd MMMMddd dd", ""); + sprintf(Expected, "04 %s%s 04", genitive_month, short_day); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); EXPECT_EQA; + + STRINGSA("MMMMddd dd", ""); + sprintf(Expected, "%s%s 04", month, short_day); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + EXPECT_EQA; + + STRINGSA("MMMMddd", ""); + sprintf(Expected, "%s%s", month, short_day); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + EXPECT_EQA; + + STRINGSA("MMMMdd", ""); + sprintf(Expected, "%s04", genitive_month); + sprintf(Broken, "%s04", month); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || + broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, + "Expected '%s', got '%s'\n", Expected, buffer); + + STRINGSA("MMMMdd ddd", ""); + sprintf(Expected, "%s04 %s", genitive_month, short_day); + sprintf(Broken, "%s04 %s", month, short_day); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || + broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, + "Expected '%s', got '%s'\n", Expected, buffer); + + STRINGSA("dd dddMMMM", ""); + sprintf(Expected, "04 %s%s", short_day, month); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + EXPECT_EQA; + + STRINGSA("dd dddMMMM ddd MMMMdd", ""); + sprintf(Expected, "04 %s%s %s %s04", short_day, month, short_day, genitive_month); + sprintf(Broken, "04 %s%s %s %s04", short_day, month, short_day, month); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || + broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, + "Expected '%s', got '%s'\n", Expected, buffer); + + /* with literal part */ + STRINGSA("ddd',' MMMM dd", ""); + sprintf(Expected, "%s, %s 04", short_day, genitive_month); + sprintf(Broken, "%s, %s 04", short_day, month); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || + broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, + "Expected '%s', got '%s'\n", Expected, buffer); } static void test_GetDateFormatW(void) diff --git a/rostests/winetests/kernel32/path.c b/rostests/winetests/kernel32/path.c index dfe889f26c8..6acb740f27e 100755 --- a/rostests/winetests/kernel32/path.c +++ b/rostests/winetests/kernel32/path.c @@ -952,14 +952,133 @@ static void test_GetTempPath(void) SetEnvironmentVariableA("TMP", save_TMP); } +static void test_GetLongPathNameA(void) +{ + DWORD length, explength, hostsize; + char tempfile[MAX_PATH]; + char longpath[MAX_PATH]; + char unc_prefix[MAX_PATH]; + char unc_short[MAX_PATH], unc_long[MAX_PATH]; + char temppath[MAX_PATH], temppath2[MAX_PATH]; + HANDLE file; + + if (!pGetLongPathNameA) + return; + + GetTempPathA(MAX_PATH, tempfile); + lstrcatA(tempfile, "longfilename.longext"); + + file = CreateFileA(tempfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + CloseHandle(file); + + /* Test a normal path with a small buffer size */ + memset(temppath, 0, MAX_PATH); + length = pGetLongPathNameA(tempfile, temppath, 4); + /* We have a failure so length should be the minumum plus the terminating '0' */ + ok(length >= lstrlen(tempfile) + 1, "Wrong length\n"); + ok(temppath[0] == 0, "Buffer should not have been touched\n"); + + /* Some UNC syntax tests */ + + memset(temppath, 0, MAX_PATH); + memset(temppath2, 0, MAX_PATH); + lstrcpyA(temppath2, "\\\\?\\"); + lstrcatA(temppath2, tempfile); + explength = length + 4; + + SetLastError(0xdeadbeef); + length = pGetLongPathNameA(temppath2, NULL, 0); + if (length == 0 && GetLastError() == ERROR_BAD_NET_NAME) + { + win_skip("UNC syntax tests don't work on Win98/WinMe\n"); + DeleteFileA(tempfile); + return; + } + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + + length = pGetLongPathNameA(temppath2, NULL, MAX_PATH); + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + + length = pGetLongPathNameA(temppath2, temppath, 4); + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + ok(temppath[0] == 0, "Buffer should not have been touched\n"); + + /* Now an UNC path with the computername */ + lstrcpyA(unc_prefix, "\\\\"); + hostsize = sizeof(unc_prefix) - 2; + GetComputerName(unc_prefix + 2, &hostsize); + lstrcatA(unc_prefix, "\\"); + + /* Create a short syntax for the whole unc path */ + memset(unc_short, 0, MAX_PATH); + GetShortPathNameA(tempfile, temppath, MAX_PATH); + lstrcpyA(unc_short, unc_prefix); + unc_short[lstrlenA(unc_short)] = temppath[0]; + lstrcatA(unc_short, "$\\"); + lstrcatA(unc_short, strchr(temppath, '\\') + 1); + + /* Create a long syntax for reference */ + memset(longpath, 0, MAX_PATH); + pGetLongPathNameA(tempfile, temppath, MAX_PATH); + lstrcpyA(longpath, unc_prefix); + longpath[lstrlenA(longpath)] = temppath[0]; + lstrcatA(longpath, "$\\"); + lstrcatA(longpath, strchr(temppath, '\\') + 1); + + /* NULL test */ + SetLastError(0xdeadbeef); + length = pGetLongPathNameA(unc_short, NULL, 0); + if (length == 0 && GetLastError() == ERROR_BAD_NETPATH) + { + /* Seen on Window XP Home */ + win_skip("UNC with computername is not supported\n"); + DeleteFileA(tempfile); + return; + } + explength = lstrlenA(longpath) + 1; + todo_wine + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + + length = pGetLongPathNameA(unc_short, NULL, MAX_PATH); + todo_wine + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + + memset(unc_long, 0, MAX_PATH); + length = pGetLongPathNameA(unc_short, unc_long, lstrlenA(unc_short)); + /* length will include terminating '0' on failure */ + todo_wine + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + ok(unc_long[0] == 0, "Buffer should not have been touched\n"); + + memset(unc_long, 0, MAX_PATH); + length = pGetLongPathNameA(unc_short, unc_long, length); + /* length doesn't include terminating '0' on success */ + explength--; + todo_wine + { + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + ok(!lstrcmpiA(unc_long, longpath), "Expected (%s), got (%s)\n", longpath, unc_long); + } + + DeleteFileA(tempfile); +} + static void test_GetLongPathNameW(void) { - DWORD length; + DWORD length, expanded; + BOOL ret; + HANDLE file; WCHAR empty[MAX_PATH]; + WCHAR tempdir[MAX_PATH], name[200]; + WCHAR dirpath[4 + MAX_PATH + 200]; /* To ease removal */ + WCHAR shortpath[4 + MAX_PATH + 200 + 1 + 200]; + static const WCHAR prefix[] = { '\\','\\','?','\\', 0}; + static const WCHAR backslash[] = { '\\', 0}; + static const WCHAR letterX[] = { 'X', 0}; + + if (!pGetLongPathNameW) + return; - /* Not present in all windows versions */ - if(pGetLongPathNameW) - { SetLastError(0xdeadbeef); length = pGetLongPathNameW(NULL,NULL,0); if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) @@ -975,7 +1094,73 @@ static void test_GetLongPathNameW(void) length = pGetLongPathNameW(empty,NULL,0); ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length); ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError()); + + /* Create a long path name. The path needs to exist for these tests to + * succeed so we need the "\\?\" prefix when creating directories and + * files. + */ + name[0] = 0; + while (lstrlenW(name) < (sizeof(name)/sizeof(WCHAR) - 1)) + lstrcatW(name, letterX); + + GetTempPathW(MAX_PATH, tempdir); + + lstrcpyW(shortpath, prefix); + lstrcatW(shortpath, tempdir); + lstrcatW(shortpath, name); + lstrcpyW(dirpath, shortpath); + ret = CreateDirectoryW(shortpath, NULL); + ok(ret, "Could not create the temporary directory : %d\n", GetLastError()); + lstrcatW(shortpath, backslash); + lstrcatW(shortpath, name); + + /* Path does not exist yet and we know it overruns MAX_PATH */ + + /* No prefix */ + SetLastError(0xdeadbeef); + length = pGetLongPathNameW(shortpath + 4, NULL, 0); + ok(length == 0, "Expected 0, got %d\n", length); + todo_wine + ok(GetLastError() == ERROR_PATH_NOT_FOUND, + "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError()); + /* With prefix */ + SetLastError(0xdeadbeef); + length = pGetLongPathNameW(shortpath, NULL, 0); + todo_wine + { + ok(length == 0, "Expected 0, got %d\n", length); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, + "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError()); } + + file = CreateFileW(shortpath, GENERIC_READ|GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, + "Could not create the temporary file : %d.\n", GetLastError()); + CloseHandle(file); + + /* Path exists */ + + /* No prefix */ + SetLastError(0xdeadbeef); + length = pGetLongPathNameW(shortpath + 4, NULL, 0); + todo_wine + { + ok(length == 0, "Expected 0, got %d\n", length); + ok(GetLastError() == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError()); + } + /* With prefix */ + expanded = 4 + (pGetLongPathNameW(tempdir, NULL, 0) - 1) + lstrlenW(name) + 1 + lstrlenW(name) + 1; + SetLastError(0xdeadbeef); + length = pGetLongPathNameW(shortpath, NULL, 0); + ok(length == expanded, "Expected %d, got %d\n", expanded, length); + + /* NULL buffer with length crashes on Windows */ + if (0) + length = pGetLongPathNameW(shortpath, NULL, 20); + + ok(DeleteFileW(shortpath), "Could not delete temporary file\n"); + ok(RemoveDirectoryW(dirpath), "Could not delete temporary directory\n"); } static void test_GetShortPathNameW(void) @@ -1273,11 +1458,18 @@ START_TEST(path) (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"), "NeedCurrentDirectoryForExePathW" ); + /* Report only once */ + if (!pGetLongPathNameA) + win_skip("GetLongPathNameA is not available\n"); + if (!pGetLongPathNameW) + win_skip("GetLongPathNameW is not available\n"); + test_InitPathA(curdir, &curDrive, &otherDrive); test_CurrentDirectoryA(origdir,curdir); test_PathNameA(curdir, curDrive, otherDrive); test_CleanupPathA(origdir,curdir); test_GetTempPath(); + test_GetLongPathNameA(); test_GetLongPathNameW(); test_GetShortPathNameW(); test_GetSystemDirectory(); diff --git a/rostests/winetests/kernel32/volume.c b/rostests/winetests/kernel32/volume.c index 42142e82707..6199d7cf9da 100644 --- a/rostests/winetests/kernel32/volume.c +++ b/rostests/winetests/kernel32/volume.c @@ -155,8 +155,11 @@ static void test_GetVolumeNameForVolumeMountPointA(void) GetLastError()); /* Try on a arbitrary directory */ + /* On FAT filesystems it seems that GetLastError() is set to + ERROR_INVALID_FUNCTION. */ ret = pGetVolumeNameForVolumeMountPointA(temp_path, volume, len); - ok(ret == FALSE && GetLastError() == ERROR_NOT_A_REPARSE_POINT, + ok(ret == FALSE && (GetLastError() == ERROR_NOT_A_REPARSE_POINT || + GetLastError() == ERROR_INVALID_FUNCTION), "GetVolumeNameForVolumeMountPointA failed on %s, last=%d\n", temp_path, GetLastError()); diff --git a/rostests/winetests/lz32/lzexpand_main.c b/rostests/winetests/lz32/lzexpand_main.c index 91fd6873e3f..3e46fb0a47c 100644 --- a/rostests/winetests/lz32/lzexpand_main.c +++ b/rostests/winetests/lz32/lzexpand_main.c @@ -881,10 +881,10 @@ static void test_LZOpenFileW(void) START_TEST(lzexpand_main) { - buf = malloc(uncompressed_data_size * 2); + buf = HeapAlloc(GetProcessHeap(), 0, uncompressed_data_size * 2); test_LZOpenFileA(); test_LZOpenFileW(); test_LZRead(); test_LZCopy(); - free(buf); + HeapFree(GetProcessHeap(), 0, buf); } diff --git a/rostests/winetests/msacm32/msacm.c b/rostests/winetests/msacm32/msacm.c index 26eeb478b63..c7cab5d6605 100644 --- a/rostests/winetests/msacm32/msacm.c +++ b/rostests/winetests/msacm32/msacm.c @@ -94,7 +94,7 @@ static BOOL CALLBACK DriverEnumProc(HACMDRIVERID hadid, /* MSDN says this should fail but it doesn't in practice */ dd.cbStruct = 4; rc = acmDriverDetails(hadid, &dd, 0); - ok(rc == MMSYSERR_NOERROR, + ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NOTSUPPORTED, "acmDriverDetails(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); @@ -119,17 +119,16 @@ static BOOL CALLBACK DriverEnumProc(HACMDRIVERID hadid, /* try valid parameters */ rc = acmDriverDetails(hadid, &dd, 0); - ok(rc == MMSYSERR_NOERROR, + ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NOTSUPPORTED, "acmDriverDetails(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); /* cbStruct should contain size of returned data (at most sizeof(dd)) TODO: should it be *exactly* sizeof(dd), as tested here? */ - if (rc == MMSYSERR_NOERROR) { + if (rc == MMSYSERR_NOERROR) { ok(dd.cbStruct == sizeof(dd), - "acmDriverDetails(): cbStruct = %08x, should be %08lx\n", - dd.cbStruct, (unsigned long)sizeof(dd)); + "acmDriverDetails(): cbStruct = %08x\n", dd.cbStruct); } if (rc == MMSYSERR_NOERROR && winetest_interactive) { @@ -210,7 +209,7 @@ static BOOL CALLBACK DriverEnumProc(HACMDRIVERID hadid, /* try valid parameters */ rc = acmDriverOpen(&had, hadid, 0); - ok(rc == MMSYSERR_NOERROR, + ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NODRIVER, "acmDriverOpen(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); diff --git a/rostests/winetests/msi/automation.c b/rostests/winetests/msi/automation.c index b792fa722bd..8a0eede3066 100644 --- a/rostests/winetests/msi/automation.c +++ b/rostests/winetests/msi/automation.c @@ -34,8 +34,8 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); -static const char *msifile = "winetest.msi"; -static const WCHAR szMsifile[] = {'w','i','n','e','t','e','s','t','.','m','s','i',0}; +static const char *msifile = "winetest-automation.msi"; +static const WCHAR szMsifile[] = {'w','i','n','e','t','e','s','t','-','a','u','t','o','m','a','t','i','o','n','.','m','s','i',0}; static const WCHAR szMSITEST[] = { 'M','S','I','T','E','S','T',0 }; static const WCHAR szProductCode[] = { '{','F','1','C','3','A','F','5','0','-','8','B','5','6','-','4','A','6','9','-','A','0','0','C','-','0','0','7','7','3','F','E','4','2','F','3','0','}',0 }; static const WCHAR szUpgradeCode[] = { '{','C','E','0','6','7','E','8','D','-','2','E','1','A','-','4','3','6','7','-','B','7','3','4','-','4','E','B','2','B','D','A','D','6','5','6','5','}',0 }; @@ -271,6 +271,27 @@ static void create_database(const CHAR *name, const msi_table *tables, int num_t MsiCloseHandle(db); } +static BOOL create_package(LPWSTR path) +{ + DWORD len; + + /* Prepare package */ + create_database(msifile, tables, + sizeof(tables) / sizeof(msi_table), summary_info, + sizeof(summary_info) / sizeof(msi_summary_info)); + + len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, + CURR_DIR, -1, path, MAX_PATH); + ok(len, "MultiByteToWideChar returned error %d\n", GetLastError()); + if (!len) + return FALSE; + + /* lstrcatW does not work on win95 */ + path[len - 1] = '\\'; + memcpy(&path[len], szMsifile, sizeof(szMsifile)); + return TRUE; +} + /* * Installation helpers */ @@ -456,35 +477,32 @@ static void test_dispid(void) ok(dispid == 1, "Expected 1, got %d\n", dispid); dispid = get_dispid(pInstaller, "OpenPackage"); ok(dispid == 2, "Expected 2, got %d\n", dispid); + dispid = get_dispid(pInstaller, "OpenProduct"); + ok(dispid == 3, "Expected 3, got %d\n", dispid); dispid = get_dispid(pInstaller, "OpenDatabase"); ok(dispid == 4, "Expected 4, got %d\n", dispid); + dispid = get_dispid(pInstaller, "SummaryInformation"); + ok(dispid == 5, "Expected 5, got %d\n", dispid); dispid = get_dispid( pInstaller, "UILevel" ); ok(dispid == 6, "Expected 6, got %d\n", dispid); + dispid = get_dispid(pInstaller, "EnableLog"); + ok(dispid == 7, "Expected 7, got %d\n", dispid); dispid = get_dispid(pInstaller, "InstallProduct"); ok(dispid == 8, "Expected 8, got %d\n", dispid); dispid = get_dispid(pInstaller, "Version"); ok(dispid == 9, "Expected 9, got %d\n", dispid); + dispid = get_dispid(pInstaller, "LastErrorRecord"); + ok(dispid == 10, "Expected 10, got %d\n", dispid); dispid = get_dispid(pInstaller, "RegistryValue"); ok(dispid == 11, "Expected 11, got %d\n", dispid); - todo_wine - { - dispid = get_dispid(pInstaller, "OpenProduct"); - ok(dispid == 3, "Expected 3, got %d\n", dispid); - dispid = get_dispid(pInstaller, "SummaryInformation"); - ok(dispid == 5, "Expected 5, got %d\n", dispid); - dispid = get_dispid(pInstaller, "EnableLog"); - ok(dispid == 7, "Expected 7, got %d\n", dispid); - dispid = get_dispid(pInstaller, "LastErrorRecord"); - ok(dispid == 10, "Expected 10, got %d\n", dispid); - dispid = get_dispid(pInstaller, "Environment"); - ok(dispid == 12, "Expected 12, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FileAttributes"); - ok(dispid == 13, "Expected 13, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FileSize"); - ok(dispid == 15, "Expected 15, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FileVersion"); - ok(dispid == 16, "Expected 16, got %d\n", dispid); - } + dispid = get_dispid(pInstaller, "Environment"); + ok(dispid == 12, "Expected 12, got %d\n", dispid); + dispid = get_dispid(pInstaller, "FileAttributes"); + ok(dispid == 13, "Expected 13, got %d\n", dispid); + dispid = get_dispid(pInstaller, "FileSize"); + ok(dispid == 15, "Expected 15, got %d\n", dispid); + dispid = get_dispid(pInstaller, "FileVersion"); + ok(dispid == 16, "Expected 16, got %d\n", dispid); dispid = get_dispid(pInstaller, "ProductState"); ok(dispid == 17, "Expected 17, got %d\n", dispid); dispid = get_dispid(pInstaller, "ProductInfo"); @@ -592,7 +610,8 @@ static void test_dispatch(void) DISPID dispid; OLECHAR *name; VARIANT varresult; - VARIANTARG vararg[2]; + VARIANTARG vararg[3]; + WCHAR path[MAX_PATH]; DISPPARAMS dispparams = {NULL, NULL, 0, 0}; /* Test getting ID of a function name that does not exist */ @@ -620,24 +639,159 @@ static void test_dispatch(void) /* Try with NULL params */ hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); - todo_wine ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); + ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); /* Try one empty parameter */ dispparams.rgvarg = vararg; dispparams.cArgs = 1; VariantInit(&vararg[0]); hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); - todo_wine ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); + ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); - /* Try one parameter, function requires two */ + /* Try two empty parameters */ + dispparams.cArgs = 2; + VariantInit(&vararg[0]); + VariantInit(&vararg[1]); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); + + /* Try one parameter, the required BSTR. Second parameter is optional. + * NOTE: The specified package does not exist, which is why the call fails. + */ + dispparams.cArgs = 1; VariantInit(&vararg[0]); V_VT(&vararg[0]) = VT_BSTR; V_BSTR(&vararg[0]) = SysAllocString(szMsifile); hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); - VariantClear(&vararg[0]); - ok(hr == DISP_E_EXCEPTION, "IDispatch::Invoke returned 0x%08x\n", hr); ok_exception(hr, szOpenPackageException); + VariantClear(&vararg[0]); + + /* Provide the required BSTR and an empty second parameter. + * NOTE: The specified package does not exist, which is why the call fails. + */ + dispparams.cArgs = 2; + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(szMsifile); + VariantInit(&vararg[0]); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_EXCEPTION, "IDispatch::Invoke returned 0x%08x\n", hr); + ok_exception(hr, szOpenPackageException); + VariantClear(&vararg[1]); + + /* Provide the required BSTR and two empty parameters. + * NOTE: The specified package does not exist, which is why the call fails. + */ + dispparams.cArgs = 3; + VariantInit(&vararg[2]); + V_VT(&vararg[2]) = VT_BSTR; + V_BSTR(&vararg[2]) = SysAllocString(szMsifile); + VariantInit(&vararg[1]); + VariantInit(&vararg[0]); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_EXCEPTION, "IDispatch::Invoke returned 0x%08x\n", hr); + ok_exception(hr, szOpenPackageException); + VariantClear(&vararg[2]); + + /* Provide the required BSTR and a second parameter with the wrong type. */ + dispparams.cArgs = 2; + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(szMsifile); + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(szMsifile); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); + VariantClear(&vararg[0]); + VariantClear(&vararg[1]); + + /* Create a proper installer package. */ + create_package(path); + + /* Try one parameter, the required BSTR. Second parameter is optional. + * Proper installer package exists. Path to the package is relative. + */ + dispparams.cArgs = 1; + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(szMsifile); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + todo_wine ok(hr == DISP_E_EXCEPTION, "IDispatch::Invoke returned 0x%08x\n", hr); + ok_exception(hr, szOpenPackageException); + VariantClear(&vararg[0]); + if (hr != DISP_E_EXCEPTION) + VariantClear(&varresult); + + /* Try one parameter, the required BSTR. Second parameter is optional. + * Proper installer package exists. Path to the package is absolute. + */ + dispparams.cArgs = 1; + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(path); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == S_OK, "IDispatch::Invoke returned 0x%08x\n", hr); + VariantClear(&vararg[0]); + VariantClear(&varresult); + + /* Provide the required BSTR and an empty second parameter. Proper + * installation package exists. + */ + dispparams.cArgs = 2; + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(path); + VariantInit(&vararg[0]); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == S_OK, "IDispatch::Invoke returned 0x%08x\n", hr); + VariantClear(&vararg[1]); + VariantClear(&varresult); + + /* Provide the required BSTR and two empty parameters. Proper + * installation package exists. + */ + dispparams.cArgs = 3; + VariantInit(&vararg[2]); + V_VT(&vararg[2]) = VT_BSTR; + V_BSTR(&vararg[2]) = SysAllocString(path); + VariantInit(&vararg[1]); + VariantInit(&vararg[0]); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == S_OK, "IDispatch::Invoke returned 0x%08x\n", hr); + VariantClear(&vararg[2]); + VariantClear(&varresult); + + /* Provide the required BSTR and a second parameter with the wrong type. */ + dispparams.cArgs = 2; + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(path); + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(path); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); + VariantClear(&vararg[0]); + VariantClear(&vararg[1]); + + /* Provide the required BSTR and a second parameter that can be coerced to + * VT_I4. + */ + dispparams.cArgs = 2; + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(path); + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_I2; + V_BSTR(&vararg[0]) = 0; + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == S_OK, "IDispatch::Invoke returned 0x%08x\n", hr); + VariantClear(&vararg[1]); + VariantClear(&varresult); + + DeleteFileW(path); /* Test invoking a method as a DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUT */ VariantInit(&vararg[0]); @@ -2353,7 +2507,6 @@ static void test_Installer(void) static WCHAR szIntegerDataException[] = { 'I','n','t','e','g','e','r','D','a','t','a',',','F','i','e','l','d',0 }; WCHAR szPath[MAX_PATH]; HRESULT hr; - UINT len; IDispatch *pSession = NULL, *pDatabase = NULL, *pRecord = NULL, *pStringList = NULL; int iValue, iCount; @@ -2404,17 +2557,7 @@ static void test_Installer(void) IDispatch_Release(pRecord); } - /* Prepare package */ - create_database(msifile, tables, sizeof(tables) / sizeof(msi_table), - summary_info, sizeof(summary_info) / sizeof(msi_summary_info)); - - len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, CURR_DIR, -1, szPath, MAX_PATH); - ok(len, "MultiByteToWideChar returned error %d\n", GetLastError()); - if (!len) return; - - /* lstrcatW does not work on win95 */ - szPath[len - 1] = '\\'; - memcpy(&szPath[len], szMsifile, sizeof(szMsifile)); + create_package(szPath); /* Installer::OpenPackage */ hr = Installer_OpenPackage(szPath, 0, &pSession); diff --git a/rostests/winetests/msi/db.c b/rostests/winetests/msi/db.c index 3af113518f8..399ce585f63 100644 --- a/rostests/winetests/msi/db.c +++ b/rostests/winetests/msi/db.c @@ -31,9 +31,10 @@ #include "wine/test.h" -static const char *msifile = "winetest.msi"; -static const char *msifile2 = "winetst2.msi"; -static const char *mstfile = "winetst.mst"; +static const char *msifile = "winetest-db.msi"; +static const char *msifile2 = "winetst2-db.msi"; +static const char *mstfile = "winetst-db.mst"; +static const WCHAR msifileW[] = {'w','i','n','e','t','e','s','t','-','d','b','.','m','s','i',0}; static void test_msidatabase(void) { @@ -921,6 +922,8 @@ static void test_viewmodify(void) r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec ); ok(r == ERROR_SUCCESS, "MsiViewModify failed\n"); + r = MsiCloseHandle(hrec); + ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); r = MsiViewClose(hview); ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); r = MsiCloseHandle(hview); @@ -1760,6 +1763,30 @@ static void test_where(void) ok( r == ERROR_SUCCESS, "query failed: %d\n", r ); MsiCloseHandle( rec ); + rec = 0; + query = "SELECT * FROM `Media` WHERE `DiskPrompt` < 'Cabinet'"; + r = do_query(hdb, query, &rec); + ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %d\n", r ); + MsiCloseHandle( rec ); + + rec = 0; + query = "SELECT * FROM `Media` WHERE `DiskPrompt` > 'Cabinet'"; + r = do_query(hdb, query, &rec); + ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %d\n", r ); + MsiCloseHandle( rec ); + + rec = 0; + query = "SELECT * FROM `Media` WHERE `DiskPrompt` <> 'Cabinet'"; + r = do_query(hdb, query, &rec); + todo_wine ok( r == ERROR_SUCCESS, "query failed: %d\n", r ); + MsiCloseHandle( rec ); + + rec = 0; + query = "SELECT * FROM `Media` WHERE `DiskPrompt` = 'Cabinet'"; + r = do_query(hdb, query, &rec); + ok( r == ERROR_NO_MORE_ITEMS, "query failed: %d\n", r ); + MsiCloseHandle( rec ); + rec = MsiCreateRecord(1); MsiRecordSetString(rec, 1, ""); @@ -5539,6 +5566,8 @@ static void enum_stream_names(IStorage *stg) ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(stm != NULL, "Expected non-NULL stream\n"); + CoTaskMemFree(stat.pwcsName); + sz = MAX_PATH; memset(data, 'a', MAX_PATH); hr = IStream_Read(stm, data, sz, &count); @@ -5569,8 +5598,6 @@ static void test_defaultdatabase(void) MSIHANDLE hdb; IStorage *stg = NULL; - static const WCHAR msifileW[] = {'w','i','n','e','t','e','s','t','.','m','s','i',0}; - DeleteFile(msifile); r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb); diff --git a/rostests/winetests/msi/format.c b/rostests/winetests/msi/format.c index 2d949e358e6..4827a209f46 100644 --- a/rostests/winetests/msi/format.c +++ b/rostests/winetests/msi/format.c @@ -27,7 +27,7 @@ #include "wine/test.h" -static const char msifile[] = "winetest.msi"; +static const char msifile[] = "winetest-format.msi"; static UINT run_query( MSIHANDLE hdb, const char *query ) { @@ -315,17 +315,16 @@ static MSIHANDLE helper_createpackage( const char *szName ) static void test_createpackage(void) { - static const CHAR filename[] = "winetest.msi"; MSIHANDLE hPackage = 0; UINT res; - hPackage = helper_createpackage( filename ); + hPackage = helper_createpackage( msifile ); ok ( hPackage != 0, " Failed to create package\n"); res = MsiCloseHandle( hPackage); ok( res == ERROR_SUCCESS , "Failed to close package\n" ); - DeleteFile( filename ); + DeleteFile( msifile ); } static void test_formatrecord(void) @@ -1620,14 +1619,13 @@ static void test_formatrecord(void) static void test_formatrecord_package(void) { - static const CHAR filename[] = "winetest.msi"; char buffer[100]; MSIHANDLE hrec; MSIHANDLE package; UINT r; DWORD sz=100; - package = helper_createpackage( filename ); + package = helper_createpackage( msifile ); ok(package!=0, "Unable to create package\n"); hrec = MsiCreateRecord(12); @@ -2117,7 +2115,7 @@ static void test_formatrecord_package(void) r = MsiCloseHandle(package); ok(r==ERROR_SUCCESS, "Unable to close package\n"); - DeleteFile( filename ); + DeleteFile( msifile ); } static void test_formatrecord_tables(void) @@ -2383,12 +2381,11 @@ static void test_formatrecord_tables(void) static void test_processmessage(void) { - static const CHAR filename[] = "winetest.msi"; MSIHANDLE hrec; MSIHANDLE package; int r; - package = helper_createpackage( filename ); + package = helper_createpackage( msifile ); ok(package!=0, "Unable to create package\n"); hrec = MsiCreateRecord(3); @@ -2403,7 +2400,7 @@ static void test_processmessage(void) MsiCloseHandle(hrec); MsiCloseHandle(package); - DeleteFile(filename); + DeleteFile(msifile); } START_TEST(format) diff --git a/rostests/winetests/msi/install.c b/rostests/winetests/msi/install.c index 9c5d777d13f..438be6ca884 100644 --- a/rostests/winetests/msi/install.c +++ b/rostests/winetests/msi/install.c @@ -163,6 +163,52 @@ static const CHAR property_dat[] = "Property\tValue\n" "SERVNAME\tTestService\n" "SERVDISP\tTestServiceDisp\n"; +static const CHAR aup_property_dat[] = "Property\tValue\n" + "s72\tl0\n" + "Property\tProperty\n" + "DefaultUIFont\tDlgFont8\n" + "HASUIRUN\t0\n" + "ALLUSERS\t1\n" + "INSTALLLEVEL\t3\n" + "InstallMode\tTypical\n" + "Manufacturer\tWine\n" + "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n" + "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n" + "ProductID\tnone\n" + "ProductLanguage\t1033\n" + "ProductName\tMSITEST\n" + "ProductVersion\t1.1.1\n" + "PROMPTROLLBACKCOST\tP\n" + "Setup\tSetup\n" + "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n" + "AdminProperties\tPOSTADMIN\n" + "ROOTDRIVE\tC:\\\n" + "SERVNAME\tTestService\n" + "SERVDISP\tTestServiceDisp\n"; + +static const CHAR aup2_property_dat[] = "Property\tValue\n" + "s72\tl0\n" + "Property\tProperty\n" + "DefaultUIFont\tDlgFont8\n" + "HASUIRUN\t0\n" + "ALLUSERS\t2\n" + "INSTALLLEVEL\t3\n" + "InstallMode\tTypical\n" + "Manufacturer\tWine\n" + "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n" + "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n" + "ProductID\tnone\n" + "ProductLanguage\t1033\n" + "ProductName\tMSITEST\n" + "ProductVersion\t1.1.1\n" + "PROMPTROLLBACKCOST\tP\n" + "Setup\tSetup\n" + "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n" + "AdminProperties\tPOSTADMIN\n" + "ROOTDRIVE\tC:\\\n" + "SERVNAME\tTestService\n" + "SERVDISP\tTestServiceDisp\n"; + static const CHAR shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n" "s72\ts72\tl128\ts72\ts72\tS255\tL255\tI2\tS72\tI2\tI2\tS72\n" "Shortcut\tShortcut\n" @@ -941,6 +987,48 @@ static const CHAR aup_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" "LaunchConditions\t\t100\n" "TestAllUsersProp\tALLUSERS AND NOT REMOVE\t50\n"; +static const CHAR aup2_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "CostFinalize\t\t1000\n" + "ValidateProductID\t\t700\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "RemoveFiles\t\t3500\n" + "InstallFiles\t\t4000\n" + "RegisterUser\t\t6000\n" + "RegisterProduct\t\t6100\n" + "PublishFeatures\t\t6300\n" + "PublishProduct\t\t6400\n" + "InstallFinalize\t\t6600\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "UnpublishFeatures\t\t1800\n" + "InstallValidate\t\t1400\n" + "LaunchConditions\t\t100\n" + "TestAllUsersProp\tALLUSERS=2 AND NOT REMOVE\t50\n"; + +static const CHAR aup3_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "CostFinalize\t\t1000\n" + "ValidateProductID\t\t700\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "RemoveFiles\t\t3500\n" + "InstallFiles\t\t4000\n" + "RegisterUser\t\t6000\n" + "RegisterProduct\t\t6100\n" + "PublishFeatures\t\t6300\n" + "PublishProduct\t\t6400\n" + "InstallFinalize\t\t6600\n" + "InstallInitialize\t\t1500\n" + "ProcessComponents\t\t1600\n" + "UnpublishFeatures\t\t1800\n" + "InstallValidate\t\t1400\n" + "LaunchConditions\t\t100\n" + "TestAllUsersProp\tALLUSERS=1 AND NOT REMOVE\t50\n"; + static const CHAR aup_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n" "s72\ti2\tS64\tS0\tS255\n" "CustomAction\tAction\n" @@ -1586,6 +1674,45 @@ static const msi_table aup_tables[] = ADD_TABLE(property) }; +static const msi_table aup2_tables[] = +{ + ADD_TABLE(component), + ADD_TABLE(directory), + ADD_TABLE(feature), + ADD_TABLE(feature_comp), + ADD_TABLE(file), + ADD_TABLE(aup2_install_exec_seq), + ADD_TABLE(aup_custom_action), + ADD_TABLE(media), + ADD_TABLE(aup_property) +}; + +static const msi_table aup3_tables[] = +{ + ADD_TABLE(component), + ADD_TABLE(directory), + ADD_TABLE(feature), + ADD_TABLE(feature_comp), + ADD_TABLE(file), + ADD_TABLE(aup2_install_exec_seq), + ADD_TABLE(aup_custom_action), + ADD_TABLE(media), + ADD_TABLE(aup2_property) +}; + +static const msi_table aup4_tables[] = +{ + ADD_TABLE(component), + ADD_TABLE(directory), + ADD_TABLE(feature), + ADD_TABLE(feature_comp), + ADD_TABLE(file), + ADD_TABLE(aup3_install_exec_seq), + ADD_TABLE(aup_custom_action), + ADD_TABLE(media), + ADD_TABLE(aup2_property) +}; + static const msi_table fiu_tables[] = { ADD_TABLE(rof_component), @@ -6778,6 +6905,7 @@ static void test_allusers_prop(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + /* ALLUSERS property unset */ r = MsiInstallProductA(msifile, "FULL=1"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -6798,6 +6926,69 @@ static void test_allusers_prop(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); delete_test_files(); + + create_test_files(); + create_database(msifile, aup2_tables, sizeof(aup2_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + /* ALLUSERS property set to 1 */ + r = MsiInstallProductA(msifile, "FULL=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n"); + ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "File not installed\n"); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + delete_test_files(); + + create_test_files(); + create_database(msifile, aup3_tables, sizeof(aup3_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + /* ALLUSERS property set to 2 */ + r = MsiInstallProductA(msifile, "FULL=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "File not installed\n"); + ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n"); + ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "File not installed\n"); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + delete_test_files(); + + create_test_files(); + create_database(msifile, aup4_tables, sizeof(aup4_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + /* ALLUSERS property set to 2, conditioned on ALLUSERS = 1 */ + r = MsiInstallProductA(msifile, "FULL=1"); + ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); } static char session_manager[] = "System\\CurrentControlSet\\Control\\Session Manager"; diff --git a/rostests/winetests/msi/msi.c b/rostests/winetests/msi/msi.c index 28ffb583dda..d5602039abf 100644 --- a/rostests/winetests/msi/msi.c +++ b/rostests/winetests/msi/msi.c @@ -2517,8 +2517,7 @@ static void test_MsiGetFileVersion(void) r = MsiGetFileVersionA(path, version, &versz, lang, &langsz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz); - ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang); - ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz); + ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang); ok(!lstrcmpA(version, vercheck), "Expected %s, got %s\n", vercheck, version); @@ -2536,8 +2535,7 @@ static void test_MsiGetFileVersion(void) lstrcpyA(lang, "lang"); r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang); - ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz); + ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang); /* check neither version nor language */ r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL); @@ -2553,7 +2551,7 @@ static void test_MsiGetFileVersion(void) langsz = MAX_PATH; r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz); + ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz); /* pcchVersionBuf not big enough */ versz = 5; @@ -2571,7 +2569,7 @@ static void test_MsiGetFileVersion(void) ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); ok(!strncmp(lang, langcheck, 2), "Expected first character of %s, got %s\n", langcheck, lang); - ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz); + ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz); HeapFree(GetProcessHeap(), 0, vercheck); HeapFree(GetProcessHeap(), 0, langcheck); @@ -2781,7 +2779,7 @@ static void test_MsiGetProductInfo(void) ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(sz == 4, "Expected 4, got %d\n", sz); - /* lpValueBuf is NULL, pcchValueBuf is too small */ + /* lpValueBuf is non-NULL, pcchValueBuf is too small */ sz = 2; lstrcpyA(buf, "apple"); r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz); @@ -2789,7 +2787,7 @@ static void test_MsiGetProductInfo(void) ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); ok(sz == 4, "Expected 4, got %d\n", sz); - /* lpValueBuf is NULL, pcchValueBuf is exactly 4 */ + /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */ sz = 4; lstrcpyA(buf, "apple"); r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz); diff --git a/rostests/winetests/msi/package.c b/rostests/winetests/msi/package.c index 95a2587bf3b..3c3e403fa83 100644 --- a/rostests/winetests/msi/package.c +++ b/rostests/winetests/msi/package.c @@ -30,7 +30,7 @@ #include "wine/test.h" -static const char msifile[] = "winetest.msi"; +static const char msifile[] = "winetest-package.msi"; char CURR_DIR[MAX_PATH]; static UINT (WINAPI *pMsiApplyMultiplePatchesA)(LPCSTR, LPCSTR, LPCSTR); @@ -2341,9 +2341,9 @@ static void test_states(void) MSIHANDLE hdb; INSTALLSTATE state, action; - static const CHAR msifile2[] = "winetest2.msi"; - static const CHAR msifile3[] = "winetest3.msi"; - static const CHAR msifile4[] = "winetest4.msi"; + static const CHAR msifile2[] = "winetest2-package.msi"; + static const CHAR msifile3[] = "winetest3-package.msi"; + static const CHAR msifile4[] = "winetest4-package.msi"; hdb = create_package_db(); ok ( hdb, "failed to create package database\n" ); @@ -11601,7 +11601,8 @@ static void test_MsiGetProductProperty(void) ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); lstrcpyA(val, path); - lstrcatA(val, "\\winetest.msi"); + lstrcatA(val, "\\"); + lstrcatA(val, msifile); res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ, (const BYTE *)val, lstrlenA(val) + 1); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); diff --git a/rostests/winetests/msi/record.c b/rostests/winetests/msi/record.c index e8dd6f55596..369c855bb4b 100644 --- a/rostests/winetests/msi/record.c +++ b/rostests/winetests/msi/record.c @@ -24,7 +24,7 @@ #include "wine/test.h" -static const char *msifile = "winetest.msi"; +static const char *msifile = "winetest-record.msi"; static BOOL create_temp_file(char *name) { @@ -604,6 +604,9 @@ static void test_fieldzero(void) r = MsiRecordIsNull(rec, 0); ok(r == FALSE, "Expected FALSE, got %d\n", r); + r = MsiCloseHandle(hview); + ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); + MsiCloseHandle(rec); MsiCloseHandle(hdb); DeleteFileA(msifile); } diff --git a/rostests/winetests/msi/suminfo.c b/rostests/winetests/msi/suminfo.c index f0e7fddc8d2..a0b225b6bd9 100644 --- a/rostests/winetests/msi/suminfo.c +++ b/rostests/winetests/msi/suminfo.c @@ -63,9 +63,12 @@ #define PID_MSISOURCE PID_WORDCOUNT #define PID_MSIRESTRICT PID_CHARCOUNT +const char *msifile = "winetest-suminfo.msi"; +static const WCHAR msifileW[] = { + 'w','i','n','e','t','e','s','t','-','s','u','m','i','n','f','o','.','m','s','i',0 }; + static void test_suminfo(void) { - const char *msifile = "winetest.msi"; MSIHANDLE hdb = 0, hsuminfo; UINT r, count, type; DWORD sz; @@ -284,8 +287,6 @@ static void test_create_database_binary(void) static const CLSID FMTID_SummaryInformation = { 0xf29f85e0, 0x4ff9, 0x1068, {0xab, 0x91, 0x08, 0x00, 0x2b, 0x27, 0xb3, 0xd9}}; DWORD mode = STGM_CREATE | STGM_READWRITE | STGM_DIRECT | STGM_SHARE_EXCLUSIVE; - static const WCHAR msifile[] = { - 'w','i','n','e','t','e','s','t','.','m','s','i',0 }; IPropertySetStorage *pss = NULL; IPropertyStorage *ps = NULL; IStorage *stg = NULL; @@ -295,7 +296,7 @@ static void test_create_database_binary(void) PROPVARIANT propvar[10]; USHORT data[2] = { 0, 0 }; - r = StgCreateDocfile( msifile, mode, 0, &stg ); + r = StgCreateDocfile( msifileW, mode, 0, &stg ); ok( r == S_OK, "failed to create database\n"); r = IStorage_SetClass( stg, &CLSID_MsiDatabase ); @@ -386,7 +387,6 @@ static void test_create_database_binary(void) static void test_summary_binary(void) { - const char *msifile = "winetest.msi"; MSIHANDLE hdb = 0, hsuminfo = 0; UINT r, type, count; INT ival; diff --git a/rostests/winetests/mstask/task.c b/rostests/winetests/mstask/task.c index 328dd76958a..b9dee3536cc 100644 --- a/rostests/winetests/mstask/task.c +++ b/rostests/winetests/mstask/task.c @@ -28,33 +28,6 @@ static ITaskScheduler *test_task_scheduler; static ITask *test_task; static const WCHAR empty[] = {0}; -/* allocate some tmp string space */ -/* FIXME: this is not 100% thread-safe */ -static char *get_tmp_space(int size) -{ - static char *list[16]; - static long pos; - char *ret; - int idx; - - idx = ++pos % (sizeof(list)/sizeof(list[0])); - if ((ret = realloc(list[idx], size))) - list[idx] = ret; - return ret; -} - -static const char *dbgstr_w(LPCWSTR str) -{ - char *buf; - int len; - if(!str) - return "(null)"; - len = lstrlenW(str) + 1; - buf = get_tmp_space(len); - WideCharToMultiByte(CP_ACP, 0, str, -1, buf, len, NULL, NULL); - return buf; -} - static BOOL setup_task(void) { HRESULT hres; @@ -122,7 +95,7 @@ static void test_SetApplicationName_GetApplicationName(void) if (hres == S_OK) { ok(!lstrcmpiW(stored_name, empty), - "Got %s, expected empty string\n", dbgstr_w(stored_name)); + "Got %s, expected empty string\n", wine_dbgstr_w(stored_name)); CoTaskMemFree(stored_name); } @@ -130,14 +103,14 @@ static void test_SetApplicationName_GetApplicationName(void) * the application name that is actually stored */ hres = ITask_SetApplicationName(test_task, non_application_name); ok(hres == S_OK, "Failed setting name %s: %08x\n", - dbgstr_w(non_application_name), hres); + wine_dbgstr_w(non_application_name), hres); hres = ITask_GetApplicationName(test_task, &stored_name); ok(hres == S_OK, "GetApplicationName failed: %08x\n", hres); if (hres == S_OK) { full_name = path_resolve_name(non_application_name); ok(!lstrcmpiW(stored_name, full_name), "Got %s, expected %s\n", - dbgstr_w(stored_name), dbgstr_w(full_name)); + wine_dbgstr_w(stored_name), wine_dbgstr_w(full_name)); CoTaskMemFree(stored_name); } @@ -145,21 +118,21 @@ static void test_SetApplicationName_GetApplicationName(void) * get the stored name */ hres = ITask_SetApplicationName(test_task, notepad_exe); ok(hres == S_OK, "Failed setting name %s: %08x\n", - dbgstr_w(notepad_exe), hres); + wine_dbgstr_w(notepad_exe), hres); hres = ITask_GetApplicationName(test_task, &stored_name); ok(hres == S_OK, "GetApplicationName failed: %08x\n", hres); if (hres == S_OK) { full_name = path_resolve_name(notepad_exe); ok(!lstrcmpiW(stored_name, full_name), "Got %s, expected %s\n", - dbgstr_w(stored_name), dbgstr_w(full_name)); + wine_dbgstr_w(stored_name), wine_dbgstr_w(full_name)); CoTaskMemFree(stored_name); } /* Set a valid application name without program type extension and * then get the stored name */ hres = ITask_SetApplicationName(test_task, notepad); - ok(hres == S_OK, "Failed setting name %s: %08x\n", dbgstr_w(notepad), hres); + ok(hres == S_OK, "Failed setting name %s: %08x\n", wine_dbgstr_w(notepad), hres); hres = ITask_GetApplicationName(test_task, &stored_name); ok(hres == S_OK, "GetApplicationName failed: %08x\n", hres); if (hres == S_OK) @@ -169,7 +142,7 @@ static void test_SetApplicationName_GetApplicationName(void) { full_name = path_resolve_name(notepad); ok(!lstrcmpiW(stored_name, full_name), "Got %s, expected %s\n", - dbgstr_w(stored_name), dbgstr_w(full_name)); + wine_dbgstr_w(stored_name), wine_dbgstr_w(full_name)); } CoTaskMemFree(stored_name); } @@ -179,26 +152,26 @@ static void test_SetApplicationName_GetApplicationName(void) * actually stored */ hres = ITask_SetApplicationName(test_task, non_application_name); ok(hres == S_OK, "Failed setting name %s: %08x\n", - dbgstr_w(non_application_name), hres); + wine_dbgstr_w(non_application_name), hres); hres = ITask_GetApplicationName(test_task, &stored_name); ok(hres == S_OK, "GetApplicationName failed: %08x\n", hres); if (hres == S_OK) { full_name = path_resolve_name(non_application_name); ok(!lstrcmpiW(stored_name, full_name), "Got %s, expected %s\n", - dbgstr_w(stored_name), dbgstr_w(full_name)); + wine_dbgstr_w(stored_name), wine_dbgstr_w(full_name)); CoTaskMemFree(stored_name); } /* Clear application name */ hres = ITask_SetApplicationName(test_task, empty); - ok(hres == S_OK, "Failed setting name %s: %08x\n", dbgstr_w(empty), hres); + ok(hres == S_OK, "Failed setting name %s: %08x\n", wine_dbgstr_w(empty), hres); hres = ITask_GetApplicationName(test_task, &stored_name); ok(hres == S_OK, "GetApplicationName failed: %08x\n", hres); if (hres == S_OK) { ok(!lstrcmpiW(stored_name, empty), - "Got %s, expected empty string\n", dbgstr_w(stored_name)); + "Got %s, expected empty string\n", wine_dbgstr_w(stored_name)); CoTaskMemFree(stored_name); } @@ -257,46 +230,46 @@ static void test_SetParameters_GetParameters(void) if (hres == S_OK) { ok(!lstrcmpW(parameters, empty), - "Got %s, expected empty string\n", dbgstr_w(parameters)); + "Got %s, expected empty string\n", wine_dbgstr_w(parameters)); CoTaskMemFree(parameters); } /* Set parameters to a simple string */ hres = ITask_SetParameters(test_task, parameters_a); ok(hres == S_OK, "Failed setting parameters %s: %08x\n", - dbgstr_w(parameters_a), hres); + wine_dbgstr_w(parameters_a), hres); hres = ITask_GetParameters(test_task, ¶meters); ok(hres == S_OK, "GetParameters failed: %08x\n", hres); if (hres == S_OK) { ok(!lstrcmpW(parameters, parameters_a), "Got %s, expected %s\n", - dbgstr_w(parameters), dbgstr_w(parameters_a)); + wine_dbgstr_w(parameters), wine_dbgstr_w(parameters_a)); CoTaskMemFree(parameters); } /* Update parameters to a different simple string */ hres = ITask_SetParameters(test_task, parameters_b); ok(hres == S_OK, "Failed setting parameters %s: %08x\n", - dbgstr_w(parameters_b), hres); + wine_dbgstr_w(parameters_b), hres); hres = ITask_GetParameters(test_task, ¶meters); ok(hres == S_OK, "GetParameters failed: %08x\n", hres); if (hres == S_OK) { ok(!lstrcmpW(parameters, parameters_b), "Got %s, expected %s\n", - dbgstr_w(parameters), dbgstr_w(parameters_b)); + wine_dbgstr_w(parameters), wine_dbgstr_w(parameters_b)); CoTaskMemFree(parameters); } /* Clear parameters */ hres = ITask_SetParameters(test_task, empty); ok(hres == S_OK, "Failed setting parameters %s: %08x\n", - dbgstr_w(empty), hres); + wine_dbgstr_w(empty), hres); hres = ITask_GetParameters(test_task, ¶meters); ok(hres == S_OK, "GetParameters failed: %08x\n", hres); if (hres == S_OK) { ok(!lstrcmpW(parameters, empty), - "Got %s, expected empty string\n", dbgstr_w(parameters)); + "Got %s, expected empty string\n", wine_dbgstr_w(parameters)); CoTaskMemFree(parameters); } @@ -327,46 +300,46 @@ static void test_SetComment_GetComment(void) if (hres == S_OK) { ok(!lstrcmpW(comment, empty), - "Got %s, expected empty string\n", dbgstr_w(comment)); + "Got %s, expected empty string\n", wine_dbgstr_w(comment)); CoTaskMemFree(comment); } /* Set comment to a simple string */ hres = ITask_SetComment(test_task, comment_a); ok(hres == S_OK, "Failed setting comment %s: %08x\n", - dbgstr_w(comment_a), hres); + wine_dbgstr_w(comment_a), hres); hres = ITask_GetComment(test_task, &comment); ok(hres == S_OK, "GetComment failed: %08x\n", hres); if (hres == S_OK) { ok(!lstrcmpW(comment, comment_a), "Got %s, expected %s\n", - dbgstr_w(comment), dbgstr_w(comment_a)); + wine_dbgstr_w(comment), wine_dbgstr_w(comment_a)); CoTaskMemFree(comment); } /* Update comment to a different simple string */ hres = ITask_SetComment(test_task, comment_b); ok(hres == S_OK, "Failed setting comment %s: %08x\n", - dbgstr_w(comment_b), hres); + wine_dbgstr_w(comment_b), hres); hres = ITask_GetComment(test_task, &comment); ok(hres == S_OK, "GetComment failed: %08x\n", hres); if (hres == S_OK) { ok(!lstrcmpW(comment, comment_b), "Got %s, expected %s\n", - dbgstr_w(comment), dbgstr_w(comment_b)); + wine_dbgstr_w(comment), wine_dbgstr_w(comment_b)); CoTaskMemFree(comment); } /* Clear comment */ hres = ITask_SetComment(test_task, empty); ok(hres == S_OK, "Failed setting comment %s: %08x\n", - dbgstr_w(empty), hres); + wine_dbgstr_w(empty), hres); hres = ITask_GetComment(test_task, &comment); ok(hres == S_OK, "GetComment failed: %08x\n", hres); if (hres == S_OK) { ok(!lstrcmpW(comment, empty), - "Got %s, expected empty string\n", dbgstr_w(comment)); + "Got %s, expected empty string\n", wine_dbgstr_w(comment)); CoTaskMemFree(comment); } @@ -477,8 +450,8 @@ static void test_SetAccountInformation_GetAccountInformation(void) if (hres == S_OK) { ok(!lstrcmpW(account_name, dummy_account_name), - "Got %s, expected %s\n", dbgstr_w(account_name), - dbgstr_w(dummy_account_name)); + "Got %s, expected %s\n", wine_dbgstr_w(account_name), + wine_dbgstr_w(dummy_account_name)); CoTaskMemFree(account_name); } @@ -496,8 +469,8 @@ static void test_SetAccountInformation_GetAccountInformation(void) if (hres == S_OK) { ok(!lstrcmpW(account_name, dummy_account_name_b), - "Got %s, expected %s\n", dbgstr_w(account_name), - dbgstr_w(dummy_account_name_b)); + "Got %s, expected %s\n", wine_dbgstr_w(account_name), + wine_dbgstr_w(dummy_account_name_b)); CoTaskMemFree(account_name); } @@ -512,7 +485,7 @@ static void test_SetAccountInformation_GetAccountInformation(void) if (hres == S_OK) { ok(!lstrcmpW(account_name, empty), - "Got %s, expected empty string\n", dbgstr_w(account_name)); + "Got %s, expected empty string\n", wine_dbgstr_w(account_name)); CoTaskMemFree(account_name); } diff --git a/rostests/winetests/msvcrt/cpp.c b/rostests/winetests/msvcrt/cpp.c index d640d674e3e..106ef73ce27 100644 --- a/rostests/winetests/msvcrt/cpp.c +++ b/rostests/winetests/msvcrt/cpp.c @@ -1032,6 +1032,8 @@ static void test_demangle(void) /* 111 */ {"?f@T@@QAEHQCY1BE@BO@D@Z", "public: int __thiscall T::f(char (volatile * const)[20][30])"}, /* 112 */ {"?f@T@@QAEHQAY2BE@BO@CI@D@Z", "public: int __thiscall T::f(char (* const)[20][30][40])"}, /* 113 */ {"?f@T@@QAEHQAY1BE@BO@$$CBD@Z", "public: int __thiscall T::f(char const (* const)[20][30])"}, +/* 114 */ {"??0?$Foo@U?$vector_c@H$00$01$0?1$0A@$0A@$0HPPPPPPP@$0HPPPPPPP@$0HPPPPPPP@$0HPPPPPPP@$0HPPPPPPP@$0HPPPPPPP@$0HPPPPPPP@$0HPPPPPPP@$0HPPPPPPP@$0HPPPPPPP@$0HPPPPPPP@$0HPPPPPPP@$0HPPPPPPP@$0HPPPPPPP@$0HPPPPPPP@@mpl@boost@@@@QAE@XZ", + "public: __thiscall Foo >::Foo >(void)"}, }; int i, num_test = (sizeof(test)/sizeof(test[0])); diff --git a/rostests/winetests/msvcrt/file.c b/rostests/winetests/msvcrt/file.c index 8afc0e1f593..3159fdc6d40 100644 --- a/rostests/winetests/msvcrt/file.c +++ b/rostests/winetests/msvcrt/file.c @@ -439,6 +439,7 @@ static void test_fgetc( void ) ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret); fclose(tempfh); unlink(tempf); + free(tempf); } static void test_fputc( void ) @@ -463,6 +464,7 @@ static void test_fputc( void ) fclose(tempfh); unlink(tempf); + free(tempf); } static void test_flsbuf( void ) @@ -517,6 +519,7 @@ static void test_flsbuf( void ) fclose(tempfh); unlink(tempf); + free(tempf); } static void test_fgetwc( void ) @@ -634,6 +637,7 @@ static void test_fgetwc( void ) free(mytextW); fclose(tempfh); unlink(tempf); + free(tempf); } static void test_ctrlz( void ) @@ -681,6 +685,7 @@ static void test_ctrlz( void ) ok(feof(tempfh), "did not get EOF\n"); fclose(tempfh); unlink(tempf); + free(tempf); } static void test_file_put_get( void ) @@ -730,6 +735,7 @@ static void test_file_put_get( void ) free(mytextW); fclose(tempfh); unlink(tempf); + free(tempf); } static void test_file_write_read( void ) @@ -806,6 +812,7 @@ static void test_file_write_read( void ) ret = unlink(tempf); ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno); + free(tempf); tempf=_tempnam(".","wne"); tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0); @@ -833,6 +840,7 @@ static void test_file_write_read( void ) "Can't chmod '%s' to read-write: %d\n", tempf, errno); ret = unlink(tempf); ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno); + free(tempf); } static void test_file_inherit_child(const char* fd_s) @@ -1080,6 +1088,7 @@ static void test_chsize( void ) _close( fd ); _unlink( tempfile ); + free( tempfile ); } static void test_fopen_fclose_fcloseall( void ) diff --git a/rostests/winetests/msvcrt/msvcrt.rbuild b/rostests/winetests/msvcrt/msvcrt.rbuild index ca047facb44..1657252b945 100644 --- a/rostests/winetests/msvcrt/msvcrt.rbuild +++ b/rostests/winetests/msvcrt/msvcrt.rbuild @@ -29,6 +29,7 @@ heap.c printf.c scanf.c + signal.c string.c testlist.c time.c diff --git a/rostests/winetests/msvcrt/signal.c b/rostests/winetests/msvcrt/signal.c new file mode 100644 index 00000000000..d33498bd537 --- /dev/null +++ b/rostests/winetests/msvcrt/signal.c @@ -0,0 +1,48 @@ +/* + * Unit test suite for signal function. + * + * Copyright 2009 Peter Rosin + * + * 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 "wine/test.h" +#include +#include + +static int test_value = 0; + +static void __cdecl sighandler(int signum) +{ + ++test_value; +} + +static void test_signal(void) +{ + void (__cdecl *old)(int); + int res; + + old = signal(SIGBREAK, sighandler); + ok(old != SIG_ERR, "Failed to install signal handler for SIGBREAK\n"); + test_value = 0; + res = raise(SIGBREAK); + ok(res == 0, "Failed to raise SIGBREAK\n"); + ok(test_value == 1, "SIGBREAK handler not invoked\n"); +} + +START_TEST(signal) +{ + test_signal(); +} diff --git a/rostests/winetests/msvcrt/string.c b/rostests/winetests/msvcrt/string.c index 7d4eb88effb..585930760a2 100644 --- a/rostests/winetests/msvcrt/string.c +++ b/rostests/winetests/msvcrt/string.c @@ -51,6 +51,7 @@ static int (__cdecl *pstrcpy_s)(char *dst, size_t len, const char *src); static int (__cdecl *pstrcat_s)(char *dst, size_t len, const char *src); static int (__cdecl *p_mbsnbcpy_s)(unsigned char * dst, size_t size, const unsigned char * src, size_t count); static int (__cdecl *p_wcscpy_s)(wchar_t *wcDest, size_t size, const wchar_t *wcSrc); +static int (__cdecl *p_wcsupr_s)(wchar_t *str, size_t size); static int *p__mb_cur_max; static unsigned char *p_mbctype; @@ -597,6 +598,93 @@ static void test_wcscpy_s(void) ok(szDestShort[0] == 0, "szDestShort[0] not 0\n"); } +static void test__wcsupr_s(void) +{ + static const WCHAR mixedString[] = {'M', 'i', 'X', 'e', 'D', 'l', 'o', 'w', + 'e', 'r', 'U', 'P', 'P', 'E', 'R', 0}; + static const WCHAR expectedString[] = {'M', 'I', 'X', 'E', 'D', 'L', 'O', + 'W', 'E', 'R', 'U', 'P', 'P', 'E', + 'R', 0}; + WCHAR testBuffer[2*sizeof(mixedString)/sizeof(WCHAR)]; + int ret; + + if (!p_wcsupr_s) + { + win_skip("_wcsupr_s not found\n"); + return; + } + + /* Test NULL input string and invalid size. */ + errno = EBADF; + ret = p_wcsupr_s(NULL, 0); + ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + + /* Test NULL input string and valid size. */ + errno = EBADF; + ret = p_wcsupr_s(NULL, sizeof(testBuffer)/sizeof(WCHAR)); + ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + + /* Test empty string with zero size. */ + errno = EBADF; + testBuffer[0] = '\0'; + ret = p_wcsupr_s(testBuffer, 0); + ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + ok(testBuffer[0] == '\0', "Expected the buffer to be unchanged\n"); + + /* Test empty string with size of one. */ + testBuffer[0] = '\0'; + ret = p_wcsupr_s(testBuffer, 1); + ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret); + ok(testBuffer[0] == '\0', "Expected the buffer to be unchanged\n"); + + /* Test one-byte buffer with zero size. */ + errno = EBADF; + testBuffer[0] = 'x'; + ret = p_wcsupr_s(testBuffer, 0); + ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n"); + + /* Test one-byte buffer with size of one. */ + errno = EBADF; + testBuffer[0] = 'x'; + ret = p_wcsupr_s(testBuffer, 1); + ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n"); + + /* Test invalid size. */ + wcscpy(testBuffer, mixedString); + errno = EBADF; + ret = p_wcsupr_s(testBuffer, 0); + ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n"); + + /* Test normal string uppercasing. */ + wcscpy(testBuffer, mixedString); + ret = p_wcsupr_s(testBuffer, sizeof(mixedString)/sizeof(WCHAR)); + ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret); + ok(!wcscmp(testBuffer, expectedString), "Expected the string to be fully upper-case\n"); + + /* Test uppercasing with a shorter buffer size count. */ + wcscpy(testBuffer, mixedString); + errno = EBADF; + ret = p_wcsupr_s(testBuffer, sizeof(mixedString)/sizeof(WCHAR) - 1); + ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n"); + + /* Test uppercasing with a longer buffer size count. */ + wcscpy(testBuffer, mixedString); + ret = p_wcsupr_s(testBuffer, sizeof(testBuffer)/sizeof(WCHAR)); + ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret); + ok(!wcscmp(testBuffer, expectedString), "Expected the string to be fully upper-case\n"); +} + static void test_mbcjisjms(void) { /* List of value-pairs to test. The test assumes the last pair to be {0, ..} */ @@ -721,6 +809,7 @@ START_TEST(string) pstrcat_s = (void *)GetProcAddress( hMsvcrt,"strcat_s" ); p_mbsnbcpy_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcpy_s" ); p_wcscpy_s = (void *)GetProcAddress( hMsvcrt,"wcscpy_s" ); + p_wcsupr_s = (void *)GetProcAddress( hMsvcrt,"_wcsupr_s" ); /* MSVCRT memcpy behaves like memmove for overlapping moves, MFC42 CString::Insert seems to rely on that behaviour */ @@ -746,5 +835,6 @@ START_TEST(string) test_mbcjisjms(); test_strtok(); test_wcscpy_s(); + test__wcsupr_s(); test_strtol(); } diff --git a/rostests/winetests/msvcrt/testlist.c b/rostests/winetests/msvcrt/testlist.c index db41945d89d..4bd436d9dea 100644 --- a/rostests/winetests/msvcrt/testlist.c +++ b/rostests/winetests/msvcrt/testlist.c @@ -15,6 +15,7 @@ extern void func_headers(void); extern void func_heap(void); extern void func_printf(void); extern void func_scanf(void); +extern void func_signal(void); extern void func_string(void); extern void func_time(void); @@ -29,6 +30,7 @@ const struct test winetest_testlist[] = { "heap", func_heap }, { "printf", func_printf }, { "scanf", func_scanf }, + { "signal", func_signal }, { "string", func_string }, { "time", func_time }, { 0, 0 } diff --git a/rostests/winetests/msvcrtd/debug.c b/rostests/winetests/msvcrtd/debug.c index fbfcdc5ea4d..71f6e4c3966 100644 --- a/rostests/winetests/msvcrtd/debug.c +++ b/rostests/winetests/msvcrtd/debug.c @@ -30,7 +30,7 @@ /**********************************************************************/ -static void * (*pMSVCRTD_operator_new_dbg)(unsigned long, int, const char *, int) = NULL; +static void * (__cdecl *pMSVCRTD_operator_new_dbg)(size_t, int, const char *, int) = NULL; /* Some exports are only available in later versions */ #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hModule,y) diff --git a/rostests/winetests/msxml3/domdoc.c b/rostests/winetests/msxml3/domdoc.c index de78b6550ce..87ad9b563d6 100644 --- a/rostests/winetests/msxml3/domdoc.c +++ b/rostests/winetests/msxml3/domdoc.c @@ -3085,6 +3085,8 @@ static void test_xmlTypes(void) IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1; VARIANT var; + VariantInit(&var); + hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (LPVOID*)&pElement); ok(hr == E_NOINTERFACE, "ret %08x\n", hr); @@ -3155,7 +3157,8 @@ static void test_xmlTypes(void) /* test get nodeValue */ hr = IXMLDOMCDATASection_get_nodeValue(pCDataSec, &var); ok(hr == S_OK, "ret %08x\n", hr ); - ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n"); + ok(V_VT(&var) == VT_BSTR, "got vt %04x\n", V_VT(&var)); + ok( !lstrcmpW( V_BSTR(&var), _bstr_("This &is a ; test <>\\") ), "incorrect text string\n"); VariantClear(&var); /* test get data */ diff --git a/rostests/winetests/netapi32/apibuf.c b/rostests/winetests/netapi32/apibuf.c index de8613b8fb3..28a1e339ee3 100644 --- a/rostests/winetests/netapi32/apibuf.c +++ b/rostests/winetests/netapi32/apibuf.c @@ -59,6 +59,8 @@ static void run_apibuf_tests(void) /* border reallocate cases */ ok(pNetApiBufferReallocate(0, 1500, &p) == NERR_Success, "Reallocate with OldBuffer = NULL failed\n"); ok(p != NULL, "No memory got allocated\n"); + ok(pNetApiBufferFree(p) == NERR_Success, "NetApiBufferFree failed\n"); + ok(pNetApiBufferAllocate(1024, &p) == NERR_Success, "Memory not reserved\n"); ok(pNetApiBufferReallocate(p, 0, &p) == NERR_Success, "Not freed\n"); ok(p == NULL, "Pointer not cleared\n"); diff --git a/rostests/winetests/ntdll/om.c b/rostests/winetests/ntdll/om.c index 033013b8c78..489d1f23427 100644 --- a/rostests/winetests/ntdll/om.c +++ b/rostests/winetests/ntdll/om.c @@ -63,8 +63,8 @@ static void test_case_sensitive (void) ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status); status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE); - ok(status == STATUS_OBJECT_NAME_COLLISION, - "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status); + ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH, + "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status); pRtlInitUnicodeString(&str, buffer2); InitializeObjectAttributes(&attr, &str, 0, 0, NULL); @@ -82,8 +82,8 @@ static void test_case_sensitive (void) pRtlInitUnicodeString(&str, buffer4); InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL); status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE); - ok(status == STATUS_OBJECT_NAME_COLLISION, - "NtCreateMutant should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status); + ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH, + "NtCreateMutant should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status); status = pNtCreateEvent(&h, GENERIC_ALL, &attr, FALSE, FALSE); ok(status == STATUS_OBJECT_NAME_COLLISION, diff --git a/rostests/winetests/ntdll/rtlbitmap.c b/rostests/winetests/ntdll/rtlbitmap.c index fc7f6c55fc9..d24f0af8be6 100755 --- a/rostests/winetests/ntdll/rtlbitmap.c +++ b/rostests/winetests/ntdll/rtlbitmap.c @@ -413,7 +413,7 @@ static void test_RtlFindClearBitsAndSet(void) static void test_RtlFindMostSignificantBit(void) { int i; - CCHAR cPos; + signed char cPos; ULONGLONG ulLong; if (!pRtlFindMostSignificantBit) @@ -442,7 +442,7 @@ static void test_RtlFindMostSignificantBit(void) static void test_RtlFindLeastSignificantBit(void) { int i; - CCHAR cPos; + signed char cPos; ULONGLONG ulLong; if (!pRtlFindLeastSignificantBit) diff --git a/rostests/winetests/ntdll/rtlstr.c b/rostests/winetests/ntdll/rtlstr.c index df01cf314d0..ba7f663b6c9 100755 --- a/rostests/winetests/ntdll/rtlstr.c +++ b/rostests/winetests/ntdll/rtlstr.c @@ -46,6 +46,7 @@ static NTSTATUS (WINAPI *pRtlDuplicateUnicodeString)(long, UNICODE_STRING *, UNI static BOOLEAN (WINAPI *pRtlEqualUnicodeString)(const UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN); static NTSTATUS (WINAPI *pRtlFindCharInUnicodeString)(int, const UNICODE_STRING *, const UNICODE_STRING *, USHORT *); static VOID (WINAPI *pRtlFreeAnsiString)(PSTRING); +static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); static VOID (WINAPI *pRtlInitAnsiString)(PSTRING, LPCSTR); static VOID (WINAPI *pRtlInitString)(PSTRING, LPCSTR); static VOID (WINAPI *pRtlInitUnicodeString)(PUNICODE_STRING, LPCWSTR); @@ -65,7 +66,6 @@ static NTSTATUS (WINAPI *pRtlStringFromGUID)(const GUID*, UNICODE_STRING*); static BOOLEAN (WINAPI *pRtlIsTextUnicode)(LPVOID, INT, INT *); /*static VOID (WINAPI *pRtlFreeOemString)(PSTRING);*/ -/*static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);*/ /*static VOID (WINAPI *pRtlCopyUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *);*/ /*static VOID (WINAPI *pRtlEraseUnicodeString)(UNICODE_STRING *);*/ /*static LONG (WINAPI *pRtlCompareString)(const STRING *,const STRING *,BOOLEAN);*/ @@ -114,6 +114,7 @@ static void InitFunctionPtrs(void) pRtlEqualUnicodeString = (void *)GetProcAddress(hntdll, "RtlEqualUnicodeString"); pRtlFindCharInUnicodeString = (void *)GetProcAddress(hntdll, "RtlFindCharInUnicodeString"); pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString"); + pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); pRtlInitAnsiString = (void *)GetProcAddress(hntdll, "RtlInitAnsiString"); pRtlInitString = (void *)GetProcAddress(hntdll, "RtlInitString"); pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString"); @@ -467,6 +468,7 @@ static void test_RtlDuplicateUnicodeString(void) ok(memcmp(dest_str.Buffer, res_str.Buffer, dupl_ustr[test_num].res_buf_size) == 0, "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination \"%s\" expected \"%s\"\n", test_num, dupl_ustr[test_num].add_nul, dest_ansi_str.Buffer, dupl_ustr[test_num].res_buf); + if(result == STATUS_SUCCESS) pRtlFreeUnicodeString(&dest_str); } else { ok(dest_str.Buffer == NULL && dupl_ustr[test_num].res_buf == NULL, "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination %p expected %p\n", @@ -794,6 +796,8 @@ static void test_RtlUnicodeStringToAnsiString(void) ok(memcmp(ansi_str.Buffer, ustr2astr[test_num].res_buf, ustr2astr[test_num].res_buf_size) == 0, "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) has ansi \"%s\" expected \"%s\"\n", test_num, ustr2astr[test_num].doalloc, ansi_str.Buffer, ustr2astr[test_num].res_buf); + if(result == STATUS_SUCCESS && ustr2astr[test_num].doalloc) + pRtlFreeAnsiString(&ansi_str); } } @@ -1850,6 +1854,7 @@ static void test_RtlStringFromGUID(void) ret = pRtlStringFromGUID(&IID_Endianess, &str); ok(ret == 0, "expected ret=0, got 0x%0x\n", ret); ok(str.Buffer && !lstrcmpiW(str.Buffer, szGuid), "Endianess broken\n"); + pRtlFreeUnicodeString(&str); } START_TEST(rtlstr) diff --git a/rostests/winetests/rsaenh/rsaenh.c b/rostests/winetests/rsaenh/rsaenh.c index 5a3fafd2fbc..a78eec58f49 100644 --- a/rostests/winetests/rsaenh/rsaenh.c +++ b/rostests/winetests/rsaenh/rsaenh.c @@ -2093,6 +2093,7 @@ static void test_rsa_round_trip(void) ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen); ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n"); } + CryptDestroyKey(keyExchangeKey); CryptReleaseContext(prov, 0); CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, @@ -2334,6 +2335,7 @@ static void test_null_provider(void) ok(result, "CryptAcquireContext failed: %08x\n", GetLastError()); result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key); ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError()); + CryptDestroyKey(key); result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key); ok(!result, "expected CryptGetUserKey to fail\n"); result = CryptGetUserKey(prov, AT_SIGNATURE, &key); @@ -2350,11 +2352,12 @@ static void test_null_provider(void) ok(result, "CryptAcquireContext failed: %08x\n", GetLastError()); result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key); ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError()); + CryptDestroyKey(key); result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key); ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError()); + CryptDestroyKey(key); result = CryptGetUserKey(prov, AT_SIGNATURE, &key); ok(!result, "expected CryptGetUserKey to fail\n"); - CryptDestroyKey(key); CryptReleaseContext(prov, 0); CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, diff --git a/rostests/winetests/setupapi/install.c b/rostests/winetests/setupapi/install.c index 5361238fb3b..668b2c2565b 100644 --- a/rostests/winetests/setupapi/install.c +++ b/rostests/winetests/setupapi/install.c @@ -35,6 +35,7 @@ #include "wine/test.h" static const char inffile[] = "test.inf"; +static const WCHAR inffileW[] = {'t','e','s','t','.','i','n','f',0}; static char CURR_DIR[MAX_PATH]; /* Notes on InstallHinfSectionA/W: @@ -52,6 +53,7 @@ static char CURR_DIR[MAX_PATH]; static void (WINAPI *pInstallHinfSectionA)(HWND, HINSTANCE, LPCSTR, INT); static void (WINAPI *pInstallHinfSectionW)(HWND, HINSTANCE, LPCWSTR, INT); +static BOOL (WINAPI *pSetupGetInfFileListW)(PCWSTR, DWORD, PWSTR, DWORD, PDWORD); /* * Helpers @@ -466,6 +468,177 @@ cleanup: DeleteFile(inffile); } +static void test_inffilelist(void) +{ + static const char inffile2[] = "test2.inf"; + static const WCHAR inffile2W[] = {'t','e','s','t','2','.','i','n','f',0}; + static const char invalid_inf[] = "invalid.inf"; + static const WCHAR invalid_infW[] = {'i','n','v','a','l','i','d','.','i','n','f',0}; + static const char *inf = + "[Version]\n" + "Signature=\"$Chicago$\""; + static const char *inf2 = + "[Version]\n" + "Signature=\"$CHICAGO$\""; + static const char *infNT = + "[Version]\n" + "Signature=\"$WINDOWS NT$\""; + + WCHAR *p, *ptr; + char dirA[MAX_PATH]; + WCHAR dir[MAX_PATH] = { 0 }; + WCHAR buffer[MAX_PATH] = { 0 }; + DWORD expected, outsize; + BOOL ret; + + if(!pSetupGetInfFileListW) + { + win_skip("SetupGetInfFileListW not present\n"); + return; + } + + /* NULL means %windir%\\inf + * get the value as reference + */ + expected = 0; + SetLastError(0xdeadbeef); + ret = pSetupGetInfFileListW(NULL, INF_STYLE_WIN4, NULL, 0, &expected); + if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + { + win_skip("SetupGetInfFileListW not implemented\n"); + return; + } + ok(ret, "expected SetupGetInfFileListW to succeed! Error: %d\n", GetLastError()); + ok(expected > 0, "expected required buffersize to be at least 1\n"); + + /* check if an empty string doesn't behaves like NULL */ + outsize = 0; + SetLastError(0xdeadbeef); + ret = pSetupGetInfFileListW(dir, INF_STYLE_WIN4, NULL, 0, &outsize); + ok(!ret, "expected SetupGetInfFileListW to fail!\n"); + + /* create a private directory, the temp directory may contain some + * inf files left over from old installations + */ + if (!GetTempFileNameA(CURR_DIR, "inftest", 1, dirA)) + { + win_skip("GetTempFileNameA failed with error %d\n", GetLastError()); + return; + } + if (!CreateDirectoryA(dirA, NULL )) + { + win_skip("CreateDirectoryA(%s) failed with error %d\n", dirA, GetLastError()); + return; + } + if (!SetCurrentDirectoryA(dirA)) + { + win_skip("SetCurrentDirectoryA failed with error %d\n", GetLastError()); + RemoveDirectoryA(dirA); + return; + } + + MultiByteToWideChar(CP_ACP, 0, dirA, -1, dir, MAX_PATH); + /* check a not existing directory + */ + ptr = dir + lstrlenW(dir); + MultiByteToWideChar(CP_ACP, 0, "\\not_existent", -1, ptr, MAX_PATH - lstrlenW(dir)); + outsize = 0xffffffff; + SetLastError(0xdeadbeef); + ret = pSetupGetInfFileListW(dir, INF_STYLE_WIN4, NULL, 0, &outsize); + ok(ret, "expected SetupGetInfFileListW to succeed!\n"); + ok(outsize == 1, "expected required buffersize to be 1, got %d\n", outsize); + ok(ERROR_PATH_NOT_FOUND == GetLastError(), + "expected error ERROR_PATH_NOT_FOUND, got %d\n", GetLastError()); + + create_inf_file(inffile, inf); + create_inf_file(inffile2, inf); + create_inf_file(invalid_inf, "This content does not match the inf file format"); + + /* pass a filename instead of a directory + */ + *ptr = '\\'; + MultiByteToWideChar(CP_ACP, 0, invalid_inf, -1, ptr+1, MAX_PATH - lstrlenW(dir)); + outsize = 0xffffffff; + SetLastError(0xdeadbeef); + ret = pSetupGetInfFileListW(dir, INF_STYLE_WIN4, NULL, 0, &outsize); + ok(!ret, "expected SetupGetInfFileListW to fail!\n"); + ok(ERROR_DIRECTORY == GetLastError(), + "expected error ERROR_DIRECTORY, got %d\n", GetLastError()); + + /* make the filename look like directory + */ + dir[1 + lstrlenW(dir)] = 0; + dir[lstrlenW(dir)] = '\\'; + SetLastError(0xdeadbeef); + ret = pSetupGetInfFileListW(dir, INF_STYLE_WIN4, NULL, 0, &outsize); + ok(!ret, "expected SetupGetInfFileListW to fail!\n"); + ok(ERROR_DIRECTORY == GetLastError(), + "expected error ERROR_DIRECTORY, got %d\n", GetLastError()); + + /* now check the buffer content of a vaild call + */ + *ptr = 0; + expected = 3 + strlen(inffile) + strlen(inffile2); + ret = pSetupGetInfFileListW(dir, INF_STYLE_WIN4, buffer, MAX_PATH, &outsize); + ok(ret, "expected SetupGetInfFileListW to succeed!\n"); + ok(expected == outsize, "expected required buffersize to be %d, got %d\n", + expected, outsize); + for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1) + ok(!lstrcmpW(p,inffile2W) || !lstrcmpW(p,inffileW), + "unexpected filename %s\n",wine_dbgstr_w(p)); + + /* upper case value + */ + create_inf_file(inffile2, inf2); + ret = pSetupGetInfFileListW(dir, INF_STYLE_WIN4, buffer, MAX_PATH, &outsize); + ok(ret, "expected SetupGetInfFileListW to succeed!\n"); + ok(expected == outsize, "expected required buffersize to be %d, got %d\n", + expected, outsize); + for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1) + ok(!lstrcmpW(p,inffile2W) || !lstrcmpW(p,inffileW), + "unexpected filename %s\n",wine_dbgstr_w(p)); + + /* signature Windows NT is also inf style win4 + */ + create_inf_file(inffile2, infNT); + expected = 3 + strlen(inffile) + strlen(inffile2); + ret = pSetupGetInfFileListW(dir, INF_STYLE_WIN4, buffer, MAX_PATH, &outsize); + ok(ret, "expected SetupGetInfFileListW to succeed!\n"); + ok(expected == outsize, "expected required buffersize to be %d, got %d\n", + expected, outsize); + for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1) + ok(!lstrcmpW(p,inffile2W) || !lstrcmpW(p,inffileW), + "unexpected filename %s\n",wine_dbgstr_w(p)); + + /* old style + */ + expected = 2 + strlen(invalid_inf); + ret = pSetupGetInfFileListW(dir, INF_STYLE_OLDNT, buffer, MAX_PATH, &outsize); + ok(ret, "expected SetupGetInfFileListW to succeed!\n"); + ok(expected == outsize, "expected required buffersize to be %d, got %d\n", + expected, outsize); + for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1) + ok(!lstrcmpW(p,invalid_infW), "unexpected filename %s\n",wine_dbgstr_w(p)); + + /* mixed style + */ + expected = 4 + strlen(inffile) + strlen(inffile2) + strlen(invalid_inf); + ret = pSetupGetInfFileListW(dir, INF_STYLE_OLDNT | INF_STYLE_WIN4, buffer, + MAX_PATH, &outsize); + ok(ret, "expected SetupGetInfFileListW to succeed!\n"); + ok(expected == outsize, "expected required buffersize to be %d, got %d\n", + expected, outsize); + for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1) + ok(!lstrcmpW(p,inffile2W) || !lstrcmpW(p,inffileW) || !lstrcmpW(p,invalid_infW), + "unexpected filename %s\n",wine_dbgstr_w(p)); + + DeleteFile(inffile); + DeleteFile(inffile2); + DeleteFile(invalid_inf); + SetCurrentDirectoryA(CURR_DIR); + RemoveDirectoryA(dirA); +} + START_TEST(install) { HMODULE hsetupapi = GetModuleHandle("setupapi.dll"); @@ -483,6 +656,8 @@ START_TEST(install) pInstallHinfSectionA = (void *)GetProcAddress(hsetupapi, "InstallHinfSectionA"); pInstallHinfSectionW = (void *)GetProcAddress(hsetupapi, "InstallHinfSectionW"); + pSetupGetInfFileListW = (void *)GetProcAddress(hsetupapi, "SetupGetInfFileListW"); + if (pInstallHinfSectionA) { /* Check if pInstallHinfSectionA sets last error or is a stub (as on WinXP) */ @@ -519,5 +694,7 @@ START_TEST(install) test_profile_items(); } + test_inffilelist(); + SetCurrentDirectory(prev_path); } diff --git a/rostests/winetests/setupapi/misc.c b/rostests/winetests/setupapi/misc.c index e110e221e8b..a3abde46746 100644 --- a/rostests/winetests/setupapi/misc.c +++ b/rostests/winetests/setupapi/misc.c @@ -46,6 +46,7 @@ static CHAR CURR_DIR[MAX_PATH]; static BOOL (WINAPI *pSetupGetFileCompressionInfoExA)(PCSTR, PSTR, DWORD, PDWORD, PDWORD, PDWORD, PUINT); static BOOL (WINAPI *pSetupCopyOEMInfA)(PCSTR, PCSTR, DWORD, DWORD, PSTR, DWORD, PDWORD, PSTR *); static BOOL (WINAPI *pSetupQueryInfOriginalFileInformationA)(PSP_INF_INFORMATION, UINT, PSP_ALTPLATFORM_INFO, PSP_ORIGINAL_FILE_INFO_A); +static BOOL (WINAPI *pSetupUninstallOEMInfA)(PCSTR, DWORD, PVOID); static void create_inf_file(LPCSTR filename) { @@ -196,21 +197,23 @@ static void test_SetupCopyOEMInf(void) /* try a relative SourceInfFileName */ SetLastError(0xdeadbeef); res = pSetupCopyOEMInfA(tmpfile, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); - ok(res == FALSE, "Expected FALSE, got %d\n", res); - if (GetLastError() == ERROR_WRONG_INF_TYPE) + ok(res == FALSE || + broken(res == TRUE), /* Win98 */ + "Expected FALSE, got %d\n", res); + if (GetLastError() == ERROR_WRONG_INF_TYPE || GetLastError() == ERROR_UNSUPPORTED_TYPE /* Win7 */) { /* FIXME: * Vista needs a [Manufacturer] entry in the inf file. Doing this will give some * popups during the installation though as it also needs a catalog file (signed?). */ - win_skip("Needs a different inf file on Vista/W2K8\n"); + win_skip("Needs a different inf file on Vista+\n"); DeleteFile(tmpfile); return; } ok(GetLastError() == ERROR_FILE_NOT_FOUND || - GetLastError() == ERROR_FILE_EXISTS, /* Win98 */ - "Expected ERROR_FILE_NOT_FOUND or ERROR_FILE_EXISTS, got %d\n", GetLastError()); + broken(GetLastError() == ERROR_SUCCESS), /* Win98 */ + "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError()); ok(file_exists(tmpfile), "Expected tmpfile to exist\n"); /* try SP_COPY_REPLACEONLY, dest does not exist */ @@ -306,6 +309,24 @@ static void test_SetupCopyOEMInf(void) ok(res == TRUE, "Expected TRUE, got %d\n", res); ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError()); ok(!file_exists(path), "Expected source inf to not exist\n"); + + if (pSetupUninstallOEMInfA) + { + char *destfile = strrchr(dest, '\\') + 1; + + SetLastError(0xdeadbeef); + ok(pSetupUninstallOEMInfA(destfile, 0, NULL), "Failed to uninstall '%s' : %d\n", destfile, GetLastError()); + } + else + { + /* Win9x/WinMe */ + SetLastError(0xdeadbeef); + ok(DeleteFileA(dest), "Failed to delete file '%s' : %d\n", dest, GetLastError()); + + /* On WinMe we also need to remove the .pnf file */ + *(strrchr(dest, '.') + 1) = 'p'; + DeleteFileA(dest); + } } static void create_source_file(LPSTR filename, const BYTE *data, DWORD size) @@ -581,6 +602,32 @@ static void test_SetupDecompressOrCopyFile(void) DeleteFileA(source); } +static void test_SetupUninstallOEMInf(void) +{ + BOOL ret; + + SetLastError(0xdeadbeef); + ret = pSetupUninstallOEMInfA(NULL, 0, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = pSetupUninstallOEMInfA("", 0, NULL); + todo_wine + { + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); + } + + SetLastError(0xdeadbeef); + ret = pSetupUninstallOEMInfA("nonexistent.inf", 0, NULL); + todo_wine + { + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); + } +} + START_TEST(misc) { HMODULE hsetupapi = GetModuleHandle("setupapi.dll"); @@ -588,6 +635,7 @@ START_TEST(misc) pSetupGetFileCompressionInfoExA = (void*)GetProcAddress(hsetupapi, "SetupGetFileCompressionInfoExA"); pSetupCopyOEMInfA = (void*)GetProcAddress(hsetupapi, "SetupCopyOEMInfA"); pSetupQueryInfOriginalFileInformationA = (void*)GetProcAddress(hsetupapi, "SetupQueryInfOriginalFileInformationA"); + pSetupUninstallOEMInfA = (void*)GetProcAddress(hsetupapi, "SetupUninstallOEMInfA"); GetCurrentDirectoryA(MAX_PATH, CURR_DIR); @@ -604,4 +652,9 @@ START_TEST(misc) win_skip("SetupGetFileCompressionInfoExA is not available\n"); test_SetupDecompressOrCopyFile(); + + if (pSetupUninstallOEMInfA) + test_SetupUninstallOEMInf(); + else + win_skip("SetupUninstallOEMInfA is not available\n"); } diff --git a/rostests/winetests/setupapi/parser.c b/rostests/winetests/setupapi/parser.c index 06bffaf13bb..30ffea10831 100644 --- a/rostests/winetests/setupapi/parser.c +++ b/rostests/winetests/setupapi/parser.c @@ -32,14 +32,18 @@ /* function pointers */ static HMODULE hSetupAPI; -static LPCWSTR (WINAPI *pSetupGetField)(PINFCONTEXT,DWORD); +static LPCSTR (WINAPI *pSetupGetFieldA)(PINFCONTEXT,DWORD); +static LPCWSTR (WINAPI *pSetupGetFieldW)(PINFCONTEXT,DWORD); static BOOL (WINAPI *pSetupEnumInfSectionsA)( HINF hinf, UINT index, PSTR buffer, DWORD size, UINT *need ); static void init_function_pointers(void) { hSetupAPI = GetModuleHandleA("setupapi.dll"); - pSetupGetField = (void *)GetProcAddress(hSetupAPI, "pSetupGetField"); + /* Nice, pSetupGetField is either A or W depending on the Windows version! The actual test + * takes care of this difference */ + pSetupGetFieldA = (void *)GetProcAddress(hSetupAPI, "pSetupGetField"); + pSetupGetFieldW = (void *)GetProcAddress(hSetupAPI, "pSetupGetField"); pSetupEnumInfSectionsA = (void *)GetProcAddress(hSetupAPI, "SetupEnumInfSectionsA" ); } @@ -497,7 +501,14 @@ static const char *contents = "[Version]\n" "[Strings]\n" "RTMQFE_NAME = \"RTMQFE\"\n"; -static const WCHAR getfield_res[][20] = +static const CHAR getfield_resA[][20] = +{ + "RTMQFE", + "%RTMGFE_NAME%", + "SP1RTM", +}; + +static const WCHAR getfield_resW[][20] = { {'R','T','M','Q','F','E',0}, {'%','R','T','M','G','F','E','_','N','A','M','E','%',0}, @@ -509,10 +520,20 @@ static void test_pSetupGetField(void) UINT err; BOOL ret; HINF hinf; - LPCWSTR field; + LPCSTR fieldA; + LPCWSTR fieldW; INFCONTEXT context; int i; int len; + BOOL unicode = TRUE; + + SetLastError(0xdeadbeef); + lstrcmpW(NULL, NULL); + if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + { + win_skip("Using A-functions instead of W\n"); + unicode = FALSE; + } hinf = test_file_contents( contents, &err ); ok( hinf != NULL, "Expected valid INF file\n" ); @@ -524,23 +545,47 @@ static void test_pSetupGetField(void) for ( i = 0; i < 3; i++ ) { - field = pSetupGetField( &context, i ); - ok( field != NULL, "Failed to get field %i\n", i ); - ok( !lstrcmpW( getfield_res[i], field ), "Wrong string returned\n" ); + if (unicode) + { + fieldW = pSetupGetFieldW( &context, i ); + ok( fieldW != NULL, "Failed to get field %i\n", i ); + ok( !lstrcmpW( getfield_resW[i], fieldW ), "Wrong string returned\n" ); + } + else + { + fieldA = pSetupGetFieldA( &context, i ); + ok( fieldA != NULL, "Failed to get field %i\n", i ); + ok( !lstrcmpA( getfield_resA[i], fieldA ), "Wrong string returned\n" ); + } } - field = pSetupGetField( &context, 3 ); - ok( field != NULL, "Failed to get field 3\n" ); - len = lstrlenW( field ); - ok( len == 511 /* NT4, W2K, XP and W2K3 */ || - len == 4096 /* Vista */ || - len == 256 /* Win9x and WinME */, - "Unexpected length, got %d\n", len ); + if (unicode) + { + fieldW = pSetupGetFieldW( &context, 3 ); + ok( fieldW != NULL, "Failed to get field 3\n" ); + len = lstrlenW( fieldW ); + ok( len == 511 || /* NT4, W2K, XP and W2K3 */ + len == 4096, /* Vista */ + "Unexpected length, got %d\n", len ); - field = pSetupGetField( &context, 4 ); - ok( field == NULL, "Expected NULL, got %p\n", field ); - ok( GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError() ); + fieldW = pSetupGetFieldW( &context, 4 ); + ok( fieldW == NULL, "Expected NULL, got %p\n", fieldW ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError() ); + } + else + { + fieldA = pSetupGetFieldA( &context, 3 ); + ok( fieldA != NULL, "Failed to get field 3\n" ); + len = lstrlenA( fieldA ); + ok( len == 511, /* Win9x, WinME */ + "Unexpected length, got %d\n", len ); + + fieldA = pSetupGetFieldA( &context, 4 ); + ok( fieldA == NULL, "Expected NULL, got %p\n", fieldA ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError() ); + } SetupCloseInfFile( hinf ); } @@ -557,14 +602,14 @@ static void test_SetupGetIntField(void) } keys[] = { /* key fields index expected int errorcode */ - { "Key=", "48", 1, 48, ERROR_SUCCESS }, - { "Key=", "48", 0, -1, ERROR_INVALID_DATA }, - { "123=", "48", 0, 123, ERROR_SUCCESS }, - { "Key=", "0x4", 1, 4, ERROR_SUCCESS }, - { "Key=", "Field1", 1, -1, ERROR_INVALID_DATA }, - { "Key=", "Field1,34", 2, 34, ERROR_SUCCESS }, - { "Key=", "Field1,,Field3", 2, 0, ERROR_SUCCESS }, - { "Key=", "Field1,", 2, 0, ERROR_SUCCESS } + { "Key", "48", 1, 48, ERROR_SUCCESS }, + { "Key", "48", 0, -1, ERROR_INVALID_DATA }, + { "123", "48", 0, 123, ERROR_SUCCESS }, + { "Key", "0x4", 1, 4, ERROR_SUCCESS }, + { "Key", "Field1", 1, -1, ERROR_INVALID_DATA }, + { "Key", "Field1,34", 2, 34, ERROR_SUCCESS }, + { "Key", "Field1,,Field3", 2, 0, ERROR_SUCCESS }, + { "Key", "Field1,", 2, 0, ERROR_SUCCESS } }; unsigned int i; @@ -579,11 +624,12 @@ static void test_SetupGetIntField(void) strcpy( buffer, STD_HEADER "[TestSection]\n" ); strcat( buffer, keys[i].key ); + strcat( buffer, "=" ); strcat( buffer, keys[i].fields ); hinf = test_file_contents( buffer, &err); ok( hinf != NULL, "Expected valid INF file\n" ); - SetupFindFirstLineA( hinf, "TestSection", "Key", &context ); + SetupFindFirstLineA( hinf, "TestSection", keys[i].key, &context ); SetLastError( 0xdeadbeef ); intfield = -1; retb = SetupGetIntField( &context, keys[i].index, &intfield ); diff --git a/rostests/winetests/setupapi/query.c b/rostests/winetests/setupapi/query.c index bbc2c659724..c77912d3d91 100644 --- a/rostests/winetests/setupapi/query.c +++ b/rostests/winetests/setupapi/query.c @@ -167,14 +167,15 @@ static void test_SetupGetInfInformation(void) broken(GetLastError() == ERROR_FILE_NOT_FOUND) || /* win98 */ broken(GetLastError() == ERROR_PATH_NOT_FOUND) || /* NT4 */ broken(GetLastError() == ERROR_INVALID_NAME) || /* win2k */ - broken(GetLastError() == ERROR_GENERAL_SYNTAX), /* another win2k */ + broken(GetLastError() == ERROR_GENERAL_SYNTAX), /* another win2k / winMe */ "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); ok(size == 0xdeadbeef, "Expected size to remain unchanged\n"); /* try an invalid inf filename */ - /* do not use NULL as absolute inf filename on win9x (crash) */ + /* do not use NULL as absolute inf filename on win9x/winMe (crash) */ if ((GetLastError() != ERROR_BAD_PATHNAME) && /* win95 */ - (GetLastError() != ERROR_FILE_NOT_FOUND)) /* win98 */ + (GetLastError() != ERROR_FILE_NOT_FOUND) && /* win98 */ + (GetLastError() != ERROR_GENERAL_SYNTAX)) /* winMe */ { size = 0xdeadbeef; SetLastError(0xbeefcafe); diff --git a/rostests/winetests/setupapi/stringtable.c b/rostests/winetests/setupapi/stringtable.c index 59c3f17a327..93701ba5ae9 100644 --- a/rostests/winetests/setupapi/stringtable.c +++ b/rostests/winetests/setupapi/stringtable.c @@ -301,6 +301,7 @@ static void test_StringTableLookUpStringEx(void) ok(!memcmp(buffer, &data, 4), "unexpected data\n"); pStringTableDestroy(table); + pStringTableDestroy(table2); } static void test_StringTableStringFromId(void) diff --git a/rostests/winetests/shell32/progman_dde.c b/rostests/winetests/shell32/progman_dde.c new file mode 100644 index 00000000000..0a7fdaa2102 --- /dev/null +++ b/rostests/winetests/shell32/progman_dde.c @@ -0,0 +1,722 @@ +/* + * Unit test of the Program Manager DDE Interfaces + * + * Copyright 2009 Mikey Alexander + * + * 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 + */ + +/* DDE Program Manager Tests + * - Covers basic CreateGroup, ShowGroup, DeleteGroup, AddItem, and DeleteItem + * functionality + * - Todo: Handle CommonGroupFlag + * Better AddItem Tests (Lots of parameters to test) + * Tests for Invalid Characters in Names / Invalid Parameters + */ + +#include +#include +#include +#include "dde.h" +#include "ddeml.h" +#include "winuser.h" +#include "shlobj.h" + +/* Timeout on DdeClientTransaction Call */ +#define MS_TIMEOUT_VAL 1000 +/* # of times to poll for window creation */ +#define PDDE_POLL_NUM 150 +/* time to sleep between polls */ +#define PDDE_POLL_TIME 300 + +/* Call Info */ +#define DDE_TEST_MISC 0x00010000 +#define DDE_TEST_CREATEGROUP 0x00020000 +#define DDE_TEST_DELETEGROUP 0x00030000 +#define DDE_TEST_SHOWGROUP 0x00040000 +#define DDE_TEST_ADDITEM 0x00050000 +#define DDE_TEST_DELETEITEM 0x00060000 +#define DDE_TEST_COMPOUND 0x00070000 +#define DDE_TEST_CALLMASK 0x00ff0000 + +#define DDE_TEST_NUMMASK 0x0000ffff + +static HRESULT (WINAPI *pSHGetLocalizedName)(LPCWSTR, LPWSTR, UINT, int *); +static BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL); +static BOOL (WINAPI *pReadCabinetState)(CABINETSTATE *, int); + +static void init_function_pointers(void) +{ + HMODULE hmod; + + hmod = GetModuleHandleA("shell32.dll"); + pSHGetLocalizedName = (void*)GetProcAddress(hmod, "SHGetLocalizedName"); + pSHGetSpecialFolderPathA = (void*)GetProcAddress(hmod, "SHGetSpecialFolderPathA"); + pReadCabinetState = (void*)GetProcAddress(hmod, "ReadCabinetState"); + if (!pReadCabinetState) + pReadCabinetState = (void*)GetProcAddress(hmod, (LPSTR)651); +} + +static BOOL use_common(void) +{ + HMODULE hmod; + static BOOL (WINAPI *pIsNTAdmin)(DWORD, LPDWORD); + + /* IsNTAdmin() is available on all platforms. */ + hmod = LoadLibraryA("advpack.dll"); + pIsNTAdmin = (void*)GetProcAddress(hmod, "IsNTAdmin"); + + if (!pIsNTAdmin(0, NULL)) + { + /* We are definitely not an administrator */ + FreeLibrary(hmod); + return FALSE; + } + FreeLibrary(hmod); + + /* If we end up here we are on NT4+ as Win9x and WinMe don't have the + * notion of administrators (as we need it). + */ + + /* As of Vista we should always use the users directory. Tests with the + * real Administrator account on Windows 7 proved this. + * + * FIXME: We need a better way of identifying Vista+ as currently this check + * also covers Wine and we don't know yet which behavior we want to follow. + */ + if (pSHGetLocalizedName) + return FALSE; + + return TRUE; +} + +static char ProgramsDir[MAX_PATH]; + +static char Group1Title[MAX_PATH] = "Group1"; +static char Group2Title[MAX_PATH] = "Group2"; +static char Group3Title[MAX_PATH] = "Group3"; +static char StartupTitle[MAX_PATH] = "Startup"; + +static void init_strings(void) +{ + char startup[MAX_PATH]; + char commonprograms[MAX_PATH]; + char programs[MAX_PATH]; + + CABINETSTATE cs; + + if (pSHGetSpecialFolderPathA) + { + pSHGetSpecialFolderPathA(NULL, programs, CSIDL_PROGRAMS, FALSE); + pSHGetSpecialFolderPathA(NULL, commonprograms, CSIDL_COMMON_PROGRAMS, FALSE); + pSHGetSpecialFolderPathA(NULL, startup, CSIDL_STARTUP, FALSE); + } + else + { + HKEY key; + DWORD size; + LONG res; + + /* Older Win9x and NT4 */ + + RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &key); + size = sizeof(programs); + RegQueryValueExA(key, "Programs", NULL, NULL, (LPBYTE)&programs, &size); + size = sizeof(startup); + RegQueryValueExA(key, "Startup", NULL, NULL, (LPBYTE)&startup, &size); + RegCloseKey(key); + + RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &key); + size = sizeof(commonprograms); + res = RegQueryValueExA(key, "Common Programs", NULL, NULL, (LPBYTE)&commonprograms, &size); + RegCloseKey(key); + } + + /* ProgramsDir on Vista+ is always the users one (CSIDL_PROGRAMS). Before Vista + * it depends on whether the user is an administrator (CSIDL_COMMON_PROGRAMS) or + * not (CSIDL_PROGRAMS). + */ + if (use_common()) + lstrcpyA(ProgramsDir, commonprograms); + else + lstrcpyA(ProgramsDir, programs); + + memset(&cs, 0, sizeof(cs)); + pReadCabinetState(&cs, sizeof(cs)); + if (cs.fFullPathTitle == -1) + { + lstrcpyA(Group1Title, ProgramsDir); + lstrcatA(Group1Title, "\\Group1"); + lstrcpyA(Group2Title, ProgramsDir); + lstrcatA(Group2Title, "\\Group2"); + lstrcpyA(Group3Title, ProgramsDir); + lstrcatA(Group3Title, "\\Group3"); + + lstrcpyA(StartupTitle, startup); + } + else + { + /* Vista has the nice habit of displaying the full path in English + * and the short one localized. CSIDL_STARTUP on Vista gives us the + * English version so we have to 'translate' this one. + * + * MSDN claims it should be used for files not folders but this one + * suits our purposes just fine. + */ + if (pSHGetLocalizedName) + { + WCHAR startupW[MAX_PATH]; + WCHAR module[MAX_PATH]; + WCHAR module_expanded[MAX_PATH]; + WCHAR localized[MAX_PATH]; + int id; + + MultiByteToWideChar(CP_ACP, 0, startup, -1, startupW, sizeof(startupW)/sizeof(WCHAR)); + pSHGetLocalizedName(startupW, module, MAX_PATH, &id); + ExpandEnvironmentStringsW(module, module_expanded, MAX_PATH); + LoadStringW(GetModuleHandleW(module_expanded), id, localized, MAX_PATH); + + WideCharToMultiByte(CP_ACP, 0, localized, -1, StartupTitle, sizeof(StartupTitle), NULL, NULL); + } + else + { + lstrcpyA(StartupTitle, (strrchr(startup, '\\') + 1)); + } + } +} + +static HDDEDATA CALLBACK DdeCallback(UINT type, UINT format, HCONV hConv, HSZ hsz1, HSZ hsz2, + HDDEDATA hDDEData, ULONG_PTR data1, ULONG_PTR data2) +{ + trace("Callback: type=%i, format=%i\n", type, format); + return NULL; +} + +/* + * Encoded String for Error Messages so that inner failures can determine + * what test is failing. Format is: [Code:TestNum] + */ +static const char * GetStringFromTestParams(int testParams) +{ + int testNum; + static char testParamString[64]; + const char *callId; + + testNum = testParams & DDE_TEST_NUMMASK; + switch (testParams & DDE_TEST_CALLMASK) + { + default: + case DDE_TEST_MISC: + callId = "MISC"; + break; + case DDE_TEST_CREATEGROUP: + callId = "C_G"; + break; + case DDE_TEST_DELETEGROUP: + callId = "D_G"; + break; + case DDE_TEST_SHOWGROUP: + callId = "S_G"; + break; + case DDE_TEST_ADDITEM: + callId = "A_I"; + break; + case DDE_TEST_DELETEITEM: + callId = "D_I"; + break; + case DDE_TEST_COMPOUND: + callId = "CPD"; + break; + } + + sprintf(testParamString, " [%s:%i]", callId, testNum); + return testParamString; +} + +/* Transfer DMLERR's into text readable strings for Error Messages */ +#define DMLERR_TO_STR(x) case x: return#x; +static const char * GetStringFromError(UINT err) +{ + switch (err) + { + DMLERR_TO_STR(DMLERR_NO_ERROR); + DMLERR_TO_STR(DMLERR_ADVACKTIMEOUT); + DMLERR_TO_STR(DMLERR_BUSY); + DMLERR_TO_STR(DMLERR_DATAACKTIMEOUT); + DMLERR_TO_STR(DMLERR_DLL_NOT_INITIALIZED); + DMLERR_TO_STR(DMLERR_DLL_USAGE); + DMLERR_TO_STR(DMLERR_EXECACKTIMEOUT); + DMLERR_TO_STR(DMLERR_INVALIDPARAMETER); + DMLERR_TO_STR(DMLERR_LOW_MEMORY); + DMLERR_TO_STR(DMLERR_MEMORY_ERROR); + DMLERR_TO_STR(DMLERR_NOTPROCESSED); + DMLERR_TO_STR(DMLERR_NO_CONV_ESTABLISHED); + DMLERR_TO_STR(DMLERR_POKEACKTIMEOUT); + DMLERR_TO_STR(DMLERR_POSTMSG_FAILED); + DMLERR_TO_STR(DMLERR_REENTRANCY); + DMLERR_TO_STR(DMLERR_SERVER_DIED); + DMLERR_TO_STR(DMLERR_SYS_ERROR); + DMLERR_TO_STR(DMLERR_UNADVACKTIMEOUT); + DMLERR_TO_STR(DMLERR_UNFOUND_QUEUE_ID); + default: + return "Unknown DML Error"; + } +} + +/* Helper Function to Transfer DdeGetLastError into a String */ +static const char * GetDdeLastErrorStr(DWORD instance) +{ + UINT err = DdeGetLastError(instance); + + return GetStringFromError(err); +} + +/* Execute a Dde Command and return the error & result */ +/* Note: Progman DDE always returns a pointer to 0x00000001 on a successful result */ +static void DdeExecuteCommand(DWORD instance, HCONV hConv, const char *strCmd, HDDEDATA *hData, UINT *err, int testParams) +{ + HDDEDATA command; + + command = DdeCreateDataHandle(instance, (LPBYTE) strCmd, strlen(strCmd)+1, 0, 0L, 0, 0); + ok (command != NULL, "DdeCreateDataHandle Error %s.%s\n", + GetDdeLastErrorStr(instance), GetStringFromTestParams(testParams)); + *hData = DdeClientTransaction((void *) command, + -1, + hConv, + 0, + 0, + XTYP_EXECUTE, + MS_TIMEOUT_VAL, + NULL); + + /* hData is technically a pointer, but for Program Manager, + * it is NULL (error) or 1 (success) + * TODO: Check other versions of Windows to verify 1 is returned. + * While it is unlikely that anyone is actually testing that the result is 1 + * if all versions of windows return 1, Wine should also. + */ + if (*hData == NULL) + { + *err = DdeGetLastError(instance); + } + else + { + *err = DMLERR_NO_ERROR; + todo_wine + { + ok(*hData == (HDDEDATA) 1, "Expected HDDEDATA Handle == 1, actually %p.%s\n", + *hData, GetStringFromTestParams(testParams)); + } + } + DdeFreeDataHandle(command); +} + +/* + * Check if Window is onscreen with the appropriate name. + * + * Windows are not created synchronously. So we do not know + * when and if the window will be created/shown on screen. + * This function implements a polling mechanism to determine + * creation. + * A more complicated method would be to use SetWindowsHookEx. + * Since polling worked fine in my testing, no reason to implement + * the other. Comments about other methods of determining when + * window creation happened were not encouraging (not including + * SetWindowsHookEx). + */ +static void CheckWindowCreated(const char *winName, int closeWindow, int testParams) +{ + HWND window = NULL; + int i; + + /* Poll for Window Creation */ + for (i = 0; window == NULL && i < PDDE_POLL_NUM; i++) + { + Sleep(PDDE_POLL_TIME); + window = FindWindowA(NULL, winName); + } + ok (window != NULL, "Window \"%s\" was not created in %i seconds - assumed failure.%s\n", + winName, PDDE_POLL_NUM*PDDE_POLL_TIME/1000, GetStringFromTestParams(testParams)); + + /* Close Window as desired. */ + if (window != NULL && closeWindow) + { + SendMessageA(window, WM_SYSCOMMAND, SC_CLOSE, 0); + } +} + +/* Check for Existence (or non-existence) of a file or group + * When testing for existence of a group, groupName is not needed + */ +static void CheckFileExistsInProgramGroups(const char *nameToCheck, int shouldExist, int isGroup, + const char *groupName, int testParams) +{ + char path[MAX_PATH]; + DWORD attributes; + int len; + + lstrcpyA(path, ProgramsDir); + + len = strlen(path) + strlen(nameToCheck)+1; + if (groupName != NULL) + { + len += strlen(groupName)+1; + } + ok (len <= MAX_PATH, "Path Too Long.%s\n", GetStringFromTestParams(testParams)); + if (len <= MAX_PATH) + { + if (groupName != NULL) + { + strcat(path, "\\"); + strcat(path, groupName); + } + strcat(path, "\\"); + strcat(path, nameToCheck); + attributes = GetFileAttributes(path); + if (!shouldExist) + { + ok (attributes == INVALID_FILE_ATTRIBUTES , "File exists and shouldn't %s.%s\n", + path, GetStringFromTestParams(testParams)); + } else { + if (attributes == INVALID_FILE_ATTRIBUTES) + { + ok (FALSE, "Created File %s doesn't exist.%s\n", path, GetStringFromTestParams(testParams)); + } else if (isGroup) { + ok (attributes & FILE_ATTRIBUTE_DIRECTORY, "%s is not a folder (attr=%x).%s\n", + path, attributes, GetStringFromTestParams(testParams)); + } else { + ok (attributes & FILE_ATTRIBUTE_ARCHIVE, "Created File %s has wrong attributes (%x).%s\n", + path, attributes, GetStringFromTestParams(testParams)); + } + } + } +} + +/* Create Group Test. + * command and expected_result. + * if expected_result is DMLERR_NO_ERROR, test + * 1. group was created + * 2. window is open + */ +static void CreateGroupTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result, + const char *groupName, const char *windowTitle, int testParams) +{ + HDDEDATA hData; + UINT error; + + /* Execute Command & Check Result */ + DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams); + todo_wine + { + ok (expected_result == error, "CreateGroup %s: Expected Error %s, received %s.%s\n", + groupName, GetStringFromError(expected_result), GetStringFromError(error), + GetStringFromTestParams(testParams)); + } + + /* No Error */ + if (error == DMLERR_NO_ERROR) + { + + /* Check if Group Now Exists */ + CheckFileExistsInProgramGroups(groupName, TRUE, TRUE, NULL, testParams); + /* Check if Window is Open (polling) */ + CheckWindowCreated(windowTitle, TRUE, testParams); + } +} + +/* Show Group Test. + * DDE command, expected_result, and the group name to check for existence + * if expected_result is DMLERR_NO_ERROR, test + * 1. window is open + */ +static void ShowGroupTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result, + const char *groupName, const char *windowTitle, int closeAfterShowing, int testParams) +{ + HDDEDATA hData; + UINT error; + + DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams); +/* todo_wine... Is expected to fail, wine stubbed functions DO fail */ +/* TODO REMOVE THIS CODE!!! */ + if (expected_result == DMLERR_NOTPROCESSED) + { + ok (expected_result == error, "ShowGroup %s: Expected Error %s, received %s.%s\n", + groupName, GetStringFromError(expected_result), GetStringFromError(error), + GetStringFromTestParams(testParams)); + } else { + todo_wine + { + ok (expected_result == error, "ShowGroup %s: Expected Error %s, received %s.%s\n", + groupName, GetStringFromError(expected_result), GetStringFromError(error), + GetStringFromTestParams(testParams)); + } + } + + if (error == DMLERR_NO_ERROR) + { + /* Check if Window is Open (polling) */ + CheckWindowCreated(windowTitle, closeAfterShowing, testParams); + } +} + +/* Delete Group Test. + * DDE command, expected_result, and the group name to check for existence + * if expected_result is DMLERR_NO_ERROR, test + * 1. group does not exist + */ +static void DeleteGroupTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result, + const char *groupName, int testParams) +{ + HDDEDATA hData; + UINT error; + + DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams); + todo_wine + { + ok (expected_result == error, "DeleteGroup %s: Expected Error %s, received %s.%s\n", + groupName, GetStringFromError(expected_result), GetStringFromError(error), + GetStringFromTestParams(testParams)); + } + + if (error == DMLERR_NO_ERROR) + { + /* Check that Group does not exist */ + CheckFileExistsInProgramGroups(groupName, FALSE, TRUE, NULL, testParams); + } +} + +/* Add Item Test + * DDE command, expected result, and group and file name where it should exist. + * checks to make sure error code matches expected error code + * checks to make sure item exists if successful + */ +static void AddItemTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result, + const char *fileName, const char *groupName, int testParams) +{ + HDDEDATA hData; + UINT error; + + DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams); + todo_wine + { + ok (expected_result == error, "AddItem %s: Expected Error %s, received %s.%s\n", + fileName, GetStringFromError(expected_result), GetStringFromError(error), + GetStringFromTestParams(testParams)); + } + + if (error == DMLERR_NO_ERROR) + { + /* Check that File exists */ + CheckFileExistsInProgramGroups(fileName, TRUE, FALSE, groupName, testParams); + } +} + +/* Delete Item Test. + * DDE command, expected result, and group and file name where it should exist. + * checks to make sure error code matches expected error code + * checks to make sure item does not exist if successful + */ +static void DeleteItemTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result, + const char *fileName, const char *groupName, int testParams) +{ + HDDEDATA hData; + UINT error; + + DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams); + todo_wine + { + ok (expected_result == error, "DeleteItem %s: Expected Error %s, received %s.%s\n", + fileName, GetStringFromError(expected_result), GetStringFromError(error), + GetStringFromTestParams(testParams)); + } + + if (error == DMLERR_NO_ERROR) + { + /* Check that File does not exist */ + CheckFileExistsInProgramGroups(fileName, FALSE, FALSE, groupName, testParams); + } +} + +/* Compound Command Test. + * not really generic, assumes command of the form: + * [CreateGroup ...][AddItem ...][AddItem ...] + * All samples I've seen using Compound were of this form (CreateGroup, + * AddItems) so this covers minimum expected functionality. + */ +static void CompoundCommandTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result, + const char *groupName, const char *windowTitle, const char *fileName1, + const char *fileName2, int testParams) +{ + HDDEDATA hData; + UINT error; + + DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams); + todo_wine + { + ok (expected_result == error, "Compound String %s: Expected Error %s, received %s.%s\n", + command, GetStringFromError(expected_result), GetStringFromError(error), + GetStringFromTestParams(testParams)); + } + + if (error == DMLERR_NO_ERROR) + { + /* Check that File exists */ + CheckFileExistsInProgramGroups(groupName, TRUE, TRUE, NULL, testParams); + CheckWindowCreated(windowTitle, FALSE, testParams); + CheckFileExistsInProgramGroups(fileName1, TRUE, FALSE, groupName, testParams); + CheckFileExistsInProgramGroups(fileName2, TRUE, FALSE, groupName, testParams); + } +} + +static void CreateAddItemText(char *itemtext, const char *cmdline, const char *name) +{ + lstrcpyA(itemtext, "[AddItem("); + lstrcatA(itemtext, cmdline); + lstrcatA(itemtext, ","); + lstrcatA(itemtext, name); + lstrcatA(itemtext, ")]"); +} + +/* 1st set of tests */ +static int DdeTestProgman(DWORD instance, HCONV hConv) +{ + HDDEDATA hData; + UINT error; + int testnum; + char temppath[MAX_PATH]; + char f1g1[MAX_PATH], f2g1[MAX_PATH], f3g1[MAX_PATH], f1g3[MAX_PATH], f2g3[MAX_PATH]; + char itemtext[MAX_PATH + 20]; + char comptext[2 * (MAX_PATH + 20) + 21]; + + testnum = 1; + /* Invalid Command */ + DdeExecuteCommand(instance, hConv, "[InvalidCommand()]", &hData, &error, DDE_TEST_MISC|testnum++); + ok (error == DMLERR_NOTPROCESSED, "InvalidCommand(), expected error %s, received %s.\n", + GetStringFromError(DMLERR_NOTPROCESSED), GetStringFromError(error)); + + /* On Vista+ the files have to exist when adding a link */ + GetTempPathA(MAX_PATH, temppath); + GetTempFileNameA(temppath, "dde", 0, f1g1); + GetTempFileNameA(temppath, "dde", 0, f2g1); + GetTempFileNameA(temppath, "dde", 0, f3g1); + GetTempFileNameA(temppath, "dde", 0, f1g3); + GetTempFileNameA(temppath, "dde", 0, f2g3); + + /* CreateGroup Tests (including AddItem, DeleteItem) */ + CreateGroupTest(instance, hConv, "[CreateGroup(Group1)]", DMLERR_NO_ERROR, "Group1", Group1Title, DDE_TEST_CREATEGROUP|testnum++); + CreateAddItemText(itemtext, f1g1, "f1g1Name"); + AddItemTest(instance, hConv, itemtext, DMLERR_NO_ERROR, "f1g1Name.lnk", "Group1", DDE_TEST_ADDITEM|testnum++); + CreateAddItemText(itemtext, f2g1, "f2g1Name"); + AddItemTest(instance, hConv, itemtext, DMLERR_NO_ERROR, "f2g1Name.lnk", "Group1", DDE_TEST_ADDITEM|testnum++); + DeleteItemTest(instance, hConv, "[DeleteItem(f2g1Name)]", DMLERR_NO_ERROR, "f2g1Name.lnk", "Group1", DDE_TEST_DELETEITEM|testnum++); + CreateAddItemText(itemtext, f3g1, "f3g1Name"); + AddItemTest(instance, hConv, itemtext, DMLERR_NO_ERROR, "f3g1Name.lnk", "Group1", DDE_TEST_ADDITEM|testnum++); + CreateGroupTest(instance, hConv, "[CreateGroup(Group2)]", DMLERR_NO_ERROR, "Group2", Group2Title, DDE_TEST_CREATEGROUP|testnum++); + /* Create Group that already exists - same instance */ + CreateGroupTest(instance, hConv, "[CreateGroup(Group1)]", DMLERR_NO_ERROR, "Group1", Group1Title, DDE_TEST_CREATEGROUP|testnum++); + + /* ShowGroup Tests */ + ShowGroupTest(instance, hConv, "[ShowGroup(Group1)]", DMLERR_NOTPROCESSED, "Group1", Group1Title, TRUE, DDE_TEST_SHOWGROUP|testnum++); + DeleteItemTest(instance, hConv, "[DeleteItem(f3g1Name)]", DMLERR_NO_ERROR, "f3g1Name.lnk", "Group1", DDE_TEST_DELETEITEM|testnum++); + ShowGroupTest(instance, hConv, "[ShowGroup(Startup,0)]", DMLERR_NO_ERROR, "Startup", StartupTitle, TRUE, DDE_TEST_SHOWGROUP|testnum++); + ShowGroupTest(instance, hConv, "[ShowGroup(Group1,0)]", DMLERR_NO_ERROR, "Group1", Group1Title, FALSE, DDE_TEST_SHOWGROUP|testnum++); + + /* DeleteGroup Test - Note that Window is Open for this test */ + DeleteGroupTest(instance, hConv, "[DeleteGroup(Group1)]", DMLERR_NO_ERROR, "Group1", DDE_TEST_DELETEGROUP|testnum++); + + /* Compound Execute String Command */ + lstrcpyA(comptext, "[CreateGroup(Group3)]"); + CreateAddItemText(itemtext, f1g3, "f1g3Name"); + lstrcatA(comptext, itemtext); + CreateAddItemText(itemtext, f2g3, "f2g3Name"); + lstrcatA(comptext, itemtext); + CompoundCommandTest(instance, hConv, comptext, DMLERR_NO_ERROR, "Group3", Group3Title, "f1g3Name.lnk", "f2g3Name.lnk", DDE_TEST_COMPOUND|testnum++); + + DeleteGroupTest(instance, hConv, "[DeleteGroup(Group3)]", DMLERR_NO_ERROR, "Group3", DDE_TEST_DELETEGROUP|testnum++); + + /* Full Parameters of Add Item */ + /* AddItem(CmdLine[,Name[,IconPath[,IconIndex[,xPos,yPos[,DefDir[,HotKey[,fMinimize[fSeparateSpace]]]]]]]) */ + + DeleteFileA(f1g1); + DeleteFileA(f2g1); + DeleteFileA(f3g1); + DeleteFileA(f1g3); + DeleteFileA(f2g3); + + return testnum; +} + +/* 2nd set of tests - 2nd connection */ +static void DdeTestProgman2(DWORD instance, HCONV hConv, int testnum) +{ + /* Create Group that already exists on a separate connection */ + CreateGroupTest(instance, hConv, "[CreateGroup(Group2)]", DMLERR_NO_ERROR, "Group2", Group2Title, DDE_TEST_CREATEGROUP|testnum++); + DeleteGroupTest(instance, hConv, "[DeleteGroup(Group2)]", DMLERR_NO_ERROR, "Group2", DDE_TEST_DELETEGROUP|testnum++); +} + +START_TEST(progman_dde) +{ + DWORD instance = 0; + UINT err; + HSZ hszProgman; + HCONV hConv; + int testnum; + + init_function_pointers(); + init_strings(); + + /* Initialize DDE Instance */ + err = DdeInitialize(&instance, DdeCallback, APPCMD_CLIENTONLY, 0); + ok (err == DMLERR_NO_ERROR, "DdeInitialize Error %s\n", GetStringFromError(err)); + + /* Create Connection */ + hszProgman = DdeCreateStringHandle(instance, "PROGMAN", CP_WINANSI); + ok (hszProgman != NULL, "DdeCreateStringHandle Error %s\n", GetDdeLastErrorStr(instance)); + hConv = DdeConnect(instance, hszProgman, hszProgman, NULL); + ok (DdeFreeStringHandle(instance, hszProgman), "DdeFreeStringHandle failure\n"); + /* Seeing failures on early versions of Windows Connecting to progman, exit if connection fails */ + if (hConv == NULL) + { + ok (DdeUninitialize(instance), "DdeUninitialize failed\n"); + return; + } + + /* Run Tests */ + testnum = DdeTestProgman(instance, hConv); + + /* Cleanup & Exit */ + ok (DdeDisconnect(hConv), "DdeDisonnect Error %s\n", GetDdeLastErrorStr(instance)); + ok (DdeUninitialize(instance), "DdeUninitialize failed\n"); + + /* 2nd Instance (Followup Tests) */ + /* Initialize DDE Instance */ + instance = 0; + err = DdeInitialize(&instance, DdeCallback, APPCMD_CLIENTONLY, 0); + ok (err == DMLERR_NO_ERROR, "DdeInitialize Error %s\n", GetStringFromError(err)); + + /* Create Connection */ + hszProgman = DdeCreateStringHandle(instance, "PROGMAN", CP_WINANSI); + ok (hszProgman != NULL, "DdeCreateStringHandle Error %s\n", GetDdeLastErrorStr(instance)); + hConv = DdeConnect(instance, hszProgman, hszProgman, NULL); + ok (hConv != NULL, "DdeConnect Error %s\n", GetDdeLastErrorStr(instance)); + ok (DdeFreeStringHandle(instance, hszProgman), "DdeFreeStringHandle failure\n"); + + /* Run Tests */ + DdeTestProgman2(instance, hConv, testnum); + + /* Cleanup & Exit */ + ok (DdeDisconnect(hConv), "DdeDisonnect Error %s\n", GetDdeLastErrorStr(instance)); + ok (DdeUninitialize(instance), "DdeUninitialize failed\n"); +} diff --git a/rostests/winetests/shell32/shell32.rbuild b/rostests/winetests/shell32/shell32.rbuild index 5d7c99a5aa1..81f764b220e 100644 --- a/rostests/winetests/shell32/shell32.rbuild +++ b/rostests/winetests/shell32/shell32.rbuild @@ -18,6 +18,7 @@ appbar.c autocomplete.c generated.c + progman_dde.c shelllink.c shellpath.c shlexec.c diff --git a/rostests/winetests/shell32/shelllink.c b/rostests/winetests/shell32/shelllink.c index 2f20200c67a..25354718601 100755 --- a/rostests/winetests/shell32/shelllink.c +++ b/rostests/winetests/shell32/shelllink.c @@ -275,6 +275,20 @@ static void test_get_set(void) ok(SUCCEEDED(r), "GetArguments failed (0x%08x)\n", r); ok(lstrcmp(buffer,str)==0, "GetArguments returned '%s'\n", buffer); + strcpy(buffer,"garbage"); + r = IShellLinkA_SetArguments(sl, NULL); + ok(SUCCEEDED(r), "SetArguments failed (0x%08x)\n", r); + r = IShellLinkA_GetArguments(sl, buffer, sizeof(buffer)); + ok(SUCCEEDED(r), "GetArguments failed (0x%08x)\n", r); + ok(!buffer[0] || lstrcmp(buffer,str)==0, "GetArguments returned '%s'\n", buffer); + + strcpy(buffer,"garbage"); + r = IShellLinkA_SetArguments(sl, ""); + ok(SUCCEEDED(r), "SetArguments failed (0x%08x)\n", r); + r = IShellLinkA_GetArguments(sl, buffer, sizeof(buffer)); + ok(SUCCEEDED(r), "GetArguments failed (0x%08x)\n", r); + ok(!buffer[0], "GetArguments returned '%s'\n", buffer); + /* Test Getting / Setting showcmd */ i=0xdeadbeef; r = IShellLinkA_GetShowCmd(sl, &i); diff --git a/rostests/winetests/shell32/shlexec.c b/rostests/winetests/shell32/shlexec.c index fa5a2162027..fd712528bd8 100755 --- a/rostests/winetests/shell32/shlexec.c +++ b/rostests/winetests/shell32/shlexec.c @@ -1095,7 +1095,7 @@ static void test_find_executable(void) * like '.mpeg', etc. * Also it means we cannot do any other test. */ - trace("FindExecutable() is broken -> skipping 4+ character extension tests\n"); + win_skip("FindExecutable() is broken -> not running 4+ character extension tests\n"); return; } diff --git a/rostests/winetests/shell32/shlfileop.c b/rostests/winetests/shell32/shlfileop.c index c24a6f2bf0d..a035567b645 100644 --- a/rostests/winetests/shell32/shlfileop.c +++ b/rostests/winetests/shell32/shlfileop.c @@ -965,9 +965,10 @@ static void test_copy(void) set_curr_dir_path(from, "test1.txt\0test2.txt\0"); set_curr_dir_path(to, "test3.txt\0"); retval = SHFileOperation(&shfo); - if (retval == DE_FLDDESTISFILE) + if (retval == DE_FLDDESTISFILE || /* Vista and W2K8 */ + retval == DE_INVALIDFILES) /* Win7 */ { - /* Vista and W2K8 (broken or new behavior ?) */ + /* Most likely new behavior */ ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n"); } else diff --git a/rostests/winetests/shell32/shlfolder.c b/rostests/winetests/shell32/shlfolder.c index 903c0894f9b..435942ba2bb 100644 --- a/rostests/winetests/shell32/shlfolder.c +++ b/rostests/winetests/shell32/shlfolder.c @@ -472,7 +472,8 @@ static void test_GetDisplayName(void) /* WinXP and up store the filenames as both ANSI and UNICODE in the pidls */ if (pidlLast->mkid.cb >= 76) { ok(!lstrcmpW((WCHAR*)&pidlLast->mkid.abID[46], wszFileName) || - (pidlLast->mkid.cb >= 94 && !lstrcmpW((WCHAR*)&pidlLast->mkid.abID[64], wszFileName)), /* Vista */ + (pidlLast->mkid.cb >= 94 && !lstrcmpW((WCHAR*)&pidlLast->mkid.abID[64], wszFileName)) || /* Vista */ + (pidlLast->mkid.cb >= 98 && !lstrcmpW((WCHAR*)&pidlLast->mkid.abID[68], wszFileName)), /* Win7 */ "Filename should be stored as wchar-string at this position!\n"); } @@ -585,6 +586,7 @@ static void test_GetDisplayName(void) ok (!lstrcmpiW(wszTestFile, wszTestFile2), "GetDisplayNameOf returns incorrect path!\n"); } + ILFree(pidlTestFile); IShellFolder_Release(psfDesktop); IShellFolder_Release(psfPersonal); } @@ -646,8 +648,12 @@ static void test_CallForAttributes(void) * key. So the test will return at this point, if run on wine. */ lResult = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszMyDocumentsKey, 0, KEY_WRITE|KEY_READ, &hKey); - ok (lResult == ERROR_SUCCESS, "RegOpenKeyEx failed! result: %08x\n", lResult); + ok (lResult == ERROR_SUCCESS || + lResult == ERROR_ACCESS_DENIED, + "RegOpenKeyEx failed! result: %08x\n", lResult); if (lResult != ERROR_SUCCESS) { + if (lResult == ERROR_ACCESS_DENIED) + skip("Not enough rights to open the registry key\n"); IMalloc_Free(ppM, pidlMyDocuments); IShellFolder_Release(psfDesktop); return; @@ -1524,18 +1530,38 @@ static void test_ITEMIDLIST_format(void) { pFileStructA->uFileTime == pFileStructW->uTime, "Last write time should match creation time!\n"); - ok (pFileStructA->uFileDate == pFileStructW->uDate2 && - pFileStructA->uFileTime == pFileStructW->uTime2, - "Last write time should match last access time!\n"); + /* On FAT filesystems the last access time is midnight + local time, so the values of uDate2 and uTime2 will + depend on the local timezone. If the times are exactly + equal then the dates should be identical for both FAT + and NTFS as no timezone is more than 1 day away from UTC. + */ + if (pFileStructA->uFileTime == pFileStructW->uTime2) + { + ok (pFileStructA->uFileDate == pFileStructW->uDate2, + "Last write date and time should match last access date and time!\n"); + } + else + { + /* Filesystem may be FAT. Check date within 1 day + and seconds are zero. */ + trace ("Filesystem may be FAT. Performing less strict atime test.\n"); + ok ((pFileStructW->uTime2 & 0x1F) == 0, + "Last access time on FAT filesystems should have zero seconds.\n"); + /* TODO: Perform check for date being within one day.*/ + } ok (!lstrcmpW(wszFile[i], pFileStructW->wszName) || - !lstrcmpW(wszFile[i], (WCHAR *)(pFileStructW->abFooBar2 + 22)), /* Vista */ + !lstrcmpW(wszFile[i], (WCHAR *)(pFileStructW->abFooBar2 + 22)) || /* Vista */ + !lstrcmpW(wszFile[i], (WCHAR *)(pFileStructW->abFooBar2 + 26)), /* Win7 */ "The filename should be stored in unicode at this position!\n"); } } pILFree(pidlFile); } + + IShellFolder_Release(psfPersonal); } static void testSHGetFolderPathAndSubDirA(void) diff --git a/rostests/winetests/shell32/testlist.c b/rostests/winetests/shell32/testlist.c index 0c78417d4f6..72d9cef3e2f 100644 --- a/rostests/winetests/shell32/testlist.c +++ b/rostests/winetests/shell32/testlist.c @@ -9,6 +9,7 @@ extern void func_appbar(void); extern void func_autocomplete(void); extern void func_generated(void); +extern void func_progman_dde(void); extern void func_shelllink(void); extern void func_shellpath(void); extern void func_shfldr_netplaces(void); @@ -24,6 +25,7 @@ const struct test winetest_testlist[] = { "appbar", func_appbar }, { "autocomplete", func_autocomplete }, { "generated", func_generated }, + { "progman_dde", func_progman_dde }, { "shelllink", func_shelllink }, { "shellpath", func_shellpath }, { "shfldr_netplaces", func_shfldr_netplaces }, diff --git a/rostests/winetests/usp10/usp10.c b/rostests/winetests/usp10/usp10.c index 1eefee0509a..5795e909cd6 100644 --- a/rostests/winetests/usp10/usp10.c +++ b/rostests/winetests/usp10/usp10.c @@ -27,11 +27,7 @@ #include #include -#include -#include -#include -#include -#include +#include #include static void test_ScriptShape(HDC hdc) @@ -67,9 +63,10 @@ static void test_ScriptShape(HDC hdc) ok(hr == E_PENDING, "ScriptShape should return E_PENDING not %08x\n", hr); hr = ScriptShape(hdc, &sc, test1, 4, 4, &items[0].a, glyphs, NULL, attrs, &nb); - ok(!hr || - hr == E_INVALIDARG, /* Vista, W2K8 */ - "ScriptShape should return S_OK or E_INVALIDARG, not %08x\n", hr); + ok(broken(hr == S_OK) || + hr == E_INVALIDARG || /* Vista, W2K8 */ + hr == E_FAIL, /* WIN7 */ + "ScriptShape should return E_FAIL or E_INVALIDARG, not %08x\n", hr); ok(items[0].a.fNoGlyphIndex == FALSE, "fNoGlyphIndex TRUE\n"); hr = ScriptShape(hdc, &sc, test1, 4, 4, &items[0].a, glyphs, logclust, attrs, &nb); @@ -83,17 +80,19 @@ static void test_ScriptShape(HDC hdc) ok(hr == E_INVALIDARG, "ScriptPlace should return E_INVALIDARG not %08x\n", hr); hr = ScriptPlace(NULL, &sc, glyphs, 4, attrs, &items[0].a, widths, NULL, NULL); - ok(hr == E_PENDING || - hr == E_INVALIDARG, /* Vista, W2K8 */ - "ScriptPlace should return E_PENDING or E_INVALIDARG, not %08x\n", hr); + ok(broken(hr == E_PENDING) || + hr == E_INVALIDARG || /* Vista, W2K8 */ + hr == E_FAIL, /* WIN7 */ + "ScriptPlace should return E_FAIL or E_INVALIDARG, not %08x\n", hr); hr = ScriptPlace(NULL, &sc, glyphs, 4, attrs, &items[0].a, widths, offset, NULL); ok(hr == E_PENDING, "ScriptPlace should return E_PENDING not %08x\n", hr); hr = ScriptPlace(NULL, &sc, glyphs, 4, attrs, &items[0].a, widths, NULL, abc); - ok(hr == E_PENDING || - hr == E_INVALIDARG, /* Vista, W2K8 */ - "ScriptPlace should return E_PENDING or E_INVALIDARG, not %08x\n", hr); + ok(broken(hr == E_PENDING) || + hr == E_INVALIDARG || /* Vista, W2K8 */ + hr == E_FAIL, /* WIN7 */ + "ScriptPlace should return E_FAIL or E_INVALIDARG, not %08x\n", hr); hr = ScriptPlace(hdc, &sc, glyphs, 4, attrs, &items[0].a, widths, offset, NULL); ok(!hr, "ScriptPlace should return S_OK not %08x\n", hr); @@ -339,14 +338,14 @@ static void test_ScriptGetCMap(HDC hdc, unsigned short pwOutGlyphs[256]) /* Set psc to NULL, to be able to check if a pointer is returned in psc */ psc = NULL; - hr = ScriptGetCMap(NULL, &psc, NULL, 0, 0, NULL); - ok( hr == E_PENDING, "(NULL,&psc,NULL,0,0NULL), expected E_PENDING, " + hr = ScriptGetCMap(NULL, &psc, TestItem1, cInChars, 0, pwOutGlyphs3); + ok( hr == E_PENDING, "(NULL,&psc,NULL,0,0,NULL), expected E_PENDING, " "got %08x\n", hr); ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc); /* Set psc to NULL but add hdc, to be able to check if a pointer is returned in psc */ psc = NULL; - hr = ScriptGetCMap(hdc, &psc, NULL, 0, 0, NULL); + hr = ScriptGetCMap(hdc, &psc, TestItem1, cInChars, 0, pwOutGlyphs3); ok( hr == S_OK, "ScriptGetCMap(NULL,&psc,NULL,0,0,NULL), expected S_OK, " "got %08x\n", hr); ok( psc != NULL, "ScritpGetCMap expected psc to be not NULL\n"); @@ -1058,6 +1057,11 @@ static void test_ScriptGetGlyphABCWidth(HDC hdc) ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr); hr = ScriptGetGlyphABCWidth(NULL, &sc, 'a', NULL); + ok(broken(hr == E_PENDING) || + hr == E_INVALIDARG, /* WIN7 */ + "expected E_INVALIDARG, got 0x%08x\n", hr); + + hr = ScriptGetGlyphABCWidth(NULL, &sc, 'a', &abc); ok(hr == E_PENDING, "expected E_PENDING, got 0x%08x\n", hr); if (0) { /* crashes on WinXP */ @@ -1169,7 +1173,7 @@ static void test_digit_substitution(void) LGRPID_ARMENIAN }; HMODULE hKernel32; - static BOOL (WINAPI * pEnumLanguageGroupLocalesA)(LANGGROUPLOCALE_ENUMPROC,LGRPID,DWORD,LONG_PTR); + static BOOL (WINAPI * pEnumLanguageGroupLocalesA)(LANGGROUPLOCALE_ENUMPROCA,LGRPID,DWORD,LONG_PTR); hKernel32 = GetModuleHandleA("kernel32.dll"); pEnumLanguageGroupLocalesA = (void*)GetProcAddress(hKernel32, "EnumLanguageGroupLocalesA"); diff --git a/rostests/winetests/winmm/mci.c b/rostests/winetests/winmm/mci.c index 5f8698507a8..6607e17c99f 100644 --- a/rostests/winetests/winmm/mci.c +++ b/rostests/winetests/winmm/mci.c @@ -2,6 +2,7 @@ * Test winmm mci * * Copyright 2006 Jan Zerebecki + * 2009 Jörg Höhle * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,53 +19,843 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "wine/test.h" -#include "winuser.h" +#include +#include "windows.h" #include "mmsystem.h" +#include "mmreg.h" +#include "wine/test.h" -START_TEST(mci) +/* The tests use the MCI's own save capability to create the tempfile.wav to play. + * To use a pre-existing file, write-protect it. */ +static MCIERROR ok_saved = MCIERR_FILE_NOT_FOUND; + +typedef union { + MCI_STATUS_PARMS status; + MCI_WAVE_SET_PARMS set; + MCI_WAVE_OPEN_PARMS open; + MCI_SEEK_PARMS seek; + } MCI_PARMS_UNION; + +static const char* dbg_mcierr(MCIERROR err) { - int err; - const char command_open[] = "open new type waveaudio alias mysound"; + switch (err) { + case 0: return "0=NOERROR"; +#define X(label) case label: return #label ; + X(MCIERR_INVALID_DEVICE_ID) + X(MCIERR_UNRECOGNIZED_KEYWORD) + X(MCIERR_UNRECOGNIZED_COMMAND) + X(MCIERR_HARDWARE) + X(MCIERR_INVALID_DEVICE_NAME) + X(MCIERR_OUT_OF_MEMORY) + X(MCIERR_DEVICE_OPEN) + X(MCIERR_CANNOT_LOAD_DRIVER) + X(MCIERR_MISSING_COMMAND_STRING) + X(MCIERR_PARAM_OVERFLOW) + X(MCIERR_MISSING_STRING_ARGUMENT) + X(MCIERR_BAD_INTEGER) + X(MCIERR_PARSER_INTERNAL) + X(MCIERR_DRIVER_INTERNAL) + X(MCIERR_MISSING_PARAMETER) + X(MCIERR_UNSUPPORTED_FUNCTION) + X(MCIERR_FILE_NOT_FOUND) + X(MCIERR_DEVICE_NOT_READY) + X(MCIERR_INTERNAL) + X(MCIERR_DRIVER) + X(MCIERR_CANNOT_USE_ALL) + X(MCIERR_MULTIPLE) + X(MCIERR_EXTENSION_NOT_FOUND) + X(MCIERR_OUTOFRANGE) + X(MCIERR_FLAGS_NOT_COMPATIBLE) + X(MCIERR_FILE_NOT_SAVED) + X(MCIERR_DEVICE_TYPE_REQUIRED) + X(MCIERR_DEVICE_LOCKED) + X(MCIERR_DUPLICATE_ALIAS) + X(MCIERR_BAD_CONSTANT) + X(MCIERR_MUST_USE_SHAREABLE) + X(MCIERR_MISSING_DEVICE_NAME) + X(MCIERR_BAD_TIME_FORMAT) + X(MCIERR_NO_CLOSING_QUOTE) + X(MCIERR_DUPLICATE_FLAGS) + X(MCIERR_INVALID_FILE) + X(MCIERR_NULL_PARAMETER_BLOCK) + X(MCIERR_UNNAMED_RESOURCE) + X(MCIERR_NEW_REQUIRES_ALIAS) + X(MCIERR_NOTIFY_ON_AUTO_OPEN) + X(MCIERR_NO_ELEMENT_ALLOWED) + X(MCIERR_NONAPPLICABLE_FUNCTION) + X(MCIERR_ILLEGAL_FOR_AUTO_OPEN) + X(MCIERR_FILENAME_REQUIRED) + X(MCIERR_EXTRA_CHARACTERS) + X(MCIERR_DEVICE_NOT_INSTALLED) + X(MCIERR_GET_CD) + X(MCIERR_SET_CD) + X(MCIERR_SET_DRIVE) + X(MCIERR_DEVICE_LENGTH) + X(MCIERR_DEVICE_ORD_LENGTH) + X(MCIERR_NO_INTEGER) + X(MCIERR_WAVE_OUTPUTSINUSE) + X(MCIERR_WAVE_SETOUTPUTINUSE) + X(MCIERR_WAVE_INPUTSINUSE) + X(MCIERR_WAVE_SETINPUTINUSE) + X(MCIERR_WAVE_OUTPUTUNSPECIFIED) + X(MCIERR_WAVE_INPUTUNSPECIFIED) + X(MCIERR_WAVE_OUTPUTSUNSUITABLE) + X(MCIERR_WAVE_SETOUTPUTUNSUITABLE) + X(MCIERR_WAVE_INPUTSUNSUITABLE) + X(MCIERR_WAVE_SETINPUTUNSUITABLE) + X(MCIERR_SEQ_DIV_INCOMPATIBLE) + X(MCIERR_SEQ_PORT_INUSE) + X(MCIERR_SEQ_PORT_NONEXISTENT) + X(MCIERR_SEQ_PORT_MAPNODEVICE) + X(MCIERR_SEQ_PORT_MISCERROR) + X(MCIERR_SEQ_TIMER) + X(MCIERR_SEQ_PORTUNSPECIFIED) + X(MCIERR_SEQ_NOMIDIPRESENT) + X(MCIERR_NO_WINDOW) + X(MCIERR_CREATEWINDOW) + X(MCIERR_FILE_READ) + X(MCIERR_FILE_WRITE) + X(MCIERR_NO_IDENTITY) +#undef X + default: { + static char name[20]; /* Not to be called twice in a parameter list! */ + sprintf(name, "MMSYSERR %u", err); + return name; + } + } +} + +static BOOL spurious_message(LPMSG msg) +{ + /* WM_DEVICECHANGE 0x0219 appears randomly */ + if(msg->message != MM_MCINOTIFY) { + trace("skipping spurious message %04x\n",msg->message); + return TRUE; + } + return FALSE; +} + +static void test_notification(HWND hwnd, const char* command, WPARAM type) +{ /* Use type 0 as meaning no message */ + MSG msg; + BOOL seen; + do { seen = PeekMessageA(&msg, hwnd, 0, 0, PM_REMOVE); } + while(seen && spurious_message(&msg)); + if(type==0) + ok(!seen, "Expect no message from command %s\n", command); + else + ok(seen, "PeekMessage should succeed for command %s\n", command); + if(seen) { + ok(msg.hwnd == hwnd, "Didn't get the handle to our test window\n"); + ok(msg.message == MM_MCINOTIFY, "got %04x instead of MM_MCINOTIFY from command %s\n", msg.message, command); + ok(msg.wParam == type, "got %04lx instead of MCI_NOTIFY_xyz %04lx from command %s\n", msg.wParam, type, command); + } +} +static void test_notification1(HWND hwnd, const char* command, WPARAM type) +{ /* This version works with todo_wine prefix. */ + MSG msg; + BOOL seen; + do { seen = PeekMessageA(&msg, hwnd, 0, 0, PM_REMOVE); } + while(seen && spurious_message(&msg)); + if(type==0) + ok(!seen, "Expect no message from command %s\n", command); + else if(seen) + ok(msg.message == MM_MCINOTIFY && msg.wParam == type,"got %04lx instead of MCI_NOTIFY_xyz %04lx from command %s\n", msg.wParam, type, command); + else ok(seen, "PeekMessage should succeed for command %s\n", command); +} + +static void test_openCloseWAVE(HWND hwnd) +{ + MCIERROR err; + MCI_GENERIC_PARMS parm; + const char command_open[] = "open new type waveaudio alias mysound notify"; const char command_close_my[] = "close mysound notify"; const char command_close_all[] = "close all notify"; const char command_sysinfo[] = "sysinfo waveaudio quantity open"; - MSG msg; char buf[1024]; - HWND hwnd; + memset(buf, 0, sizeof(buf)); + test_notification(hwnd, "-prior to any command-", 0); - hwnd = CreateWindowExA(0, "static", "winmm test", WS_POPUP, 0,0,100,100, - 0, 0, 0, NULL); + err = mciSendString("sysinfo all quantity", buf, sizeof(buf), hwnd); + todo_wine ok(!err,"mci %s returned %s\n", command_open, dbg_mcierr(err)); + if(!err) trace("[MCI] with %s drivers\n", buf); - err = mciSendString(command_open, NULL, 0, NULL); - ok(!err,"mciSendString(%s, NULL, 0 , NULL) returned error: %d\n", command_open, err); + err = mciSendString("open new type waveaudio alias r shareable", buf, sizeof(buf), NULL); + ok(err==MCIERR_UNSUPPORTED_FUNCTION,"mci open new shareable returned %s\n", dbg_mcierr(err)); + if(!err) { + err = mciSendString("close r", NULL, 0, NULL); + ok(!err,"mci close shareable returned %s\n", dbg_mcierr(err)); + } + + err = mciSendString(command_open, buf, sizeof(buf), hwnd); + ok(!err,"mci %s returned %s\n", command_open, dbg_mcierr(err)); + ok(!strcmp(buf,"1"), "mci open deviceId: %s, expected 1\n", buf); + /* Wine<=1.1.33 used to ignore anything past alias XY */ + test_notification(hwnd,"open new alias notify",MCI_NOTIFY_SUCCESSFUL); + + err = mciSendString("status mysound time format", buf, sizeof(buf), hwnd); + ok(!err,"mci status time format returned %s\n", dbg_mcierr(err)); + if(!err) { + if (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) == LANG_ENGLISH) + ok(!strcmp(buf,"milliseconds"), "mci status time format: %s\n", buf); + else trace("locale-dependent time format: %s (ms)\n", buf); + } err = mciSendString(command_close_my, NULL, 0, hwnd); - ok(!err,"mciSendString(%s, NULL, 0 , NULL) returned error: %d\n", command_close_my, err); + ok(!err,"mci %s returned %s\n", command_close_my, dbg_mcierr(err)); + test_notification(hwnd, command_close_my, MCI_NOTIFY_SUCCESSFUL); + Sleep(5); + test_notification(hwnd, command_close_my, 0); - ok(PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE ), "PeekMessage should succeed\n"); - ok(msg.hwnd == hwnd, "Didn't get the handle to our test window\n"); - ok(msg.message == MM_MCINOTIFY, "got %04x instead of MM_MCINOTIFY\n", msg.message); - ok(msg.wParam == MCI_NOTIFY_SUCCESSFUL, "got %08lx instead of MCI_NOTIFY_SUCCESSFUL\n", msg.wParam); + err = mciSendString("open no-such-file-exists.wav alias y", buf, sizeof(buf), NULL); + ok(err==MCIERR_FILE_NOT_FOUND,"open no-such-file.wav returned %s\n", dbg_mcierr(err)); + if(!err) { + err = mciSendString("close y", NULL, 0, NULL); + ok(!err,"close y returned %s\n", dbg_mcierr(err)); + } + + err = mciSendString("open no-such-dir\\file.wav alias y type waveaudio", buf, sizeof(buf), NULL); + ok(err==MCIERR_FILE_NOT_FOUND || broken(err==MCIERR_INVALID_FILE /* Win9X */),"open no-such-dir/file.wav returned %s\n", dbg_mcierr(err)); + if(!err) { + err = mciSendString("close y", NULL, 0, NULL); + ok(!err,"close y returned %s\n", dbg_mcierr(err)); + } err = mciSendString(command_close_all, NULL, 0, NULL); - todo_wine ok(!err,"mciSendString(%s, NULL, 0 , NULL) returned error: %d\n", command_close_all, err); + todo_wine ok(!err,"mci %s (without buffer) returned %s\n", command_close_all, dbg_mcierr(err)); memset(buf, 0, sizeof(buf)); err = mciSendString(command_close_all, buf, sizeof(buf), hwnd); - todo_wine ok(!err,"mciSendString(%s, buf, sizeof(buf) , NULL) returned error: %d\n", command_close_all, err); - ok(buf[0] == 0, "mciSendString(%s, buf, sizeof(buf) , NULL) changed output buffer: %s\n", command_close_all, buf); + todo_wine ok(!err,"mci %s (with output buffer) returned %s\n", command_close_all, dbg_mcierr(err)); + ok(buf[0] == 0, "mci %s changed output buffer: %s\n", command_close_all, buf); + /* No notification left, everything closed already */ + test_notification(hwnd, command_close_all, 0); + /* TODO test close all sends one notification per open device */ memset(buf, 0, sizeof(buf)); err = mciSendString(command_sysinfo, buf, sizeof(buf), NULL); - ok(!err,"mciSendString(%s, buf, sizeof(buf) , NULL) returned error: %d\n", command_sysinfo, err); - todo_wine ok(buf[0] == '0' && buf[1] == 0, "mciSendString(%s, buf, sizeof(buf) , NULL), expected output buffer '0', got: '%s'\n", command_sysinfo, buf); + ok(!err,"mci %s returned %s\n", command_sysinfo, dbg_mcierr(err)); + todo_wine ok(buf[0] == '0' && buf[1] == 0, "mci %s, expected output buffer '0', got: '%s'\n", command_sysinfo, buf); + + err = mciSendString("open new type waveaudio", buf, sizeof(buf), NULL); + ok(err==MCIERR_NEW_REQUIRES_ALIAS,"mci open new without alias returned %s\n", dbg_mcierr(err)); + + err = mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_WAIT, 0); /* from MSDN */ + ok(!err,"mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_NOTIFY, 0) returned %s\n", dbg_mcierr(err)); err = mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_NOTIFY, 0); - todo_wine ok(err == MCIERR_INVALID_DEVICE_ID || - broken(!err), /* Win9x and WinMe */ - "mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_NOTIFY, NULL) returned %d instead of %d\n", - err, MCIERR_INVALID_DEVICE_ID); + ok(!err,"mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_NOTIFY, 0) returned %s\n", dbg_mcierr(err)); + parm.dwCallback = (DWORD_PTR)hwnd; + err = mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_NOTIFY, (DWORD_PTR)&parm); + ok(!err,"mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_NOTIFY, hwnd) returned %s\n", dbg_mcierr(err)); + test_notification(hwnd, command_close_all, 0); /* None left */ +} + +static void test_recordWAVE(HWND hwnd) +{ + WORD nch = 1; + WORD nbits = 16; + DWORD nsamp = 16000, expect; + MCIERROR err, ok_pcm; + MCIDEVICEID wDeviceID; + MCI_PARMS_UNION parm; + char buf[1024]; + memset(buf, 0, sizeof(buf)); + test_notification(hwnd, "-prior to recording-", 0); + + parm.open.lpstrDeviceType = "waveaudio"; + parm.open.lpstrElementName = ""; /* "new" at the command level */ + parm.open.lpstrAlias = "x"; /* to enable mciSendString */ + parm.open.dwCallback = (DWORD_PTR)hwnd; + err = mciSendCommand(0, MCI_OPEN, + MCI_OPEN_ELEMENT | MCI_OPEN_TYPE | MCI_OPEN_ALIAS | MCI_NOTIFY, + (DWORD_PTR)&parm); + ok(!err,"mciCommand open new type waveaudio alias x notify: %s\n", dbg_mcierr(err)); + wDeviceID = parm.open.wDeviceID; + + /* In Wine, both MCI_Open and the individual drivers send notifications. */ + test_notification(hwnd, "open new", MCI_NOTIFY_SUCCESSFUL); + todo_wine test_notification1(hwnd, "open new no #2", 0); + + /* Do not query time format as string because result depends on locale! */ + parm.status.dwItem = MCI_STATUS_TIME_FORMAT; + err = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&parm); + ok(!err,"mciCommand status time format: %s\n", dbg_mcierr(err)); + ok(parm.status.dwReturn==MCI_FORMAT_MILLISECONDS,"status time format: %ld\n",parm.status.dwReturn); + + /* Info file fails until named in Open or Save. */ + err = mciSendString("info x file", buf, sizeof(buf), NULL); + todo_wine ok(err==MCIERR_NONAPPLICABLE_FUNCTION,"mci info new file returned %s\n", dbg_mcierr(err)); + + /* Check the default recording: 8-bits per sample, mono, 11kHz */ + err = mciSendString("status x samplespersec", buf, sizeof(buf), NULL); + ok(!err,"mci status samplespersec returned %s\n", dbg_mcierr(err)); + if(!err) ok(!strcmp(buf,"11025"), "mci status samplespersec expected 11025, got: %s\n", buf); + + /* MCI seems to solely support PCM, no need for ACM conversion. */ + err = mciSendString("set x format tag 2", NULL, 0, NULL); + ok(err==MCIERR_OUTOFRANGE,"mci set format tag 2 returned %s\n", dbg_mcierr(err)); + + /* MCI appears to scan the available devices for support of this format, + * returning MCIERR_OUTOFRANGE on machines with no sound. + * Don't skip here, record will fail below. */ + err = mciSendString("set x format tag pcm", NULL, 0, NULL); + ok(!err || err==MCIERR_OUTOFRANGE,"mci set format tag pcm returned %s\n", dbg_mcierr(err)); + ok_pcm = err; + + err = mciSendString("set x samplespersec 41000 alignment 4 channels 2", NULL, 0, NULL); + ok(err==ok_pcm,"mci set samples+align+channels returned %s\n", dbg_mcierr(err)); + + /* Investigate: on w2k, set samplespersec 22050 sets nChannels to 2! + * err = mciSendString("set x samplespersec 22050", NULL, 0, NULL); + * ok(!err,"mci set samplespersec returned %s\n", dbg_mcierr(err)); + */ + + parm.set.wFormatTag = WAVE_FORMAT_PCM; + parm.set.nSamplesPerSec = nsamp; + parm.set.wBitsPerSample = nbits; + parm.set.nChannels = nch; + parm.set.nBlockAlign = parm.set.nChannels * parm.set.wBitsPerSample /8; + parm.set.nAvgBytesPerSec= parm.set.nSamplesPerSec * parm.set.nBlockAlign; + err = mciSendCommand(wDeviceID, MCI_SET, + MCI_WAVE_SET_SAMPLESPERSEC | MCI_WAVE_SET_CHANNELS | + MCI_WAVE_SET_BITSPERSAMPLE | MCI_WAVE_SET_BLOCKALIGN | + MCI_WAVE_SET_AVGBYTESPERSEC| MCI_WAVE_SET_FORMATTAG, (DWORD_PTR)&parm); + ok(err==ok_pcm,"mciCommand set wave format: %s\n", dbg_mcierr(err)); + + /* A few ME machines pass all tests except set format tag pcm! */ + err = mciSendString("record x to 2000 wait", NULL, 0, hwnd); + ok(err || !ok_pcm,"can record yet set wave format pcm returned %s\n", dbg_mcierr(ok_pcm)); + ok(!err || err==(ok_pcm==MCIERR_OUTOFRANGE ? MCIERR_WAVE_INPUTSUNSUITABLE : 0),"mci record to 2000 returned %s\n", dbg_mcierr(err)); + if(err) { + if (err==MCIERR_WAVE_INPUTSUNSUITABLE) + skip("Please install audio driver. Everything is skipped.\n"); + else skip("Cannot record cause %s. Everything is skipped.\n", dbg_mcierr(err)); + + err = mciSendString("close x", NULL, 0, NULL); + ok(!err,"mci close returned %s\n", dbg_mcierr(err)); + test_notification(hwnd,"record skipped",0); + return; + } + + /* Query some wave format parameters depending on the time format. */ + err = mciSendString("status x position", buf, sizeof(buf), NULL); + ok(!err,"mci status position returned %s\n", dbg_mcierr(err)); + if(!err) todo_wine ok(!strcmp(buf,"2000"), "mci status position gave %s, expected 2000, some tests will fail\n", buf); + + err = mciSendString("set x time format 8", NULL, 0, NULL); /* bytes */ + ok(!err,"mci returned %s\n", dbg_mcierr(err)); + + parm.status.dwItem = MCI_STATUS_POSITION; + err = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&parm); + ok(!err,"mciCommand status position: %s\n", dbg_mcierr(err)); + expect = 2 * nsamp * nch * nbits/8; + if(!err) todo_wine ok(parm.status.dwReturn==expect,"recorded %lu bytes, expected %u\n",parm.status.dwReturn,expect); + + parm.set.dwTimeFormat = MCI_FORMAT_SAMPLES; + err = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)&parm); + ok(!err,"mciCommand set time format samples: %s\n", dbg_mcierr(err)); + + parm.status.dwItem = MCI_STATUS_POSITION; + err = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&parm); + ok(!err,"mciCommand status position: %s\n", dbg_mcierr(err)); + expect = 2 * nsamp; + if(!err) todo_wine ok(parm.status.dwReturn==expect,"recorded %lu samples, expected %u\n",parm.status.dwReturn,expect); + + err = mciSendString("set x time format milliseconds", NULL, 0, NULL); + ok(!err,"mci set time format milliseconds returned %s\n", dbg_mcierr(err)); + + err = mciSendString("save x tempfile1.wav", NULL, 0, NULL); + ok(!err,"mci save returned %s\n", dbg_mcierr(err)); + + err = mciSendString("save x tempfile.wav", NULL, 0, NULL); + ok(!err,"mci save returned %s\n", dbg_mcierr(err)); + if(!err) ok_saved = 0; + + /* Save must not rename the original file. */ + if (!DeleteFile("tempfile1.wav")) + todo_wine ok(FALSE, "Save must not rename the original file; DeleteFile returned %d\n", GetLastError()); + + err = mciSendString("set x channels 2", NULL, 0, NULL); + ok(err==MCIERR_NONAPPLICABLE_FUNCTION,"mci set channels after saving returned %s\n", dbg_mcierr(err)); + + parm.seek.dwTo = 600; + err = mciSendCommand(wDeviceID, MCI_SEEK, MCI_TO | MCI_WAIT, (DWORD_PTR)&parm); + ok(!err,"mciCommand seek to 600: %s\n", dbg_mcierr(err)); + + /* Truncate to current position */ + err = mciSendString("delete x", NULL, 0, NULL); + todo_wine ok(!err,"mci delete returned %s\n", dbg_mcierr(err)); + + buf[0]='\0'; + err = mciSendString("status x length", buf, sizeof(buf), NULL); + ok(!err,"mci status length returned %s\n", dbg_mcierr(err)); + todo_wine ok(!strcmp(buf,"600"), "mci status length after delete gave %s, expected 600\n", buf); + + err = mciSendString("close x", NULL, 0, NULL); + ok(!err,"mci close returned %s\n", dbg_mcierr(err)); + test_notification(hwnd,"record complete",0); +} + +static void test_playWAVE(HWND hwnd) +{ + MCIERROR err; + char buf[1024]; + memset(buf, 0, sizeof(buf)); + + err = mciSendString("open waveaudio!tempfile.wav alias mysound", NULL, 0, NULL); + ok(err==ok_saved,"mci open waveaudio!tempfile.wav returned %s\n", dbg_mcierr(err)); + if(err) { + skip("Cannot open waveaudio!tempfile.wav for playing (%s), skipping\n", dbg_mcierr(err)); + return; + } + + err = mciSendString("status mysound length", buf, sizeof(buf), NULL); + ok(!err,"mci status length returned %s\n", dbg_mcierr(err)); + todo_wine ok(!strcmp(buf,"2000"), "mci status length gave %s, expected 2000, some tests will fail.\n", buf); + + err = mciSendString("cue output", NULL, 0, NULL); + todo_wine ok(err==MCIERR_UNRECOGNIZED_COMMAND,"mci incorrect cue output returned %s\n", dbg_mcierr(err)); + + /* Test MCI to the bones -- Some todo_wine from Cue and + * from Play from 0 to 0 are not worth fixing. */ + err = mciSendString("cue mysound output notify", NULL, 0, hwnd); + ok(!err,"mci cue output after open file returned %s\n", dbg_mcierr(err)); + /* Notification is delayed as a play thread is started. */ + todo_wine test_notification1(hwnd, "cue immediate", 0); + + /* Cue pretends to put the MCI into paused state. */ + err = mciSendString("status mysound mode", buf, sizeof(buf), hwnd); + ok(!err,"mci status mode returned %s\n", dbg_mcierr(err)); + todo_wine ok(!strcmp(buf,"paused"), "mci status mode: %s, expected (pseudo)paused\n", buf); + + /* Strange pause where Pause is rejected, unlike Play; Pause; Pause tested below */ + err = mciSendString("pause mysound", NULL, 0, hwnd); + ok(err==MCIERR_NONAPPLICABLE_FUNCTION,"mci pause after cue returned %s\n", dbg_mcierr(err)); + + /* MCI appears to start the play thread in this border case. + * Guessed that from (flaky) status mode and late notification arrival. */ + err = mciSendString("play mysound from 0 to 0 notify", NULL, 0, hwnd); + ok(!err,"mci play from 0 to 0 returned %s\n", dbg_mcierr(err)); + todo_wine test_notification1(hwnd, "cue aborted by play", MCI_NOTIFY_ABORTED); + /* play's own notification follows below */ + + err = mciSendString("play mysound from 250 to 0", NULL, 0, NULL); + ok(err==MCIERR_OUTOFRANGE,"mci play from 250 to 0 returned %s\n", dbg_mcierr(err)); + + Sleep(50); /* Give play from 0 to 0 time to finish. */ + todo_wine test_notification1(hwnd, "play from 0 to 0", MCI_NOTIFY_SUCCESSFUL); + + err = mciSendString("status mysound mode", buf, sizeof(buf), hwnd); + ok(!err,"mci status mode returned %s\n", dbg_mcierr(err)); + ok(!strcmp(buf,"stopped"), "mci status mode: %s after play from 0 to 0\n", buf); + + err = mciSendString("play MYSOUND from 250 to 0 notify", NULL, 0, hwnd); + ok(err==MCIERR_OUTOFRANGE,"mci play from 250 to 0 notify returned %s\n", dbg_mcierr(err)); + /* No notification (checked below) sent if error */ + + /* A second play caused Wine<1.1.33 to hang */ + err = mciSendString("play mysound from 500 to 1500 wait", NULL, 0, NULL); + ok(!err,"mci play from 500 to 1500 returned %s\n", dbg_mcierr(err)); + + memset(buf, 0, sizeof(buf)); + err = mciSendString("status mysound position", buf, sizeof(buf), hwnd); + ok(!err,"mci status position returned %s\n", dbg_mcierr(err)); + if(!err) ok(!strcmp(buf,"1500"), "mci status position: %s\n", buf); + + /* mci will not play position < current */ + err = mciSendString("play mysound to 1000", NULL, 0, NULL); + ok(err==MCIERR_OUTOFRANGE,"mci play to 1000 returned %s\n", dbg_mcierr(err)); + + /* mci will not play to > end */ + err = mciSendString("play mysound TO 3000 notify", NULL, 0, hwnd); + ok(err==MCIERR_OUTOFRANGE,"mci play to 3000 notify returned %s\n", dbg_mcierr(err)); + + err = mciSendString("play mysound to 2000", NULL, 0, NULL); + ok(!err,"mci play to 2000 returned %s\n", dbg_mcierr(err)); + + /* Rejected while playing */ + err = mciSendString("cue mysound output", NULL, 0, NULL); + ok(err==MCIERR_NONAPPLICABLE_FUNCTION,"mci cue output while playing returned %s\n", dbg_mcierr(err)); + + err = mciSendString("play mysound to 3000", NULL, 0, NULL); + ok(err==MCIERR_OUTOFRANGE,"mci play to 3000 returned %s\n", dbg_mcierr(err)); + + err = mciSendString("stop mysound Wait", NULL, 0, NULL); + ok(!err,"mci stop wait returned %s\n", dbg_mcierr(err)); + test_notification(hwnd, "play/cue/pause/stop", 0); + + err = mciSendString("Seek Mysound to 250 wait Notify", NULL, 0, hwnd); + ok(!err,"mci seek to 250 wait notify returned %s\n", dbg_mcierr(err)); + test_notification(hwnd,"seek wait notify",MCI_NOTIFY_SUCCESSFUL); + + memset(buf, 0, sizeof(buf)); + err = mciSendString("status mysound position notify", buf, sizeof(buf), hwnd); + ok(!err,"mci status position notify returned %s\n", dbg_mcierr(err)); + if(!err) ok(!strcmp(buf,"250"), "mci status position: %s\n", buf); + /* Immediate commands like status also send notifications. */ + test_notification(hwnd,"status position",MCI_NOTIFY_SUCCESSFUL); + + memset(buf, 0, sizeof(buf)); + err = mciSendString("status mysound mode", buf, sizeof(buf), hwnd); + ok(!err,"mci status mode returned %s\n", dbg_mcierr(err)); + ok(!strcmp(buf,"stopped"), "mci status mode: %s\n", buf); + + /* Another play from == to testcase */ + err = mciSendString("play mysound to 250 wait notify", NULL, 0, hwnd); + ok(!err,"mci play (from 250) to 250 returned %s\n", dbg_mcierr(err)); + todo_wine test_notification1(hwnd,"play to 250 wait notify",MCI_NOTIFY_SUCCESSFUL); + + err = mciSendString("cue mysound output", NULL, 0, NULL); + ok(!err,"mci cue output after play returned %s\n", dbg_mcierr(err)); + + err = mciSendString("close mysound", NULL, 0, NULL); + ok(!err,"mci close returned %s\n", dbg_mcierr(err)); + test_notification(hwnd,"after close",0); +} + +static void test_asyncWAVE(HWND hwnd) +{ + MCIDEVICEID wDeviceID; + MCI_PARMS_UNION parm; + int err, p1, p2; + char buf[1024]; + memset(buf, 0, sizeof(buf)); + + err = mciSendString("open tempfile.wav alias mysound notify", buf, sizeof(buf), hwnd); + ok(err==ok_saved,"mci open tempfile.wav returned %s\n", dbg_mcierr(err)); + if(err) { + skip("Cannot open tempfile.wav for playing (%s), skipping\n", dbg_mcierr(err)); + return; + } + ok(!strcmp(buf,"1"), "mci open deviceId: %s, expected 1\n", buf); + wDeviceID = atoi(buf); + ok(wDeviceID,"mci open DeviceID: %d\n", wDeviceID); + test_notification(hwnd,"open alias notify",MCI_NOTIFY_SUCCESSFUL); + + err = mciSendString("status mysound mode", buf, sizeof(buf), hwnd); + ok(!err,"mci status mode returned %s\n", dbg_mcierr(err)); + ok(!strcmp(buf,"stopped"), "mci status mode: %s\n", buf); + + err = mciSendString("play mysound notify", NULL, 0, hwnd); + ok(!err,"mci play returned %s\n", dbg_mcierr(err)); + + /* Give Wine's asynchronous thread time to start up. Furthermore, + * it uses 3 buffers per second, so that the positions reported + * will be 333ms, 667ms etc. at best. */ + Sleep(100); /* milliseconds */ + + /* Do not query time format as string because result depends on locale! */ + parm.status.dwItem = MCI_STATUS_TIME_FORMAT; + err = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&parm); + ok(!err,"mciCommand status time format: %s\n", dbg_mcierr(err)); + if(!err) ok(parm.status.dwReturn==MCI_FORMAT_MILLISECONDS,"status time format: %ld\n",parm.status.dwReturn); + + parm.set.dwTimeFormat = MCI_FORMAT_MILLISECONDS; + err = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)&parm); + ok(!err,"mciCommand set time format ms: %s\n", dbg_mcierr(err)); + + buf[0]=0; + err = mciSendString("status mysound position", buf, sizeof(buf), hwnd); + ok(!err,"mci status position returned %s\n", dbg_mcierr(err)); + ok(strcmp(buf,"2000"), "mci status position: %s, expected 2000\n", buf); + trace("position after Sleep: %sms\n",buf); + p2 = atoi(buf); + /* Some machines reach 79ms only during the 100ms sleep. */ + ok(p2>=67,"not enough time elapsed %ums\n",p2); + test_notification(hwnd,"play (nowait)",0); + + err = mciSendString("pause mysound wait", NULL, 0, hwnd); + ok(!err,"mci pause wait returned %s\n", dbg_mcierr(err)); + + buf[0]=0; + err = mciSendString("status mysound mode notify", buf, sizeof(buf), hwnd); + ok(!err,"mci status mode returned %s\n", dbg_mcierr(err)); + if(!err) ok(!strcmp(buf,"paused"), "mci status mode: %s\n", buf); + test_notification(hwnd,"play",MCI_NOTIFY_SUPERSEDED); + test_notification(hwnd,"status",MCI_NOTIFY_SUCCESSFUL); + + buf[0]=0; + err = mciSendString("status mysound position", buf, sizeof(buf), hwnd); + ok(!err,"mci status position returned %s\n", dbg_mcierr(err)); + trace("position while paused: %sms\n",buf); + p1 = atoi(buf); + ok(p1>=p2, "position not increasing: %u > %u\n", p2, p1); + + err = mciSendString("stop mysound wait", NULL, 0, NULL); + ok(!err,"mci stop returned %s\n", dbg_mcierr(err)); + + buf[0]=0; + err = mciSendString("info mysound file notify", buf, sizeof(buf), hwnd); + ok(!err,"mci info file returned %s\n", dbg_mcierr(err)); + if(!err) { /* fully qualified name */ + int len = strlen(buf); + todo_wine ok(len>2 && buf[1]==':',"Expected full pathname from info file: %s\n", buf); + ok(len>=12 && !strcmp(&buf[len-12],"tempfile.wav"), "info file returned: %s\n", buf); + } + test_notification(hwnd,"info file",MCI_NOTIFY_SUCCESSFUL); + + buf[0]=0; + err = mciSendString("status mysound mode", buf, sizeof(buf), hwnd); + ok(!err,"mci status mode returned %s\n", dbg_mcierr(err)); + ok(!strcmp(buf,"stopped"), "mci status mode: %s\n", buf); + + buf[0]=0; + err = mciSendString("status mysound position", buf, sizeof(buf), hwnd); + ok(!err,"mci status position returned %s\n", dbg_mcierr(err)); + trace("position once stopped: %sms\n",buf); + p2 = atoi(buf); + /* An XP machine let the position increase slightly after pause. */ + ok(p2>=p1 && p2<=p1+16,"position changed from %ums to %ums\n",p1,p2); + + /* No Resume once stopped (waveaudio, sequencer and cdaudio differ). */ + err = mciSendString("resume mysound wait", NULL, 0, NULL); + ok(err==MCIERR_NONAPPLICABLE_FUNCTION,"mci resume wait returned %s\n", dbg_mcierr(err)); + + err = mciSendString("play mysound wait", NULL, 0, NULL); + ok(!err,"mci play wait returned %s\n", dbg_mcierr(err)); + + buf[0]=0; + err = mciSendString("status mysound position", buf, sizeof(buf), hwnd); + ok(!err,"mci status position returned %s\n", dbg_mcierr(err)); + todo_wine ok(!strcmp(buf,"2000"), "mci status position: %s\n", buf); + + err = mciSendString("seek mysound to start wait", NULL, 0, NULL); + ok(!err,"mci seek to start wait returned %s\n", dbg_mcierr(err)); + + err = mciSendString("play mysound to 1000 notify", NULL, 0, hwnd); + ok(!err,"mci play returned %s\n", dbg_mcierr(err)); + + /* Sleep(200); not needed with Wine any more. */ + + err = mciSendString("pause mysound notify", NULL, 0, NULL); /* notify no callback */ + ok(!err,"mci pause notify returned %s\n", dbg_mcierr(err)); + /* Supersede even though pause cannot notify given no callback */ + test_notification(hwnd,"pause aborted play #1 notification",MCI_NOTIFY_SUPERSEDED); + test_notification(hwnd,"impossible pause notification",0); + + err = mciSendString("cue mysound output notify", NULL, 0, hwnd); + ok(err==MCIERR_NONAPPLICABLE_FUNCTION,"mci cue output while paused returned %s\n", dbg_mcierr(err)); + test_notification(hwnd,"cue output notify #2",0); + + err = mciSendString("resume mysound notify", NULL, 0, hwnd); + ok(!err,"mci resume notify returned %s\n", dbg_mcierr(err)); + test_notification(hwnd, "resume notify", MCI_NOTIFY_SUCCESSFUL); + + /* Seek or even Stop used to hang Wine<1.1.32 on MacOS. */ + err = mciSendString("seek mysound to 0 wait", NULL, 0, NULL); + ok(!err,"mci seek to start returned %s\n", dbg_mcierr(err)); + + /* Seek stops. */ + err = mciSendString("status mysound mode", buf, sizeof(buf), NULL); + ok(!err,"mci status mode returned %s\n", dbg_mcierr(err)); + if(!err) ok(!strcmp(buf,"stopped"), "mci status mode: %s\n", buf); + + err = mciSendString("seek mysound wait", NULL, 0, NULL); + ok(err==MCIERR_MISSING_PARAMETER,"mci seek to nowhere returned %s\n", dbg_mcierr(err)); + + /* cdaudio does not detect to start to end as error */ + err = mciSendString("seek mysound to start to 0", NULL, 0, NULL); + ok(err==MCIERR_FLAGS_NOT_COMPATIBLE,"mci seek to start to 0 returned %s\n", dbg_mcierr(err)); + + err = mciSendString("PLAY mysound to 1000 notify", NULL, 0, hwnd); + ok(!err,"mci play to 1000 notify returned %s\n", dbg_mcierr(err)); + + /* Sleep(200); not needed with Wine any more. */ + /* Give it 400ms and resume will appear to complete below. */ + + err = mciSendString("pause mysound wait", NULL, 0, NULL); + ok(!err,"mci pause wait returned %s\n", dbg_mcierr(err)); + /* Unlike sequencer and cdaudio, waveaudio's pause does not abort. */ + test_notification(hwnd,"pause aborted play #2 notification",0); + + err = mciSendString("resume mysound wait", NULL, 0, NULL); + ok(!err,"mci resume wait returned %s\n", dbg_mcierr(err)); + /* Resume is a short asynchronous call, something else is playing. */ + + err = mciSendString("status mysound mode", buf, sizeof(buf), NULL); + ok(!err,"mci status mode returned %s\n", dbg_mcierr(err)); + if(!err) ok(!strcmp(buf,"playing"), "mci status mode: %s\n", buf); + + /* Note extra space before alias */ + err = mciSendString("pause mysound wait", NULL, 0, NULL); + todo_wine ok(!err,"mci pause (space) wait returned %s\n", dbg_mcierr(err)); + + err = mciSendString("pause mysound wait", NULL, 0, NULL); + ok(!err,"mci pause wait returned %s\n", dbg_mcierr(err)); + + /* Better ask position only when paused, is it updated while playing? */ + buf[0]='\0'; + err = mciSendString("status mysound position", buf, sizeof(buf), NULL); + ok(!err,"mci status position returned %s\n", dbg_mcierr(err)); + /* TODO compare position < 900 */ + ok(strcmp(buf,"1000"), "mci resume waited\n"); + ok(strcmp(buf,"2000"), "mci resume played to end\n"); + trace("position after resume: %sms\n",buf); + test_notification(hwnd,"play (aborted by pause/resume/pause)",0); + + err = mciSendString("close mysound wait", NULL, 0, NULL); + ok(!err,"mci close wait returned %s\n", dbg_mcierr(err)); + test_notification(hwnd,"play (aborted by close)",MCI_NOTIFY_ABORTED); +} + +static void test_AutoOpenWAVE(HWND hwnd) +{ + /* This test used(?) to cause intermittent crashes when Wine exits, after + * fixme:winmm:MMDRV_Exit Closing while ll-driver open + */ + MCIERROR err, ok_snd; + char buf[512], path[300], command[330]; + memset(buf, 0, sizeof(buf)); memset(path, 0, sizeof(path)); + + /* Do not crash on NULL buffer pointer */ + err = mciSendString("sysinfo waveaudio quantity open", NULL, 0, NULL); + ok(err==MCIERR_PARAM_OVERFLOW,"mci sysinfo without buffer returned %s\n", dbg_mcierr(err)); + + err = mciSendString("sysinfo waveaudio quantity open", buf, sizeof(buf), NULL); + ok(!err,"mci sysinfo waveaudio quantity open returned %s\n", dbg_mcierr(err)); + if(!err) todo_wine ok(!strcmp(buf,"0"), "sysinfo quantity open expected 0, got: %s, some more tests will fail.\n", buf); + + ok_snd = waveOutGetNumDevs() ? 0 : MCIERR_HARDWARE; + err = mciSendString("sound NoSuchSoundDefined wait", NULL, 0, NULL); + todo_wine ok(err==ok_snd,"mci sound NoSuchSoundDefined returned %s\n", dbg_mcierr(err)); + + err = mciSendString("sound SystemExclamation notify wait", NULL, 0, hwnd); + todo_wine ok(err==ok_snd,"mci sound SystemExclamation returned %s\n", dbg_mcierr(err)); + test_notification(hwnd, "sound notify", err ? 0 : MCI_NOTIFY_SUCCESSFUL); + + buf[0]=0; + err = mciSendString("sysinfo waveaudio name 1 open", buf, sizeof(buf), NULL); + todo_wine ok(err==MCIERR_OUTOFRANGE,"sysinfo waveaudio name 1 returned %s\n", dbg_mcierr(err)); + if(!err) trace("sysinfo dangling open alias: %s\n", buf); + + err = mciSendString("play no-such-file-exists.wav notify", buf, sizeof(buf), NULL); + if(err==MCIERR_FILE_NOT_FOUND) { /* a Wine detector */ + /* Unsupported auto-open leaves the file open, preventing clean-up */ + skip("Skipping auto-open tests in Wine\n"); + return; + } + + err = mciSendString("play tempfile.wav notify", buf, sizeof(buf), hwnd); + todo_wine ok(err==MCIERR_NOTIFY_ON_AUTO_OPEN,"mci auto-open play notify returned %s\n", dbg_mcierr(err)); + + if(err) /* FIXME: don't open twice yet, it confuses Wine. */ + err = mciSendString("play tempfile.wav", buf, sizeof(buf), hwnd); + ok(err==ok_saved,"mci auto-open play returned %s\n", dbg_mcierr(err)); + + if(err==MCIERR_FILE_NOT_FOUND) { + skip("Cannot open tempfile.wav for auto-play, skipping\n"); + return; + } + + buf[0]=0; + err = mciSendString("sysinfo waveaudio quantity open", buf, sizeof(buf), NULL); + ok(!err,"mci sysinfo waveaudio quantity after auto-open returned %s\n", dbg_mcierr(err)); + if(!err) todo_wine ok(!strcmp(buf,"1"), "sysinfo quantity open expected 1, got: %s\n", buf); + + buf[0]=0; + err = mciSendString("sysinfo waveaudio name 1 open", buf, sizeof(buf), NULL); + todo_wine ok(!err,"mci sysinfo waveaudio name after auto-open returned %s\n", dbg_mcierr(err)); + /* This is the alias, not necessarily a file name. */ + if(!err) ok(!strcmp(buf,"tempfile.wav"), "sysinfo name 1 open: %s\n", buf); + + /* Save the full pathname to the file. */ + err = mciSendString("info tempfile.wav file", path, sizeof(path), NULL); + ok(!err,"mci info tempfile.wav file returned %s\n", dbg_mcierr(err)); + if(err) strcpy(path,"tempfile.wav"); + + err = mciSendString("status tempfile.wav mode", NULL, 0, hwnd); + ok(!err,"mci status tempfile.wav mode without buffer returned %s\n", dbg_mcierr(err)); + + sprintf(command,"status \"%s\" mode",path); + err = mciSendString(command, buf, sizeof(buf), hwnd); + ok(!err,"mci status \"%s\" mode returned %s\n", path, dbg_mcierr(err)); + + buf[0]=0; + err = mciSendString("status tempfile.wav mode", buf, sizeof(buf), hwnd); + ok(!err,"mci status tempfile.wav mode returned %s\n", dbg_mcierr(err)); + if(!err) ok(!strcmp(buf,"playing"), "mci auto-open status mode, got: %s\n", buf); + + err = mciSendString("open tempfile.wav", buf, sizeof(buf), NULL); + todo_wine ok(err==MCIERR_DEVICE_OPEN, "mci open from auto-open returned %s\n", dbg_mcierr(err)); + + /* w2k/xp and Wine differ. While the device is busy playing, it is + * regularly open and accessible via the filename: subsequent + * commands must not cause auto-open each. In Wine, a subsequent + * command with notify request may cause the initial play + * notification to be superseded, in turn causing MCI to close the + * device. I.e. MCI uses the auto-open notification for itself, + * that's why it's not available to the app. On w2k/xp, + * subsequent commands with notify requests are returned with + * MCIERR_NOTIFY_ON_AUTO_OPEN and thus don't abort the original + * command. + */ + err = mciSendString("status tempfile.wav mode notify", buf, sizeof(buf), hwnd); + todo_wine ok(err==MCIERR_NOTIFY_ON_AUTO_OPEN, "mci status auto-open notify returned %s\n", dbg_mcierr(err)); + if(!err) { + trace("Wine style MCI auto-close upon notification\n"); + + /* "playing" because auto-close comes after the status call. */ + todo_wine ok(!strcmp(buf,"playing"), "mci auto-open status mode notify, got: %s\n", buf); + /* fixme:winmm:MMDRV_Exit Closing while ll-driver open + * is explained by failure to auto-close a device. */ + test_notification(hwnd,"status notify",MCI_NOTIFY_SUCCESSFUL); + /* MCI received NOTIFY_SUPERSEDED and auto-closed the device. */ + Sleep(16); + test_notification(hwnd,"auto-open",0); + } else if(err==MCIERR_NOTIFY_ON_AUTO_OPEN) { /* MS style */ + trace("MS style MCI auto-open forbids notification\n"); + + err = mciSendString("pause tempfile.wav", NULL, 0, hwnd); + ok(!err,"mci auto-still-open pause returned %s\n", dbg_mcierr(err)); + + err = mciSendString("status tempfile.wav mode", buf, sizeof(buf), hwnd); + ok(!err,"mci status mode returned %s\n", dbg_mcierr(err)); + if(!err) ok(!strcmp(buf,"paused"), "mci auto-open status mode, got: %s\n", buf); + + /* Auto-close */ + err = mciSendString("stop tempfile.wav", NULL, 0, hwnd); + ok(!err,"mci auto-still-open stop returned %s\n", dbg_mcierr(err)); + Sleep(16); /* makes sysinfo quantity open below succeed */ + } + + err = mciSendString("sysinfo waveaudio quantity open", buf, sizeof(buf), NULL); + ok(!err,"mci sysinfo waveaudio quantity open after close returned %s\n", dbg_mcierr(err)); + if(!err) todo_wine ok(!strcmp(buf,"0"), "sysinfo quantity open expected 0 after auto-close, got: %s\n", buf); + + /* w95-WinME (not w2k/XP) switch to C:\ after auto-playing once. Prevent + * MCIERR_FILE_NOT_FOUND by using the full path name from the Info file command. + */ + sprintf(command,"status \"%s\" mode wait",path); + err = mciSendString(command, buf, sizeof(buf), hwnd); + ok(!err,"mci re-auto-open status mode returned %s\n", dbg_mcierr(err)); + if(!err) ok(!strcmp(buf,"stopped"), "mci re-auto-open status mode, got: %s\n", buf); + + err = mciSendString("capability waveaudio device type", buf, sizeof(buf), hwnd); + ok(!err,"mci capability device type returned %s\n", dbg_mcierr(err)); + if(!err) ok(!strcmp(buf,"waveaudio"), "mci capability device type response: %s\n", buf); + + /* waveaudio forbids Pause without Play. */ + sprintf(command,"pause \"%s\"",path); + err = mciSendString(command, NULL, 0, hwnd); + ok(err==MCIERR_NONAPPLICABLE_FUNCTION,"mci auto-open pause returned %s\n", dbg_mcierr(err)); +} + +START_TEST(mci) +{ + MCIERROR err; + HWND hwnd; + hwnd = CreateWindowExA(0, "static", "winmm test", WS_POPUP, 0,0,100,100, + 0, 0, 0, NULL); + test_openCloseWAVE(hwnd); + test_recordWAVE(hwnd); + test_playWAVE(hwnd); + test_asyncWAVE(hwnd); + test_AutoOpenWAVE(hwnd); + /* Win9X hangs when exiting with something still open. */ + err = mciSendString("close all", NULL, 0, hwnd); + todo_wine ok(!err,"final close all returned %s\n", dbg_mcierr(err)); + ok(DeleteFile("tempfile.wav")||ok_saved,"Delete tempfile.wav (cause auto-open?)\n"); DestroyWindow(hwnd); } diff --git a/rostests/winetests/wldap32/parse.c b/rostests/winetests/wldap32/parse.c index d4b5de2fadf..0f22d238674 100644 --- a/rostests/winetests/wldap32/parse.c +++ b/rostests/winetests/wldap32/parse.c @@ -57,8 +57,13 @@ static void test_ldap_parse_sort_control( LDAP *ld ) ok( !ret, "ldap_search_ext_sA failed 0x%x\n", ret ); ok( res != NULL, "expected res != NULL\n" ); - ret = ldap_parse_resultA( NULL, res, &result, NULL, NULL, NULL, &server_ctrls, 1 ); - ok( ret == LDAP_PARAM_ERROR, "ldap_parse_resultA failed 0x%x\n", ret ); + if (GetProcAddress(GetModuleHandle("wldap32.dll"), "ber_init")) + { + ret = ldap_parse_resultA( NULL, res, &result, NULL, NULL, NULL, &server_ctrls, 1 ); + ok( ret == LDAP_PARAM_ERROR, "ldap_parse_resultA failed 0x%x\n", ret ); + } + else + win_skip("Test would crash on older wldap32 versions\n"); result = ~0u; ret = ldap_parse_resultA( ld, res, &result, NULL, NULL, NULL, &server_ctrls, 1 );