diff --git a/dll/ntdll/def/ntdll.spec b/dll/ntdll/def/ntdll.spec index 7a362f48ae..ebf6350346 100644 --- a/dll/ntdll/def/ntdll.spec +++ b/dll/ntdll/def/ntdll.spec @@ -124,9 +124,9 @@ @ stdcall LdrUnloadDll(ptr) @ stdcall LdrUnlockLoaderLock(long long) @ stdcall LdrVerifyImageMatchesChecksum(ptr long long long) -@ extern NlsAnsiCodePage -@ extern NlsMbCodePageTag -@ extern NlsMbOemCodePageTag +@ stdcall NlsAnsiCodePage() NlsAnsiCodePage +@ stdcall NlsMbCodePageTag() NlsMbCodePageTag +@ stdcall NlsMbOemCodePageTag() NlsMbOemCodePageTag @ stdcall NtAcceptConnectPort(ptr long ptr long long ptr) @ stdcall NtAccessCheck(ptr long long ptr ptr ptr ptr ptr) @ stdcall NtAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr) diff --git a/dll/win32/advapi32/advapi32.spec b/dll/win32/advapi32/advapi32.spec index d776e5afbe..86de042fd4 100644 --- a/dll/win32/advapi32/advapi32.spec +++ b/dll/win32/advapi32/advapi32.spec @@ -766,4 +766,6 @@ @ stdcall SetNamedSecurityInfoWNative(wstr long ptr ptr ptr ptr ptr) SetNamedSecurityInfoW @ stdcall SetSecurityInfoNative(long long long ptr ptr ptr ptr) SetSecurityInfo @ stdcall GetSecurityInfoNative(long long long ptr ptr ptr ptr ptr) GetSecurityInfo -@ stdcall GetNamedSecurityInfoWNative(wstr long long ptr ptr ptr ptr ptr) GetNamedSecurityInfoW \ No newline at end of file +@ stdcall GetNamedSecurityInfoWNative(wstr long long ptr ptr ptr ptr ptr) GetNamedSecurityInfoW +@ stdcall RegGetValueWNative(long wstr wstr long ptr ptr ptr) RegGetValueW +@ stdcall RegNotifyChangeKeyValueNative(long long long long long) RegNotifyChangeKeyValue \ No newline at end of file diff --git a/dll/win32/bcrypt/bcrypt.spec b/dll/win32/bcrypt/bcrypt.spec index 7f49bf75e3..54d7908719 100644 --- a/dll/win32/bcrypt/bcrypt.spec +++ b/dll/win32/bcrypt/bcrypt.spec @@ -59,4 +59,7 @@ @ stub GetSignatureInterface @ stub BCryptDeriveKeyCapi -@ stub BCryptDeriveKeyPBKDF2 \ No newline at end of file +@ stub BCryptDeriveKeyPBKDF2 + +#For Bcrypt Hook +@ stdcall -stub BCryptCreateHashNative(ptr ptr ptr long ptr long long) \ No newline at end of file diff --git a/win32ss/gdi/gdi32/gdi32.spec b/win32ss/gdi/gdi32/gdi32.spec index 290beba125..30a95b4821 100644 --- a/win32ss/gdi/gdi32/gdi32.spec +++ b/win32ss/gdi/gdi32/gdi32.spec @@ -622,4 +622,12 @@ 618 stdcall D3DKMTDestroyDevice(ptr) 619 stdcall D3DKMTOpenAdapterFromGdiDisplayName(ptr) 620 stdcall D3DKMTSetVidPnSourceOwner(ptr) -621 stdcall D3DKMTCheckVidPnExclusiveOwnership(ptr) \ No newline at end of file +621 stdcall D3DKMTCheckVidPnExclusiveOwnership(ptr) + +@ stdcall -stub D3DKMTCheckMonitorPowerState(ptr) +@ stdcall -stub D3DKMTCheckSharedResourceAccess(ptr) +@ stdcall -stub D3DKMTOpenAdapterFromLuid(ptr) +@ stdcall -stub D3DKMTQueryStatistics(ptr) +@ stdcall -stub D3DKMTQueryVideoMemoryInfo(ptr) +@ stdcall -stub D3DKMTSetQueuedLimit(ptr) +@ stdcall -stub D3DKMTSetProcessSchedulingPriorityClass(long long) \ No newline at end of file diff --git a/wrappers/CMakeLists.txt b/wrappers/CMakeLists.txt index b416fe6a75..357fc9276f 100644 --- a/wrappers/CMakeLists.txt +++ b/wrappers/CMakeLists.txt @@ -7,3 +7,4 @@ add_subdirectory(drivers) add_subdirectory(extensions) add_subdirectory(ext-sets) add_subdirectory(new-dlls) +add_subdirectory(tools) diff --git a/wrappers/api-sets/API-MS-WIN-APPMODEL-RUNTIME-L1-1-0.spec b/wrappers/api-sets/API-MS-WIN-APPMODEL-RUNTIME-L1-1-0.spec index acb4eb8b0a..69e8812815 100644 --- a/wrappers/api-sets/API-MS-WIN-APPMODEL-RUNTIME-L1-1-0.spec +++ b/wrappers/api-sets/API-MS-WIN-APPMODEL-RUNTIME-L1-1-0.spec @@ -1,4 +1,4 @@ -@ stub GetApplicationUserModelId +@ stdcall GetApplicationUserModelId(long ptr wstr) kernelex.GetApplicationUserModelId @ stdcall GetCurrentPackageFullName(ptr ptr) kernel32.GetCurrentPackageFullName @ stdcall GetPackageFullName(long ptr ptr) kernel32.GetPackageFullName -@ stub PackageFamilyNameFromFullName +@ stdcall -stub PackageFamilyNameFromFullName(wstr ptr wstr) diff --git a/wrappers/api-sets/API-MS-WIN-CORE-FEATURESTAGING-L1-1-0.spec b/wrappers/api-sets/API-MS-WIN-CORE-FEATURESTAGING-L1-1-0.spec index ab5127b7df..af6d74c8e4 100644 --- a/wrappers/api-sets/API-MS-WIN-CORE-FEATURESTAGING-L1-1-0.spec +++ b/wrappers/api-sets/API-MS-WIN-CORE-FEATURESTAGING-L1-1-0.spec @@ -1,5 +1,5 @@ -@ stub GetFeatureEnabledState +@ stdcall GetFeatureEnabledState(long long) shcore.GetFeatureEnabledState @ stub RecordFeatureError @ stub RecordFeatureUsage -@ stub SubscribeFeatureStateChangeNotification -@ stub UnsubscribeFeatureStateChangeNotification +@ stdcall SubscribeFeatureStateChangeNotification(ptr ptr ptr) shcore.SubscribeFeatureStateChangeNotification +@ stdcall UnsubscribeFeatureStateChangeNotification(ptr) shcore.UnsubscribeFeatureStateChangeNotification diff --git a/wrappers/api-sets/API-MS-WIN-CORE-LOCALIZATION-L1-2-2.spec b/wrappers/api-sets/API-MS-WIN-CORE-LOCALIZATION-L1-2-2.spec index 37f45c3303..f8461d21a2 100644 --- a/wrappers/api-sets/API-MS-WIN-CORE-LOCALIZATION-L1-2-2.spec +++ b/wrappers/api-sets/API-MS-WIN-CORE-LOCALIZATION-L1-2-2.spec @@ -27,7 +27,7 @@ @ stdcall IdnToUnicode(long wstr long ptr long) kernel32.IdnToUnicode @ stdcall IsDBCSLeadByte(long) kernel32.IsDBCSLeadByte @ stdcall IsDBCSLeadByteEx(long long) kernel32.IsDBCSLeadByteEx -@ stub IsNLSDefinedString +@ stdcall IsNLSDefinedString(long long ptr long long) kernel32.IsNLSDefinedString @ stdcall IsValidCodePage(long) kernel32.IsValidCodePage @ stdcall IsValidLocale(long long) kernel32.IsValidLocale @ stdcall IsValidLocaleName(wstr) kernel32.IsValidLocaleName diff --git a/wrappers/api-sets/API-MS-WIN-SHCORE-SCALING-L1-1-0.spec b/wrappers/api-sets/API-MS-WIN-SHCORE-SCALING-L1-1-0.spec index 0dd1fd8b00..263f971964 100644 --- a/wrappers/api-sets/API-MS-WIN-SHCORE-SCALING-L1-1-0.spec +++ b/wrappers/api-sets/API-MS-WIN-SHCORE-SCALING-L1-1-0.spec @@ -1,3 +1,3 @@ @ stdcall GetScaleFactorForDevice(long) shcore.GetScaleFactorForDevice -@ stub RegisterScaleChangeNotifications +@ stdcall RegisterScaleChangeNotifications(long ptr long ptr) shcore.RegisterScaleChangeNotifications @ stub RevokeScaleChangeNotifications diff --git a/wrappers/api-sets/CMakeLists.txt b/wrappers/api-sets/CMakeLists.txt index 015cb8d48f..ad91459123 100644 --- a/wrappers/api-sets/CMakeLists.txt +++ b/wrappers/api-sets/CMakeLists.txt @@ -41,18 +41,18 @@ add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/x86_reactos.apisets_6595b64144ccf1d # Apisets will be appended add_apiset(api-ms-win-appmodel-identity-l1-1-0 0x60000000 kernel32) -add_apiset(api-ms-win-appmodel-runtime-l1-1-0 0x60010000 kernel32) -add_apiset(api-ms-win-appmodel-runtime-l1-1-1 0x60020000 kernel32) -add_apiset(api-ms-win-appmodel-runtime-l1-1-2 0x0FAF0000 kernel32) +add_apiset(api-ms-win-appmodel-runtime-l1-1-0 0x60010000 kernel32 kernelex) +add_apiset(api-ms-win-appmodel-runtime-l1-1-1 0x60020000 kernel32 kernelex) +add_apiset(api-ms-win-appmodel-runtime-l1-1-2 0x0FAF0000 kernel32 kernelex) add_apiset(api-ms-win-base-util-l1-1-0 0x60060000 advapi32) add_apiset(api-ms-win-core-apiquery-l1-1-0 0x60060000 kernel32) add_apiset(api-ms-win-core-appcompat-l1-1-1 0x60070000 kernel32) add_apiset(api-ms-win-core-appinit-l1-1-0 0x60080000 kernel32) add_apiset(api-ms-win-core-atoms-l1-1-0 0x60090000 kernel32) add_apiset(api-ms-win-core-bem-l1-1-0 0x600a0000 kernel32 ntdll) -add_apiset(api-ms-win-core-com-l1-1-0 0x600b0000 ole32 ntdll kernel32) -add_apiset(api-ms-win-core-com-l1-1-1 0x600c0000 ole32 ntdll kernel32) -add_apiset(api-ms-win-core-com-private-l1-1-0 0x600e0000 ole32) +add_apiset(api-ms-win-core-com-l1-1-0 0x600b0000 ntdll kernel32 combase) +add_apiset(api-ms-win-core-com-l1-1-1 0x600c0000 ntdll kernel32 combase) +add_apiset(api-ms-win-core-com-private-l1-1-0 0x600e0000 combase) add_apiset(api-ms-win-core-comm-l1-1-0 0x60130000 kernel32) add_apiset(api-ms-win-core-console-l1-1-0 0x60140000 kernel32) add_apiset(api-ms-win-core-console-l1-2-0 0x60150000 kernel32) @@ -70,7 +70,7 @@ add_apiset(api-ms-win-core-errorhandling-l1-1-0 0x60200000 kernel32) add_apiset(api-ms-win-core-errorhandling-l1-1-1 0x60210000 kernel32) add_apiset(api-ms-win-core-errorhandling-l1-1-2 0x60220000 kernel32) add_apiset(api-ms-win-core-errorhandling-l1-1-3 0x60230000 kernel32) -add_apiset(api-ms-win-core-featurestaging-l1-1-0 0x60230000 kernel32) +add_apiset(api-ms-win-core-featurestaging-l1-1-0 0x60230000 kernel32 shcore) add_apiset(api-ms-win-core-fibers-l1-1-0 0x60240000 kernel32) add_apiset(api-ms-win-core-fibers-l1-1-1 0x60250000 kernel32) add_apiset(api-ms-win-core-fibers-l2-1-0 0x60250000 kernel32) @@ -119,10 +119,10 @@ add_apiset(api-ms-win-core-localization-obsolete-l1-3-0 0x60470000 kernel32) add_apiset(api-ms-win-core-localization-private-l1-1-0 0x60480000 kernel32) add_apiset(api-ms-win-core-localregistry-l1-1-0 0x60490000 advapi32) add_apiset(api-ms-win-core-memory-l1-1-0 0x604a0000 kernel32) -add_apiset(api-ms-win-core-memory-l1-1-1 0x604b0000 kernel32) -add_apiset(api-ms-win-core-memory-l1-1-2 0x604b0000 kernel32) -add_apiset(api-ms-win-core-memory-l1-1-3 0x604c0000 kernel32) -add_apiset(api-ms-win-core-memory-l1-1-4 0x604c0000 kernel32) +add_apiset(api-ms-win-core-memory-l1-1-1 0x604b0000 kernelex) +add_apiset(api-ms-win-core-memory-l1-1-2 0x604c0000 kernel32) +add_apiset(api-ms-win-core-memory-l1-1-3 0x604d0000 kernel32) +add_apiset(api-ms-win-core-memory-l1-1-4 0x604e0000 kernel32) add_apiset(api-ms-win-core-misc-l1-1-0 0x604d0000 kernel32) add_apiset(api-ms-win-core-namedpipe-ansi-l1-1-0 0x604d0000 kernel32) add_apiset(api-ms-win-core-namedpipe-l1-1-0 0x604e0000 kernel32 advapi32) @@ -137,7 +137,7 @@ add_apiset(api-ms-win-core-processenvironment-l1-2-0 0x60560000 kernel32) add_apiset(api-ms-win-core-processthreads-l1-1-0 0x60570000 kernel32 advapi32) add_apiset(api-ms-win-core-processthreads-l1-1-1 0x60580000 kernel32 advapi32) add_apiset(api-ms-win-core-processthreads-l1-1-2 0x60590000 kernel32 advapi32) -add_apiset(api-ms-win-core-processthreads-l1-1-3 0x605a0000 kernel32 kernelex) +add_apiset(api-ms-win-core-processthreads-l1-1-3 0x605a0000 kernelex) add_apiset(api-ms-win-core-processtopology-l1-1-0 0x605a0000 kernel32) add_apiset(api-ms-win-core-processtopology-obsolete-l1-1-0 0x605b0000 kernel32) add_apiset(api-ms-win-core-profile-l1-1-0 0x605c0000 kernel32) @@ -196,8 +196,8 @@ add_apiset(api-ms-win-core-winrt-string-l1-1-0 0x608c0000 combase) add_apiset(api-ms-win-core-winrt-string-l1-1-1 0x608e0000 combase) add_apiset(api-ms-win-core-wow64-l1-1-0 0x60900000 kernel32) add_apiset(api-ms-win-core-wow64-l1-1-1 0x60910000 kernel32) -add_apiset(api-ms-win-core-xstate-l1-1-0 0x60920000 ) -add_apiset(api-ms-win-core-xstate-l2-1-0 0x60930000 ) +add_apiset(api-ms-win-core-xstate-l1-1-0 0x60920000 kernelex) +add_apiset(api-ms-win-core-xstate-l2-1-0 0x60930000 kernelex) add_apiset(api-ms-win-crt-conio-l1-1-0 0x60940000 ucrtbase) add_apiset(api-ms-win-crt-convert-l1-1-0 0x60960000 ucrtbase) add_apiset(api-ms-win-crt-environment-l1-1-0 0x609c0000 ucrtbase) @@ -206,7 +206,6 @@ add_apiset(api-ms-win-crt-heap-l1-1-0 0x60a00000 ucrtbase) add_apiset(api-ms-win-crt-locale-l1-1-0 0x60a10000 ucrtbase) add_apiset(api-ms-win-crt-math-l1-1-0 0x60a20000 ucrtbase) add_apiset(api-ms-win-crt-multibyte-l1-1-0 0x60b30000 ucrtbase) -add_apiset(api-ms-win-crt-private-l1-1-0 0x60bb0000 ucrtbase kernel32) add_apiset(api-ms-win-crt-process-l1-1-0 0x61020000 ucrtbase) add_apiset(api-ms-win-crt-runtime-l1-1-0 0x61030000 ucrtbase) add_apiset(api-ms-win-crt-stdio-l1-1-0 0x61070000 ucrtbase) @@ -226,7 +225,7 @@ add_apiset(api-ms-win-downlevel-shlwapi-l1-1-0 0x611f0000 shlwapi kernel32) add_apiset(api-ms-win-downlevel-shlwapi-l2-1-0 0x61200000 shlwapi) add_apiset(api-ms-win-downlevel-user32-l1-1-0 0x61210000 user32) add_apiset(api-ms-win-downlevel-version-l1-1-0 0x61220000 version) -add_apiset(api-ms-win-dx-d3dkmt-l1-1-0 0x61230000 gdi32) +add_apiset(api-ms-win-dx-d3dkmt-l1-1-0 0x61230000 gdi32 d3dkmt) add_apiset(api-ms-win-eventing-classicprovider-l1-1-0 0x61290000 advapi32) add_apiset(api-ms-win-eventing-consumer-l1-1-0 0x612a0000 advapi32) add_apiset(api-ms-win-eventing-controller-l1-1-0 0x612b0000 advapi32) diff --git a/wrappers/api-sets/api-ms-win-appmodel-runtime-l1-1-1.spec b/wrappers/api-sets/api-ms-win-appmodel-runtime-l1-1-1.spec index 4d2edd60f5..f61a33a0e1 100644 --- a/wrappers/api-sets/api-ms-win-appmodel-runtime-l1-1-1.spec +++ b/wrappers/api-sets/api-ms-win-appmodel-runtime-l1-1-1.spec @@ -1,25 +1,25 @@ @ stub ClosePackageInfo -@ stub FindPackagesByPackageFamily +@ stdcall FindPackagesByPackageFamily(wstr long ptr ptr ptr ptr ptr) kernelex.FindPackagesByPackageFamily @ stub FormatApplicationUserModelId -@ stub GetApplicationUserModelId -@ stub GetCurrentApplicationUserModelId +@ stdcall GetApplicationUserModelId(long ptr wstr) kernelex.GetApplicationUserModelId +@ stdcall GetCurrentApplicationUserModelId(ptr wstr) kernelex.GetCurrentApplicationUserModelId @ stdcall GetCurrentPackageFamilyName(ptr ptr) kernel32.GetCurrentPackageFamilyName @ stdcall GetCurrentPackageFullName(ptr ptr) kernel32.GetCurrentPackageFullName @ stdcall GetCurrentPackageId(ptr ptr) kernel32.GetCurrentPackageId -@ stub GetCurrentPackageInfo -@ stub GetCurrentPackagePath -@ stub GetPackageApplicationIds -@ stub GetPackageFamilyName +@ stdcall GetCurrentPackageInfo(long ptr ptr ptr) kernelex.GetCurrentPackageInfo +@ stdcall GetCurrentPackagePath(ptr ptr) kernelex.GetCurrentPackagePath +@ stdcall GetPackageApplicationIds (ptr ptr ptr ptr) kernelex.GetPackageApplicationIds +@ stdcall GetPackageFamilyName(long ptr ptr) kernelex.GetPackageFamilyName @ stdcall GetPackageFullName(long ptr ptr) kernel32.GetPackageFullName @ stub GetPackageId @ stub GetPackageInfo @ stub GetPackagePath -@ stub GetPackagePathByFullName -@ stub GetPackagesByPackageFamily +@ stdcall GetPackagePathByFullName(wstr ptr wstr) kernelex.GetPackagePathByFullName +@ stdcall GetPackagesByPackageFamily(wstr ptr ptr ptr ptr) kernelex.GetPackagesByPackageFamily @ stub GetStagedPackageOrigin @ stub GetStagedPackagePathByFullName -@ stub OpenPackageInfoByFullName -@ stub PackageFamilyNameFromFullName +@ stdcall OpenPackageInfoByFullName (wstr long ptr) kernelex.OpenPackageInfoByFullName +@ stdcall -stub PackageFamilyNameFromFullName(wstr ptr wstr) @ stub PackageFamilyNameFromId @ stub PackageFullNameFromId @ stub PackageIdFromFullName diff --git a/wrappers/api-sets/api-ms-win-appmodel-runtime-l1-1-2.spec b/wrappers/api-sets/api-ms-win-appmodel-runtime-l1-1-2.spec index 890288d31f..9ab94806d5 100644 --- a/wrappers/api-sets/api-ms-win-appmodel-runtime-l1-1-2.spec +++ b/wrappers/api-sets/api-ms-win-appmodel-runtime-l1-1-2.spec @@ -1,7 +1,7 @@ @ stub AppPolicyGetClrCompat @ stub AppPolicyGetCreateFileAccess @ stub AppPolicyGetLifecycleManagement -@ stub AppPolicyGetMediaFoundationCodecLoading +@ stdcall AppPolicyGetMediaFoundationCodecLoading(ptr ptr) kernelex.AppPolicyGetMediaFoundationCodecLoading @ stdcall AppPolicyGetProcessTerminationMethod(ptr ptr) kernel32.AppPolicyGetProcessTerminationMethod @ stdcall AppPolicyGetShowDeveloperDiagnostic(ptr ptr) kernel32.AppPolicyGetShowDeveloperDiagnostic @ stdcall AppPolicyGetThreadInitializationType(ptr ptr) kernel32.AppPolicyGetThreadInitializationType diff --git a/wrappers/api-sets/api-ms-win-core-apiquery-l1-1-0.spec b/wrappers/api-sets/api-ms-win-core-apiquery-l1-1-0.spec index 6d63b5bf43..c06a874c0c 100644 --- a/wrappers/api-sets/api-ms-win-core-apiquery-l1-1-0.spec +++ b/wrappers/api-sets/api-ms-win-core-apiquery-l1-1-0.spec @@ -1 +1 @@ -@ stub ApiSetQueryApiSetPresence +@ stdcall -stub ApiSetQueryApiSetPresence(ptr ptr) diff --git a/wrappers/api-sets/api-ms-win-core-com-l1-1-0.spec b/wrappers/api-sets/api-ms-win-core-com-l1-1-0.spec index ccb9ca9e8e..4fc232af3e 100644 --- a/wrappers/api-sets/api-ms-win-core-com-l1-1-0.spec +++ b/wrappers/api-sets/api-ms-win-core-com-l1-1-0.spec @@ -2,25 +2,25 @@ @ stdcall CLSIDFromString(wstr ptr) ole32.CLSIDFromString @ stdcall CoAddRefServerProcess() ole32.CoAddRefServerProcess @ stub CoAllowUnmarshalerCLSID ;(long) ole.CoAllowUnmarshalerCLSID -@ stdcall CoCancelCall(long long) +@ stdcall CoCancelCall(long long) ole32.CoCancelCall @ stdcall CoCopyProxy(ptr ptr) ole32.CoCopyProxy @ stdcall CoCreateFreeThreadedMarshaler(ptr ptr) ole32.CoCreateFreeThreadedMarshaler @ stdcall CoCreateGuid(ptr) ole32.CoCreateGuid @ stdcall CoCreateInstance(ptr ptr long ptr ptr) ole32.CoCreateInstance @ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr) ole32.CoCreateInstanceEx -@ stub CoCreateInstanceFromApp -@ stub CoDecodeProxy -@ stub CoDecrementMTAUsage -@ stub CoDisableCallCancellation -@ stub CoDisconnectContext +@ stdcall CoCreateInstanceFromApp(ptr ptr long ptr long ptr) combase.CoCreateInstanceFromApp +@ stdcall CoDecodeProxy(long int64 ptr) combase.CoDecodeProxy +@ stdcall CoDecrementMTAUsage(ptr) combase.CoDecrementMTAUsage +@ stdcall CoDisableCallCancellation(ptr) ole32.CoDisableCallCancellation +@ stdcall CoDisconnectContext(long) ole32.CoDisconnectContext @ stdcall CoDisconnectObject(ptr long) ole32.CoDisconnectObject -@ stub CoEnableCallCancellation +@ stdcall CoEnableCallCancellation(ptr) ole32.CoEnableCallCancellation @ stdcall CoFreeUnusedLibraries() ole32.CoFreeUnusedLibraries @ stdcall CoFreeUnusedLibrariesEx(long long) ole32.CoFreeUnusedLibrariesEx -@ stub CoGetApartmentType +@ stdcall CoGetApartmentType(ptr ptr) combase.CoGetApartmentType @ stdcall CoGetCallContext(ptr ptr) ole32.CoGetCallContext @ stdcall CoGetCallerTID(ptr) ole32.CoGetCallerTID -@ stub CoGetCancelObject +@ stdcall CoGetCancelObject(long ptr ptr) ole32.CoGetCancelObject @ stdcall CoGetClassObject(ptr long ptr ptr ptr) ole32.CoGetClassObject @ stdcall CoGetContextToken(ptr) ole32.CoGetContextToken @ stdcall CoGetCurrentLogicalThreadId(ptr) ole32.CoGetCurrentLogicalThreadId @@ -32,10 +32,10 @@ @ stdcall CoGetObjectContext(ptr ptr) ole32.CoGetObjectContext @ stdcall CoGetPSClsid(ptr ptr) ole32.CoGetPSClsid @ stdcall CoGetStandardMarshal(ptr ptr long ptr long ptr) ole32.CoGetStandardMarshal -@ stub CoGetStdMarshalEx +@ stdcall CoGetStdMarshalEx(ptr long ptr) ole32.CoGetStdMarshalEx @ stdcall CoGetTreatAsClass(ptr ptr) ole32.CoGetTreatAsClass @ stdcall CoImpersonateClient() ole32.CoImpersonateClient -@ stub CoIncrementMTAUsage +@ stdcall CoIncrementMTAUsage(ptr) combase.CoIncrementMTAUsage @ stdcall CoInitializeEx(ptr long) ole32.CoInitializeEx @ stdcall CoInitializeSecurity(ptr long ptr ptr long long ptr long ptr) ole32.CoInitializeSecurity @ stdcall CoInvalidateRemoteMachineBindings(str) ole32.CoInvalidateRemoteMachineBindings @@ -62,7 +62,7 @@ @ stdcall CoTaskMemAlloc(long) ole32.CoTaskMemAlloc @ stdcall CoTaskMemFree(ptr) ole32.CoTaskMemFree @ stdcall CoTaskMemRealloc(ptr long) ole32.CoTaskMemRealloc -@ stdcall CoTestCancel() ole.CoTestCancel +@ stdcall CoTestCancel() ole32.CoTestCancel @ stdcall CoUninitialize() ole32.CoUninitialize @ stdcall CoUnmarshalHresult(ptr ptr) ole32.CoUnmarshalHresult @ stdcall CoUnmarshalInterface(ptr ptr ptr) ole32.CoUnmarshalInterface diff --git a/wrappers/api-sets/api-ms-win-core-com-l1-1-1.spec b/wrappers/api-sets/api-ms-win-core-com-l1-1-1.spec index 2be401e06f..a2680acc44 100644 --- a/wrappers/api-sets/api-ms-win-core-com-l1-1-1.spec +++ b/wrappers/api-sets/api-ms-win-core-com-l1-1-1.spec @@ -8,16 +8,16 @@ @ stdcall CoCreateGuid(ptr) ole32.CoCreateGuid @ stdcall CoCreateInstance(ptr ptr long ptr ptr) ole32.CoCreateInstance @ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr) ole32.CoCreateInstanceEx -@ stub CoCreateInstanceFromApp -@ stub CoDecodeProxy -@ stub CoDecrementMTAUsage +@ stdcall CoCreateInstanceFromApp(ptr ptr long ptr long ptr) combase.CoCreateInstanceFromApp +@ stdcall CoDecodeProxy(long int64 ptr) combase.CoDecodeProxy +@ stdcall CoDecrementMTAUsage(ptr) combase.CoDecrementMTAUsage @ stdcall CoDisableCallCancellation(ptr) ole32.CoDisableCallCancellation -@ stub CoDisconnectContext +@ stdcall CoDisconnectContext(long) ole32.CoDisconnectContext @ stdcall CoDisconnectObject(ptr long) ole32.CoDisconnectObject @ stdcall CoEnableCallCancellation(ptr) ole32.CoEnableCallCancellation @ stdcall CoFreeUnusedLibraries() ole32.CoFreeUnusedLibraries @ stdcall CoFreeUnusedLibrariesEx(long long) ole32.CoFreeUnusedLibrariesEx -@ stub CoGetApartmentType ;(ptr ptr) ole32.CoGetApartmentType +@ stdcall CoGetApartmentType(ptr ptr) combase.CoGetApartmentType @ stdcall CoGetCallContext(ptr ptr) ole32.CoGetCallContext @ stdcall CoGetCallerTID(ptr) ole32.CoGetCallerTID @ stdcall CoGetCancelObject(long long ptr) ole32.CoGetCancelObject @@ -35,7 +35,7 @@ @ stdcall CoGetStdMarshalEx(ptr long ptr) ole32.CoGetStdMarshalEx @ stdcall CoGetTreatAsClass(ptr ptr) ole32.CoGetTreatAsClass @ stdcall CoImpersonateClient() ole32.CoImpersonateClient -@ stub CoIncrementMTAUsage +@ stdcall CoIncrementMTAUsage(ptr) combase.CoIncrementMTAUsage @ stdcall CoInitializeEx(ptr long) ole32.CoInitializeEx @ stdcall CoInitializeSecurity(ptr long ptr ptr long long ptr long ptr) ole32.CoInitializeSecurity @ stdcall CoInvalidateRemoteMachineBindings(str) CoInvalidateRemoteMachineBindings @@ -47,7 +47,7 @@ @ stdcall CoQueryAuthenticationServices(ptr ptr) ole32.CoQueryAuthenticationServices @ stdcall CoQueryClientBlanket(ptr ptr ptr ptr ptr ptr ptr) ole32.CoQueryClientBlanket @ stdcall CoQueryProxyBlanket(ptr ptr ptr ptr ptr ptr ptr ptr) ole32.CoQueryProxyBlanket -@ stub CoRegisterActivationFilter +@ stdcall CoRegisterActivationFilter(ptr) ole32.CoRegisterActivationFilter @ stdcall CoRegisterClassObject(ptr ptr long long ptr) ole32.CoRegisterClassObject @ stdcall CoRegisterPSClsid(ptr ptr) ole32.CoRegisterPSClsid @ stdcall CoRegisterSurrogate(ptr) ole32.CoRegisterSurrogate @@ -76,7 +76,7 @@ @ stdcall ProgIDFromCLSID(ptr ptr) ole32.ProgIDFromCLSID @ stdcall PropVariantClear(ptr) ole32.PropVariantClear @ stdcall PropVariantCopy(ptr ptr) ole32.PropVariantCopy -@ stub RoGetAgileReference +@ stdcall RoGetAgileReference(long long ptr ptr) combase.RoGetAgileReference @ stdcall StringFromCLSID(ptr ptr) ole32.StringFromCLSID @ stdcall StringFromGUID2(ptr ptr long) ole32.StringFromGUID2 @ stdcall StringFromIID(ptr ptr) ole32.StringFromIID diff --git a/wrappers/api-sets/api-ms-win-core-com-private-l1-1-0.spec b/wrappers/api-sets/api-ms-win-core-com-private-l1-1-0.spec index b73c631715..bf872797b7 100644 --- a/wrappers/api-sets/api-ms-win-core-com-private-l1-1-0.spec +++ b/wrappers/api-sets/api-ms-win-core-com-private-l1-1-0.spec @@ -6,8 +6,8 @@ @ stub CoCreateObjectInContext @ stub CoDeactivateObject @ stub CoGetActivationState ;(int128 long ptr) ole32.CoGetActivationState -@ stub CoGetApartmentID -@ stub CoGetCallState ;(long ptr) ole32.CoGetCallState +@ stdcall CoGetApartmentID(long ptr) ole32.CoGetApartmentID +@ stdcall CoGetCallState(long ptr) combase.CoGetCallState @ stub CoGetClassVersion @ stub CoGetErrorInfo @ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr) ole32.CoGetInstanceFromFile diff --git a/wrappers/api-sets/api-ms-win-core-file-l1-2-2.spec b/wrappers/api-sets/api-ms-win-core-file-l1-2-2.spec index bb58af1a1d..9ddfcf56d6 100644 --- a/wrappers/api-sets/api-ms-win-core-file-l1-2-2.spec +++ b/wrappers/api-sets/api-ms-win-core-file-l1-2-2.spec @@ -1,8 +1,8 @@ @ stdcall AreFileApisANSI() kernel32.AreFileApisANSI -@ stub FindFirstFileNameW -@ stub FindFirstStreamW -@ stub FindNextFileNameW -@ stub FindNextStreamW +@ stdcall FindFirstFileNameW(wstr long ptr wstr) kernelex.FindFirstFileNameW +@ stdcall FindFirstStreamW(wstr ptr ptr long) kernelex.FindFirstStreamW +@ stdcall FindNextFileNameW(long ptr wstr) kernelex.FindNextFileNameW +@ stdcall FindNextStreamW(ptr ptr) kernelex.FindNextStreamW @ stdcall GetTempFileNameA(str str long ptr) kernel32.GetTempFileNameA @ stdcall GetTempPathA(long ptr) kernel32.GetTempPathA @ stdcall GetVolumeInformationA(str ptr long ptr ptr ptr ptr long) kernel32.GetVolumeInformationA diff --git a/wrappers/api-sets/api-ms-win-core-file-l2-1-0.spec b/wrappers/api-sets/api-ms-win-core-file-l2-1-0.spec index de460c93ad..b3533ce203 100644 --- a/wrappers/api-sets/api-ms-win-core-file-l2-1-0.spec +++ b/wrappers/api-sets/api-ms-win-core-file-l2-1-0.spec @@ -1,4 +1,4 @@ -@ stub CopyFile2 ;(wstr wstr ptr) kernel32.CopyFile2 +@ stdcall CopyFile2(wstr wstr ptr) kernelex.CopyFile2 @ stdcall CopyFileExW(wstr wstr ptr ptr ptr long) kernel32.CopyFileExW @ stdcall CreateDirectoryExW(wstr wstr ptr) kernel32.CreateDirectoryExW @ stdcall CreateHardLinkW(wstr wstr ptr) kernel32.CreateHardLinkW diff --git a/wrappers/api-sets/api-ms-win-core-file-l2-1-1.spec b/wrappers/api-sets/api-ms-win-core-file-l2-1-1.spec index fed7a8bec4..9e00520d97 100644 --- a/wrappers/api-sets/api-ms-win-core-file-l2-1-1.spec +++ b/wrappers/api-sets/api-ms-win-core-file-l2-1-1.spec @@ -1,4 +1,4 @@ -@ stub CopyFile2 ;(wstr wstr ptr) kernel32.CopyFile2 +@ stdcall CopyFile2(wstr wstr ptr) kernelex.CopyFile2 @ stdcall CopyFileExW(wstr wstr ptr ptr ptr long) kernel32.CopyFileExW @ stdcall CreateDirectoryExW(wstr wstr ptr) kernel32.CreateDirectoryExW @ stdcall CreateHardLinkW(wstr wstr ptr) kernel32.CreateHardLinkW diff --git a/wrappers/api-sets/api-ms-win-core-file-l2-1-2.spec b/wrappers/api-sets/api-ms-win-core-file-l2-1-2.spec index ab6f303a2d..7598c8d0ac 100644 --- a/wrappers/api-sets/api-ms-win-core-file-l2-1-2.spec +++ b/wrappers/api-sets/api-ms-win-core-file-l2-1-2.spec @@ -1,4 +1,4 @@ -@ stub CopyFile2 +@ stdcall CopyFile2(wstr wstr ptr) kernelex.CopyFile2 @ stdcall CopyFileExW(wstr wstr ptr ptr ptr long) kernel32.CopyFileExW @ stdcall CopyFileW(wstr wstr long) kernel32.CopyFileW @ stdcall CreateDirectoryExW(wstr wstr ptr) kernel32.CreateDirectoryExW diff --git a/wrappers/api-sets/api-ms-win-core-kernel32-legacy-l1-1-1.spec b/wrappers/api-sets/api-ms-win-core-kernel32-legacy-l1-1-1.spec index 2cf56802e8..87ed1f4c07 100644 --- a/wrappers/api-sets/api-ms-win-core-kernel32-legacy-l1-1-1.spec +++ b/wrappers/api-sets/api-ms-win-core-kernel32-legacy-l1-1-1.spec @@ -27,7 +27,7 @@ @ stdcall GetDurationFormatEx(wstr long ptr long long ptr ptr long) kernel32.GetDurationFormatEx @ stdcall GetFileAttributesTransactedA(str long ptr ptr) kernel32.GetFileAttributesTransactedA @ stdcall GetFileAttributesTransactedW(wstr long ptr ptr) kernel32.GetFileAttributesTransactedW -@ stub GetFirmwareType ;(ptr) kernel32.GetFirmwareType +@ stdcall GetFirmwareType(ptr) kernelex.GetFirmwareType @ stdcall GetMaximumProcessorGroupCount() kernel32.GetMaximumProcessorGroupCount @ stdcall GetNamedPipeClientProcessId(ptr ptr) kernel32.GetNamedPipeClientProcessId @ stdcall GetNamedPipeClientSessionId(ptr ptr) kernel32.GetNamedPipeClientSessionId diff --git a/wrappers/api-sets/api-ms-win-core-localization-l1-2-0.spec b/wrappers/api-sets/api-ms-win-core-localization-l1-2-0.spec index a1c4d37554..1cac2136b6 100644 --- a/wrappers/api-sets/api-ms-win-core-localization-l1-2-0.spec +++ b/wrappers/api-sets/api-ms-win-core-localization-l1-2-0.spec @@ -27,7 +27,7 @@ @ stdcall GetThreadLocale() kernel32.GetThreadLocale @ stdcall GetThreadPreferredUILanguages(long ptr ptr ptr) kernel32.GetThreadPreferredUILanguages @ stdcall GetThreadUILanguage() kernel32.GetThreadUILanguage -@ stub GetUILanguageInfo ;(long wstr wstr ptr ptr) kernel32.GetUILanguageInfo +@ stdcall GetUILanguageInfo(long wstr wstr ptr ptr) kernel32.GetUILanguageInfo @ stdcall GetUserDefaultLCID() kernel32.GetUserDefaultLCID @ stdcall GetUserDefaultLangID() kernel32.GetUserDefaultLangID @ stdcall GetUserDefaultLocaleName(ptr long) kernel32.GetUserDefaultLocaleName diff --git a/wrappers/api-sets/api-ms-win-core-memory-l1-1-1.spec b/wrappers/api-sets/api-ms-win-core-memory-l1-1-1.spec index 293dff1625..1da2e6d388 100644 --- a/wrappers/api-sets/api-ms-win-core-memory-l1-1-1.spec +++ b/wrappers/api-sets/api-ms-win-core-memory-l1-1-1.spec @@ -1,4 +1,4 @@ -@ stub CreateFileMappingFromApp ;(ptr ptr long int64 wstr) kernel32.CreateFileMappingFromApp +@ stdcall CreateFileMappingFromApp(long ptr long int64 wstr) kernelex.CreateFileMappingFromApp @ stdcall CreateFileMappingNumaW(ptr ptr long long long wstr long) kernel32.CreateFileMappingNumaW @ stdcall CreateFileMappingW(long ptr long long long wstr) kernel32.CreateFileMappingW @ stdcall CreateMemoryResourceNotification(long) kernel32.CreateMemoryResourceNotification @@ -9,16 +9,16 @@ @ stdcall GetWriteWatch(long ptr long ptr ptr ptr) kernel32.GetWriteWatch @ stdcall MapViewOfFile(long long long long long) kernel32.MapViewOfFile @ stdcall MapViewOfFileEx(long long long long long ptr) kernel32.MapViewOfFileEx -@ stub MapViewOfFileFromApp ;(ptr long int64 long) kernel32.MapViewOfFileFromApp +@ stdcall MapViewOfFileFromApp(long long int64 long) kernelex.MapViewOfFileFromApp @ stdcall OpenFileMappingW(long long wstr) kernel32.OpenFileMappingW -@ stub PrefetchVirtualMemory ;(ptr long ptr long) kernel32.PrefetchVirtualMemory +@ stdcall PrefetchVirtualMemory(ptr ptr ptr long) kernelex.PrefetchVirtualMemory @ stdcall QueryMemoryResourceNotification(ptr ptr) kernel32.QueryMemoryResourceNotification @ stdcall ReadProcessMemory(long ptr ptr long ptr) kernel32.ReadProcessMemory @ stdcall ResetWriteWatch(ptr long) kernel32.ResetWriteWatch @ stdcall SetProcessWorkingSetSizeEx(long long long long) kernel32.SetProcessWorkingSetSizeEx @ stdcall SetSystemFileCacheSize(long long long) kernel32.SetSystemFileCacheSize @ stdcall UnmapViewOfFile(ptr) kernel32.UnmapViewOfFile -@ stub UnmapViewOfFileEx ;(ptr long) kernel32.UnmapViewOfFileEx +@ stdcall UnmapViewOfFileEx(ptr long) kernelex.UnmapViewOfFileEx @ stdcall VirtualAlloc(ptr long long long) kernel32.VirtualAlloc @ stdcall VirtualAllocEx(long ptr long long long) kernel32.VirtualAllocEx @ stdcall VirtualFree(ptr long long) kernel32.VirtualFree diff --git a/wrappers/api-sets/api-ms-win-core-timezone-l1-1-0.spec b/wrappers/api-sets/api-ms-win-core-timezone-l1-1-0.spec index bf2c4d0d9d..8a048fd027 100644 --- a/wrappers/api-sets/api-ms-win-core-timezone-l1-1-0.spec +++ b/wrappers/api-sets/api-ms-win-core-timezone-l1-1-0.spec @@ -1,10 +1,10 @@ -@ stub EnumDynamicTimeZoneInformation +@ stdcall EnumDynamicTimeZoneInformation(long ptr) kernelex.EnumDynamicTimeZoneInformation @ stdcall FileTimeToSystemTime(ptr ptr) kernel32.FileTimeToSystemTime @ stdcall GetDynamicTimeZoneInformation(ptr) kernel32.GetDynamicTimeZoneInformation -@ stub GetDynamicTimeZoneInformationEffectiveYears +@ stdcall GetDynamicTimeZoneInformationEffectiveYears(ptr ptr ptr) kernelex.GetDynamicTimeZoneInformationEffectiveYears @ stdcall GetTimeZoneInformation(ptr) kernel32.GetTimeZoneInformation @ stdcall GetTimeZoneInformationForYear(long ptr ptr) kernel32.GetTimeZoneInformationForYear -@ stub SetDynamicTimeZoneInformation +@ stdcall SetDynamicTimeZoneInformation(ptr) kernelex.SetDynamicTimeZoneInformation @ stdcall SetTimeZoneInformation(ptr) kernel32.SetTimeZoneInformation @ stdcall SystemTimeToFileTime(ptr ptr) kernel32.SystemTimeToFileTime @ stdcall SystemTimeToTzSpecificLocalTime(ptr ptr ptr) kernel32.SystemTimeToTzSpecificLocalTime diff --git a/wrappers/api-sets/api-ms-win-core-xstate-l2-1-0.spec b/wrappers/api-sets/api-ms-win-core-xstate-l2-1-0.spec index 0f9438dc85..1e6af92811 100644 --- a/wrappers/api-sets/api-ms-win-core-xstate-l2-1-0.spec +++ b/wrappers/api-sets/api-ms-win-core-xstate-l2-1-0.spec @@ -1,6 +1,6 @@ -@ stub CopyContext -@ stub GetEnabledXStateFeatures -@ stub GetXStateFeaturesMask -@ stub InitializeContext -@ stub LocateXStateFeature -@ stub SetXStateFeaturesMask +@ stdcall CopyContext(ptr long ptr) kernelex.CopyContext +@ stdcall -ret64 -arch=i386,x86_64 GetEnabledXStateFeatures() kernelex.GetEnabledXStateFeatures +@ stdcall -arch=i386,x86_64 GetXStateFeaturesMask(ptr ptr) kernelex.GetXStateFeaturesMask +@ stdcall -arch=i386,x86_64 InitializeContext(ptr long ptr ptr) kernelex.InitializeContext +@ stdcall -arch=i386,x86_64 LocateXStateFeature(ptr long ptr) kernelex.LocateXStateFeature +@ stdcall -arch=i386,x86_64 SetXStateFeaturesMask(ptr int64) kernelex.SetXStateFeaturesMask diff --git a/wrappers/api-sets/api-ms-win-crt-private-l1-1-0.spec b/wrappers/api-sets/api-ms-win-crt-private-l1-1-0.spec deleted file mode 100644 index f2d3e15b29..0000000000 --- a/wrappers/api-sets/api-ms-win-crt-private-l1-1-0.spec +++ /dev/null @@ -1,1167 +0,0 @@ -@ cdecl _CreateFrameInfo(ptr ptr) ucrtbase._CreateFrameInfo -@ stdcall _CxxThrowException(long long) ucrtbase._CxxThrowException -@ cdecl -arch=i386 -norelay _EH_prolog() ucrtbase._EH_prolog -@ cdecl _FindAndUnlinkFrame(ptr) ucrtbase._FindAndUnlinkFrame -@ stub _GetImageBase -@ stub _GetThrowImageBase -@ cdecl _IsExceptionObjectToBeDestroyed(ptr) ucrtbase._IsExceptionObjectToBeDestroyed -@ stub _NLG_Dispatch2 -@ stub _NLG_Return -@ stub _NLG_Return2 -@ stub _SetImageBase -@ stub _SetThrowImageBase -@ stub _SetWinRTOutOfMemoryExceptionCallback -@ cdecl __AdjustPointer(ptr ptr) ucrtbase.__AdjustPointer -@ stub __BuildCatchObject -@ stub __BuildCatchObjectHelper -@ stdcall -arch=x86_64 __C_specific_handler(ptr long ptr ptr) ucrtbase.__C_specific_handler -@ cdecl -arch=i386,x86_64,arm __CxxDetectRethrow(ptr) ucrtbase.__CxxDetectRethrow -@ cdecl -arch=i386,x86_64,arm __CxxExceptionFilter(ptr ptr long ptr) ucrtbase.__CxxExceptionFilter -@ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler(ptr ptr ptr ptr) ucrtbase.__CxxFrameHandler -@ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler2(ptr ptr ptr ptr) ucrtbase.__CxxFrameHandler2 -@ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler3(ptr ptr ptr ptr) ucrtbase.__CxxFrameHandler3 -@ stdcall -arch=i386 __CxxLongjmpUnwind(ptr) ucrtbase.__CxxLongjmpUnwind -@ cdecl -arch=i386,x86_64,arm __CxxQueryExceptionSize() ucrtbase.__CxxQueryExceptionSize -@ cdecl __CxxRegisterExceptionObject(ptr ptr) ucrtbase.__CxxRegisterExceptionObject -@ cdecl __CxxUnregisterExceptionObject(ptr long) ucrtbase.__CxxUnregisterExceptionObject -@ cdecl __DestructExceptionObject(ptr) ucrtbase.__DestructExceptionObject -@ stub __FrameUnwindFilter -@ stub __GetPlatformExceptionInfo -@ stub __NLG_Dispatch2 -@ stub __NLG_Return2 -@ cdecl __RTCastToVoid(ptr) ucrtbase.__RTCastToVoid -@ cdecl __RTDynamicCast(ptr long ptr ptr long) ucrtbase.__RTDynamicCast -@ cdecl __RTtypeid(ptr) ucrtbase.__RTtypeid -@ stub __TypeMatch -@ stub __current_exception -@ stub __current_exception_context -@ stub __dcrt_get_wide_environment_from_os -@ stub __dcrt_initial_narrow_environment -@ stub __intrinsic_abnormal_termination -@ stub __intrinsic_setjmp -@ stub __intrinsic_setjmpex -@ stub __processing_throw -@ stub __report_gsfailure -@ cdecl __std_exception_copy(ptr ptr) ucrtbase.__std_exception_copy -@ cdecl __std_exception_destroy(ptr) ucrtbase.__std_exception_destroy -@ cdecl __std_type_info_compare(ptr ptr) ucrtbase.__std_type_info_compare -@ cdecl __std_type_info_destroy_list(ptr) ucrtbase.__std_type_info_destroy_list -@ cdecl __std_type_info_hash(ptr) ucrtbase.__std_type_info_hash -@ cdecl __std_type_info_name(ptr ptr) ucrtbase.__std_type_info_name -@ cdecl __unDName(ptr str long ptr ptr long) ucrtbase.__unDName -@ cdecl __unDNameEx(ptr str long ptr ptr ptr long) ucrtbase.__unDNameEx -@ cdecl __uncaught_exception() ucrtbase.__uncaught_exception -@ cdecl -arch=i386 -norelay _chkesp() ucrtbase._chkesp -@ cdecl -arch=i386 _except_handler2(ptr ptr ptr ptr) ucrtbase._except_handler2 -@ cdecl -arch=i386 _except_handler3(ptr ptr ptr ptr) ucrtbase._except_handler3 -@ cdecl -arch=i386 _except_handler4_common(ptr ptr ptr ptr ptr ptr) ucrtbase._except_handler4_common -@ stub _get_purecall_handler -@ cdecl _get_unexpected() ucrtbase._get_unexpected -@ cdecl -arch=i386 _global_unwind2(ptr) ucrtbase._global_unwind2 -@ stub _is_exception_typeof -@ cdecl -arch=x86_64 _local_unwind(ptr ptr) ucrtbase._local_unwind -@ cdecl -arch=i386 _local_unwind2(ptr long) ucrtbase._local_unwind2 -@ cdecl -arch=i386 _local_unwind4(ptr ptr long) ucrtbase._local_unwind4 -@ cdecl -arch=i386 _longjmpex(ptr long) ucrtbase._longjmpex -@ stub _o__CIacos -@ stub _o__CIasin -@ stub _o__CIatan -@ stub _o__CIatan2 -@ stub _o__CIcos -@ stub _o__CIcosh -@ stub _o__CIexp -@ stub _o__CIfmod -@ stub _o__CIlog -@ stub _o__CIlog10 -@ stub _o__CIpow -@ stub _o__CIsin -@ stub _o__CIsinh -@ stub _o__CIsqrt -@ stub _o__CItan -@ stub _o__CItanh -@ stub _o__Getdays -@ stub _o__Getmonths -@ stub _o__Gettnames -@ stub _o__Strftime -@ stub _o__W_Getdays -@ stub _o__W_Getmonths -@ stub _o__W_Gettnames -@ stub _o__Wcsftime -@ stub _o___acrt_iob_func -@ stub _o___conio_common_vcprintf -@ stub _o___conio_common_vcprintf_p -@ stub _o___conio_common_vcprintf_s -@ stub _o___conio_common_vcscanf -@ stub _o___conio_common_vcwprintf -@ stub _o___conio_common_vcwprintf_p -@ stub _o___conio_common_vcwprintf_s -@ stub _o___conio_common_vcwscanf -@ stub _o___daylight -@ stub _o___dstbias -@ stub _o___fpe_flt_rounds -@ stub _o___libm_sse2_acos -@ stub _o___libm_sse2_acosf -@ stub _o___libm_sse2_asin -@ stub _o___libm_sse2_asinf -@ stub _o___libm_sse2_atan -@ stub _o___libm_sse2_atan2 -@ stub _o___libm_sse2_atanf -@ stub _o___libm_sse2_cos -@ stub _o___libm_sse2_cosf -@ stub _o___libm_sse2_exp -@ stub _o___libm_sse2_expf -@ stub _o___libm_sse2_log -@ stub _o___libm_sse2_log10 -@ stub _o___libm_sse2_log10f -@ stub _o___libm_sse2_logf -@ stub _o___libm_sse2_pow -@ stub _o___libm_sse2_powf -@ stub _o___libm_sse2_sin -@ stub _o___libm_sse2_sinf -@ stub _o___libm_sse2_tan -@ stub _o___libm_sse2_tanf -@ stub _o___p___argc -@ stub _o___p___argv -@ stub _o___p___wargv -@ stub _o___p__acmdln -@ stub _o___p__commode -@ stub _o___p__environ -@ stub _o___p__fmode -@ stub _o___p__mbcasemap -@ stub _o___p__mbctype -@ stub _o___p__pgmptr -@ stub _o___p__wcmdln -@ stub _o___p__wenviron -@ stub _o___p__wpgmptr -@ stub _o___pctype_func -@ stub _o___pwctype_func -@ stub _o___stdio_common_vfprintf -@ stub _o___stdio_common_vfprintf_p -@ stub _o___stdio_common_vfprintf_s -@ stub _o___stdio_common_vfscanf -@ stub _o___stdio_common_vfwprintf -@ stub _o___stdio_common_vfwprintf_p -@ stub _o___stdio_common_vfwprintf_s -@ stub _o___stdio_common_vfwscanf -@ stub _o___stdio_common_vsnprintf_s -@ stub _o___stdio_common_vsnwprintf_s -@ stub _o___stdio_common_vsprintf -@ stub _o___stdio_common_vsprintf_p -@ stub _o___stdio_common_vsprintf_s -@ stub _o___stdio_common_vsscanf -@ stub _o___stdio_common_vswprintf -@ stub _o___stdio_common_vswprintf_p -@ stub _o___stdio_common_vswprintf_s -@ stub _o___stdio_common_vswscanf -@ stub _o___timezone -@ stub _o___tzname -@ stub _o___wcserror -@ stub _o__access -@ stub _o__access_s -@ stub _o__aligned_free -@ stub _o__aligned_malloc -@ stub _o__aligned_msize -@ stub _o__aligned_offset_malloc -@ stub _o__aligned_offset_realloc -@ stub _o__aligned_offset_recalloc -@ stub _o__aligned_realloc -@ stub _o__aligned_recalloc -@ stub _o__atodbl -@ stub _o__atodbl_l -@ stub _o__atof_l -@ stub _o__atoflt -@ stub _o__atoflt_l -@ stub _o__atoi64 -@ stub _o__atoi64_l -@ stub _o__atoi_l -@ stub _o__atol_l -@ stub _o__atoldbl -@ stub _o__atoldbl_l -@ stub _o__atoll_l -@ stub _o__beep -@ stub _o__beginthread -@ stub _o__beginthreadex -@ stub _o__cabs -@ stub _o__callnewh -@ stub _o__calloc_base -@ stub _o__cgets -@ stub _o__cgets_s -@ stub _o__cgetws -@ stub _o__cgetws_s -@ stub _o__chdir -@ stub _o__chdrive -@ stub _o__chmod -@ stub _o__chsize -@ stub _o__chsize_s -@ stub _o__close -@ stub _o__commit -@ stub _o__configure_wide_argv -@ stub _o__cputs -@ stub _o__cputws -@ stub _o__creat -@ stub _o__create_locale -@ stub _o__ctime32_s -@ stub _o__ctime64_s -@ stub _o__cwait -@ stub _o__d_int -@ stub _o__dclass -@ stub _o__difftime32 -@ stub _o__difftime64 -@ stub _o__dlog -@ stub _o__dnorm -@ stub _o__dpcomp -@ stub _o__dpoly -@ stub _o__dscale -@ stub _o__dsign -@ stub _o__dsin -@ stub _o__dtest -@ stub _o__dunscale -@ stub _o__dup -@ stub _o__dup2 -@ stub _o__dupenv_s -@ stub _o__ecvt -@ stub _o__ecvt_s -@ stub _o__endthread -@ stub _o__endthreadex -@ stub _o__eof -@ stub _o__errno -@ stub _o__except1 -@ stub _o__execute_onexit_table -@ stub _o__execv -@ stub _o__execve -@ stub _o__execvp -@ stub _o__execvpe -@ stub _o__expand -@ stub _o__fclose_nolock -@ stub _o__fcloseall -@ stub _o__fcvt -@ stub _o__fcvt_s -@ stub _o__fd_int -@ stub _o__fdclass -@ stub _o__fdexp -@ stub _o__fdlog -@ stub _o__fdopen -@ stub _o__fdpcomp -@ stub _o__fdpoly -@ stub _o__fdscale -@ stub _o__fdsign -@ stub _o__fdsin -@ stub _o__fflush_nolock -@ stub _o__fgetc_nolock -@ stub _o__fgetchar -@ stub _o__fgetwc_nolock -@ stub _o__fgetwchar -@ stub _o__filelength -@ stub _o__filelengthi64 -@ stub _o__fileno -@ stub _o__findclose -@ stub _o__findfirst32 -@ stub _o__findfirst32i64 -@ stub _o__findfirst64 -@ stub _o__findfirst64i32 -@ stub _o__findnext32 -@ stub _o__findnext32i64 -@ stub _o__findnext64 -@ stub _o__findnext64i32 -@ stub _o__flushall -@ stub _o__fpclass -@ stub _o__fpclassf -@ stub _o__fputc_nolock -@ stub _o__fputchar -@ stub _o__fputwc_nolock -@ stub _o__fputwchar -@ stub _o__fread_nolock -@ stub _o__fread_nolock_s -@ stub _o__free_base -@ stub _o__free_locale -@ stub _o__fseek_nolock -@ stub _o__fseeki64 -@ stub _o__fseeki64_nolock -@ stub _o__fsopen -@ stub _o__fstat32 -@ stub _o__fstat32i64 -@ stub _o__fstat64 -@ stub _o__fstat64i32 -@ stub _o__ftell_nolock -@ stub _o__ftelli64 -@ stub _o__ftelli64_nolock -@ stub _o__ftime32 -@ stub _o__ftime32_s -@ stub _o__ftime64 -@ stub _o__ftime64_s -@ stub _o__fullpath -@ stub _o__futime32 -@ stub _o__futime64 -@ stub _o__fwrite_nolock -@ stub _o__gcvt -@ stub _o__gcvt_s -@ stub _o__get_daylight -@ stub _o__get_doserrno -@ stub _o__get_dstbias -@ stub _o__get_errno -@ stub _o__get_fmode -@ stub _o__get_heap_handle -@ stub _o__get_invalid_parameter_handler -@ stub _o__get_narrow_winmain_command_line -@ stub _o__get_osfhandle -@ stub _o__get_pgmptr -@ stub _o__get_stream_buffer_pointers -@ stub _o__get_terminate -@ stub _o__get_thread_local_invalid_parameter_handler -@ stub _o__get_timezone -@ stub _o__get_tzname -@ stub _o__get_wide_winmain_command_line -@ stub _o__get_wpgmptr -@ stub _o__getc_nolock -@ stub _o__getch -@ stub _o__getch_nolock -@ stub _o__getche -@ stub _o__getche_nolock -@ stub _o__getcwd -@ stub _o__getdcwd -@ stub _o__getdiskfree -@ stub _o__getdllprocaddr -@ stub _o__getdrive -@ stub _o__getdrives -@ stub _o__getmbcp -@ stub _o__getsystime -@ stub _o__getw -@ stub _o__getwc_nolock -@ stub _o__getwch -@ stub _o__getwch_nolock -@ stub _o__getwche -@ stub _o__getwche_nolock -@ stub _o__getws -@ stub _o__getws_s -@ stub _o__gmtime32 -@ stub _o__gmtime32_s -@ stub _o__gmtime64 -@ stub _o__gmtime64_s -@ stub _o__heapchk -@ stub _o__heapmin -@ stub _o__hypot -@ stub _o__hypotf -@ stub _o__i64toa -@ stub _o__i64toa_s -@ stub _o__i64tow -@ stub _o__i64tow_s -@ stub _o__initialize_onexit_table -@ stub _o__invalid_parameter_noinfo -@ stub _o__invalid_parameter_noinfo_noreturn -@ stub _o__isatty -@ stub _o__isctype -@ stub _o__isctype_l -@ stub _o__isleadbyte_l -@ stub _o__ismbbalnum -@ stub _o__ismbbalnum_l -@ stub _o__ismbbalpha -@ stub _o__ismbbalpha_l -@ stub _o__ismbbblank -@ stub _o__ismbbblank_l -@ stub _o__ismbbgraph -@ stub _o__ismbbgraph_l -@ stub _o__ismbbkalnum -@ stub _o__ismbbkalnum_l -@ stub _o__ismbbkana -@ stub _o__ismbbkana_l -@ stub _o__ismbbkprint -@ stub _o__ismbbkprint_l -@ stub _o__ismbbkpunct -@ stub _o__ismbbkpunct_l -@ stub _o__ismbblead -@ stub _o__ismbblead_l -@ stub _o__ismbbprint -@ stub _o__ismbbprint_l -@ stub _o__ismbbpunct -@ stub _o__ismbbpunct_l -@ stub _o__ismbbtrail -@ stub _o__ismbbtrail_l -@ stub _o__ismbcalnum -@ stub _o__ismbcalnum_l -@ stub _o__ismbcalpha -@ stub _o__ismbcalpha_l -@ stub _o__ismbcblank -@ stub _o__ismbcblank_l -@ stub _o__ismbcdigit -@ stub _o__ismbcdigit_l -@ stub _o__ismbcgraph -@ stub _o__ismbcgraph_l -@ stub _o__ismbchira -@ stub _o__ismbchira_l -@ stub _o__ismbckata -@ stub _o__ismbckata_l -@ stub _o__ismbcl0 -@ stub _o__ismbcl0_l -@ stub _o__ismbcl1 -@ stub _o__ismbcl1_l -@ stub _o__ismbcl2 -@ stub _o__ismbcl2_l -@ stub _o__ismbclegal -@ stub _o__ismbclegal_l -@ stub _o__ismbclower -@ stub _o__ismbclower_l -@ stub _o__ismbcprint -@ stub _o__ismbcprint_l -@ stub _o__ismbcpunct -@ stub _o__ismbcpunct_l -@ stub _o__ismbcspace -@ stub _o__ismbcspace_l -@ stub _o__ismbcsymbol -@ stub _o__ismbcsymbol_l -@ stub _o__ismbcupper -@ stub _o__ismbcupper_l -@ stub _o__ismbslead -@ stub _o__ismbslead_l -@ stub _o__ismbstrail -@ stub _o__ismbstrail_l -@ stub _o__iswctype_l -@ stub _o__itoa -@ stub _o__itoa_s -@ stub _o__itow -@ stub _o__itow_s -@ stub _o__j0 -@ stub _o__j1 -@ stub _o__jn -@ stub _o__kbhit -@ stub _o__ld_int -@ stub _o__ldclass -@ stub _o__ldexp -@ stub _o__ldlog -@ stub _o__ldpcomp -@ stub _o__ldpoly -@ stub _o__ldscale -@ stub _o__ldsign -@ stub _o__ldsin -@ stub _o__ldtest -@ stub _o__ldunscale -@ stub _o__lfind -@ stub _o__lfind_s -@ stub _o__libm_sse2_acos_precise -@ stub _o__libm_sse2_asin_precise -@ stub _o__libm_sse2_atan_precise -@ stub _o__libm_sse2_cos_precise -@ stub _o__libm_sse2_exp_precise -@ stub _o__libm_sse2_log10_precise -@ stub _o__libm_sse2_log_precise -@ stub _o__libm_sse2_pow_precise -@ stub _o__libm_sse2_sin_precise -@ stub _o__libm_sse2_sqrt_precise -@ stub _o__libm_sse2_tan_precise -@ stub _o__loaddll -@ stub _o__localtime32 -@ stub _o__localtime32_s -@ stub _o__localtime64 -@ stub _o__localtime64_s -@ stub _o__lock_file -@ stub _o__locking -@ stub _o__logb -@ stub _o__logbf -@ stub _o__lsearch -@ stub _o__lsearch_s -@ stub _o__lseek -@ stub _o__lseeki64 -@ stub _o__ltoa -@ stub _o__ltoa_s -@ stub _o__ltow -@ stub _o__ltow_s -@ stub _o__makepath -@ stub _o__makepath_s -@ stub _o__malloc_base -@ stub _o__mbbtombc -@ stub _o__mbbtombc_l -@ stub _o__mbbtype -@ stub _o__mbbtype_l -@ stub _o__mbccpy -@ stub _o__mbccpy_l -@ stub _o__mbccpy_s -@ stub _o__mbccpy_s_l -@ stub _o__mbcjistojms -@ stub _o__mbcjistojms_l -@ stub _o__mbcjmstojis -@ stub _o__mbcjmstojis_l -@ stub _o__mbclen -@ stub _o__mbclen_l -@ stub _o__mbctohira -@ stub _o__mbctohira_l -@ stub _o__mbctokata -@ stub _o__mbctokata_l -@ stub _o__mbctolower -@ stub _o__mbctolower_l -@ stub _o__mbctombb -@ stub _o__mbctombb_l -@ stub _o__mbctoupper -@ stub _o__mbctoupper_l -@ stub _o__mblen_l -@ stub _o__mbsbtype -@ stub _o__mbsbtype_l -@ stub _o__mbscat_s -@ stub _o__mbscat_s_l -@ stub _o__mbschr -@ stub _o__mbschr_l -@ stub _o__mbscmp -@ stub _o__mbscmp_l -@ stub _o__mbscoll -@ stub _o__mbscoll_l -@ stub _o__mbscpy_s -@ stub _o__mbscpy_s_l -@ stub _o__mbscspn -@ stub _o__mbscspn_l -@ stub _o__mbsdec -@ stub _o__mbsdec_l -@ stub _o__mbsicmp -@ stub _o__mbsicmp_l -@ stub _o__mbsicoll -@ stub _o__mbsicoll_l -@ stub _o__mbsinc -@ stub _o__mbsinc_l -@ stub _o__mbslen -@ stub _o__mbslen_l -@ stub _o__mbslwr -@ stub _o__mbslwr_l -@ stub _o__mbslwr_s -@ stub _o__mbslwr_s_l -@ stub _o__mbsnbcat -@ stub _o__mbsnbcat_l -@ stub _o__mbsnbcat_s -@ stub _o__mbsnbcat_s_l -@ stub _o__mbsnbcmp -@ stub _o__mbsnbcmp_l -@ stub _o__mbsnbcnt -@ stub _o__mbsnbcnt_l -@ stub _o__mbsnbcoll -@ stub _o__mbsnbcoll_l -@ stub _o__mbsnbcpy -@ stub _o__mbsnbcpy_l -@ stub _o__mbsnbcpy_s -@ stub _o__mbsnbcpy_s_l -@ stub _o__mbsnbicmp -@ stub _o__mbsnbicmp_l -@ stub _o__mbsnbicoll -@ stub _o__mbsnbicoll_l -@ stub _o__mbsnbset -@ stub _o__mbsnbset_l -@ stub _o__mbsnbset_s -@ stub _o__mbsnbset_s_l -@ stub _o__mbsncat -@ stub _o__mbsncat_l -@ stub _o__mbsncat_s -@ stub _o__mbsncat_s_l -@ stub _o__mbsnccnt -@ stub _o__mbsnccnt_l -@ stub _o__mbsncmp -@ stub _o__mbsncmp_l -@ stub _o__mbsncoll -@ stub _o__mbsncoll_l -@ stub _o__mbsncpy -@ stub _o__mbsncpy_l -@ stub _o__mbsncpy_s -@ stub _o__mbsncpy_s_l -@ stub _o__mbsnextc -@ stub _o__mbsnextc_l -@ stub _o__mbsnicmp -@ stub _o__mbsnicmp_l -@ stub _o__mbsnicoll -@ stub _o__mbsnicoll_l -@ stub _o__mbsninc -@ stub _o__mbsninc_l -@ stub _o__mbsnlen -@ stub _o__mbsnlen_l -@ stub _o__mbsnset -@ stub _o__mbsnset_l -@ stub _o__mbsnset_s -@ stub _o__mbsnset_s_l -@ stub _o__mbspbrk -@ stub _o__mbspbrk_l -@ stub _o__mbsrchr -@ stub _o__mbsrchr_l -@ stub _o__mbsrev -@ stub _o__mbsrev_l -@ stub _o__mbsset -@ stub _o__mbsset_l -@ stub _o__mbsset_s -@ stub _o__mbsset_s_l -@ stub _o__mbsspn -@ stub _o__mbsspn_l -@ stub _o__mbsspnp -@ stub _o__mbsspnp_l -@ stub _o__mbsstr -@ stub _o__mbsstr_l -@ stub _o__mbstok -@ stub _o__mbstok_l -@ stub _o__mbstok_s -@ stub _o__mbstok_s_l -@ stub _o__mbstowcs_l -@ stub _o__mbstowcs_s_l -@ stub _o__mbstrlen -@ stub _o__mbstrlen_l -@ stub _o__mbstrnlen -@ stub _o__mbstrnlen_l -@ stub _o__mbsupr -@ stub _o__mbsupr_l -@ stub _o__mbsupr_s -@ stub _o__mbsupr_s_l -@ stub _o__mbtowc_l -@ stub _o__memicmp -@ stub _o__memicmp_l -@ stub _o__mkdir -@ stub _o__mkgmtime32 -@ stub _o__mkgmtime64 -@ stub _o__mktemp -@ stub _o__mktemp_s -@ stub _o__mktime32 -@ stub _o__mktime64 -@ stub _o__msize -@ stub _o__nextafter -@ stub _o__nextafterf -@ stub _o__open_osfhandle -@ stub _o__pclose -@ stub _o__pipe -@ stub _o__popen -@ stub _o__putc_nolock -@ stub _o__putch -@ stub _o__putch_nolock -@ stub _o__putenv -@ stub _o__putenv_s -@ stub _o__putw -@ stub _o__putwc_nolock -@ stub _o__putwch -@ stub _o__putwch_nolock -@ stub _o__putws -@ stub _o__read -@ stub _o__realloc_base -@ stub _o__recalloc -@ stub _o__register_onexit_function -@ stub _o__resetstkoflw -@ stub _o__rmdir -@ stub _o__rmtmp -@ stub _o__scalb -@ stub _o__scalbf -@ stub _o__searchenv -@ stub _o__searchenv_s -@ stub _o__set_abort_behavior -@ stub _o__set_doserrno -@ stub _o__set_errno -@ stub _o__set_invalid_parameter_handler -@ stub _o__set_new_handler -@ stub _o__set_new_mode -@ stub _o__set_thread_local_invalid_parameter_handler -@ stub _o__seterrormode -@ stub _o__setmbcp -@ stub _o__setmode -@ stub _o__setsystime -@ stub _o__sleep -@ stub _o__sopen -@ stub _o__sopen_dispatch -@ stub _o__sopen_s -@ stub _o__spawnv -@ stub _o__spawnve -@ stub _o__spawnvp -@ stub _o__spawnvpe -@ stub _o__splitpath -@ stub _o__splitpath_s -@ stub _o__stat32 -@ stub _o__stat32i64 -@ stub _o__stat64 -@ stub _o__stat64i32 -@ stub _o__strcoll_l -@ stub _o__strdate -@ stub _o__strdate_s -@ stub _o__strdup -@ stub _o__strerror -@ stub _o__strerror_s -@ stub _o__strftime_l -@ stub _o__stricmp -@ stub _o__stricmp_l -@ stub _o__stricoll -@ stub _o__stricoll_l -@ stub _o__strlwr -@ stub _o__strlwr_l -@ stub _o__strlwr_s -@ stub _o__strlwr_s_l -@ stub _o__strncoll -@ stub _o__strncoll_l -@ stub _o__strnicmp -@ stub _o__strnicmp_l -@ stub _o__strnicoll -@ stub _o__strnicoll_l -@ stub _o__strnset_s -@ stub _o__strset_s -@ stub _o__strtime -@ stub _o__strtime_s -@ stub _o__strtod_l -@ stub _o__strtof_l -@ stub _o__strtoi64 -@ stub _o__strtoi64_l -@ stub _o__strtol_l -@ stub _o__strtold_l -@ stub _o__strtoll_l -@ stub _o__strtoui64 -@ stub _o__strtoui64_l -@ stub _o__strtoul_l -@ stub _o__strtoull_l -@ stub _o__strupr -@ stub _o__strupr_l -@ stub _o__strupr_s -@ stub _o__strupr_s_l -@ stub _o__strxfrm_l -@ stub _o__swab -@ stub _o__tell -@ stub _o__telli64 -@ stub _o__timespec32_get -@ stub _o__timespec64_get -@ stub _o__tolower -@ stub _o__tolower_l -@ stub _o__toupper -@ stub _o__toupper_l -@ stub _o__towlower_l -@ stub _o__towupper_l -@ stub _o__tzset -@ stub _o__ui64toa -@ stub _o__ui64toa_s -@ stub _o__ui64tow -@ stub _o__ui64tow_s -@ stub _o__ultoa -@ stub _o__ultoa_s -@ stub _o__ultow -@ stub _o__ultow_s -@ stub _o__umask -@ stub _o__umask_s -@ stub _o__ungetc_nolock -@ stub _o__ungetch -@ stub _o__ungetch_nolock -@ stub _o__ungetwc_nolock -@ stub _o__ungetwch -@ stub _o__ungetwch_nolock -@ stub _o__unlink -@ stub _o__unloaddll -@ stub _o__unlock_file -@ stub _o__utime32 -@ stub _o__utime64 -@ stub _o__waccess -@ stub _o__waccess_s -@ stub _o__wasctime -@ stub _o__wasctime_s -@ stub _o__wchdir -@ stub _o__wchmod -@ stub _o__wcreat -@ stub _o__wcreate_locale -@ stub _o__wcscoll_l -@ stub _o__wcsdup -@ stub _o__wcserror -@ stub _o__wcserror_s -@ stub _o__wcsftime_l -@ stub _o__wcsicmp -@ stub _o__wcsicmp_l -@ stub _o__wcsicoll -@ stub _o__wcsicoll_l -@ stub _o__wcslwr -@ stub _o__wcslwr_l -@ stub _o__wcslwr_s -@ stub _o__wcslwr_s_l -@ stub _o__wcsncoll -@ stub _o__wcsncoll_l -@ stub _o__wcsnicmp -@ stub _o__wcsnicmp_l -@ stub _o__wcsnicoll -@ stub _o__wcsnicoll_l -@ stub _o__wcsnset -@ stub _o__wcsnset_s -@ stub _o__wcsset -@ stub _o__wcsset_s -@ stub _o__wcstod_l -@ stub _o__wcstof_l -@ stub _o__wcstoi64 -@ stub _o__wcstoi64_l -@ stub _o__wcstol_l -@ stub _o__wcstold_l -@ stub _o__wcstoll_l -@ stub _o__wcstombs_l -@ stub _o__wcstombs_s_l -@ stub _o__wcstoui64 -@ stub _o__wcstoui64_l -@ stub _o__wcstoul_l -@ stub _o__wcstoull_l -@ stub _o__wcsupr -@ stub _o__wcsupr_l -@ stub _o__wcsupr_s -@ stub _o__wcsupr_s_l -@ stub _o__wcsxfrm_l -@ stub _o__wctime32 -@ stub _o__wctime32_s -@ stub _o__wctime64 -@ stub _o__wctime64_s -@ stub _o__wctomb_l -@ stub _o__wctomb_s_l -@ stub _o__wdupenv_s -@ stub _o__wexecv -@ stub _o__wexecve -@ stub _o__wexecvp -@ stub _o__wexecvpe -@ stub _o__wfdopen -@ stub _o__wfindfirst32 -@ stub _o__wfindfirst32i64 -@ stub _o__wfindfirst64 -@ stub _o__wfindfirst64i32 -@ stub _o__wfindnext32 -@ stub _o__wfindnext32i64 -@ stub _o__wfindnext64 -@ stub _o__wfindnext64i32 -@ stub _o__wfopen -@ stub _o__wfopen_s -@ stub _o__wfreopen -@ stub _o__wfreopen_s -@ stub _o__wfsopen -@ stub _o__wfullpath -@ stub _o__wgetcwd -@ stub _o__wgetdcwd -@ stub _o__wgetenv -@ stub _o__wgetenv_s -@ stub _o__wmakepath -@ stub _o__wmakepath_s -@ stub _o__wmkdir -@ stub _o__wmktemp -@ stub _o__wmktemp_s -@ stub _o__wperror -@ stub _o__wpopen -@ stub _o__wputenv -@ stub _o__wputenv_s -@ stub _o__wremove -@ stub _o__wrename -@ stub _o__write -@ stub _o__wrmdir -@ stub _o__wsearchenv -@ stub _o__wsearchenv_s -@ stub _o__wsetlocale -@ stub _o__wsopen_dispatch -@ stub _o__wsopen_s -@ stub _o__wspawnv -@ stub _o__wspawnve -@ stub _o__wspawnvp -@ stub _o__wspawnvpe -@ stub _o__wsplitpath -@ stub _o__wsplitpath_s -@ stub _o__wstat32 -@ stub _o__wstat32i64 -@ stub _o__wstat64 -@ stub _o__wstat64i32 -@ stub _o__wstrdate -@ stub _o__wstrdate_s -@ stub _o__wstrtime -@ stub _o__wstrtime_s -@ stub _o__wsystem -@ stub _o__wtmpnam_s -@ stub _o__wtof -@ stub _o__wtof_l -@ stub _o__wtoi -@ stub _o__wtoi64 -@ stub _o__wtoi64_l -@ stub _o__wtoi_l -@ stub _o__wtol -@ stub _o__wtol_l -@ stub _o__wtoll -@ stub _o__wtoll_l -@ stub _o__wunlink -@ stub _o__wutime32 -@ stub _o__wutime64 -@ stub _o__y0 -@ stub _o__y1 -@ stub _o__yn -@ stub _o_abort -@ stub _o_acos -@ stub _o_acosf -@ stub _o_acosh -@ stub _o_acoshf -@ stub _o_acoshl -@ stub _o_asctime -@ stub _o_asctime_s -@ stub _o_asin -@ stub _o_asinf -@ stub _o_asinh -@ stub _o_asinhf -@ stub _o_asinhl -@ stub _o_atan -@ stub _o_atan2 -@ stub _o_atan2f -@ stub _o_atanf -@ stub _o_atanh -@ stub _o_atanhf -@ stub _o_atanhl -@ stub _o_atof -@ stub _o_atoi -@ stub _o_atol -@ stub _o_atoll -@ stub _o_bsearch -@ stub _o_bsearch_s -@ stub _o_btowc -@ stub _o_calloc -@ stub _o_cbrt -@ stub _o_cbrtf -@ stub _o_ceil -@ stub _o_ceilf -@ stub _o_clearerr -@ stub _o_clearerr_s -@ stub _o_cos -@ stub _o_cosf -@ stub _o_cosh -@ stub _o_coshf -@ stub _o_erf -@ stub _o_erfc -@ stub _o_erfcf -@ stub _o_erfcl -@ stub _o_erff -@ stub _o_erfl -@ stub _o_exp -@ stub _o_exp2 -@ stub _o_exp2f -@ stub _o_exp2l -@ stub _o_expf -@ stub _o_fabs -@ stub _o_fclose -@ stub _o_feof -@ stub _o_ferror -@ stub _o_fflush -@ stub _o_fgetc -@ stub _o_fgetpos -@ stub _o_fgets -@ stub _o_fgetwc -@ stub _o_fgetws -@ stub _o_floor -@ stub _o_floorf -@ stub _o_fma -@ stub _o_fmaf -@ stub _o_fmal -@ stub _o_fmod -@ stub _o_fmodf -@ stub _o_fopen -@ stub _o_fopen_s -@ stub _o_fputc -@ stub _o_fputs -@ stub _o_fputwc -@ stub _o_fputws -@ stub _o_fread -@ stub _o_fread_s -@ stub _o_free -@ stub _o_freopen -@ stub _o_freopen_s -@ stub _o_frexp -@ stub _o_fseek -@ stub _o_fsetpos -@ stub _o_ftell -@ stub _o_fwrite -@ stub _o_getc -@ stub _o_getchar -@ stub _o_getenv -@ stub _o_getenv_s -@ stub _o_gets -@ stub _o_gets_s -@ stub _o_getwc -@ stub _o_getwchar -@ stub _o_hypot -@ stub _o_is_wctype -@ stub _o_isalnum -@ stub _o_isalpha -@ stub _o_isblank -@ stub _o_iscntrl -@ stub _o_isdigit -@ stub _o_isgraph -@ stub _o_isleadbyte -@ stub _o_islower -@ stub _o_isprint -@ stub _o_ispunct -@ stub _o_isspace -@ stub _o_isupper -@ stub _o_iswalnum -@ stub _o_iswalpha -@ stub _o_iswascii -@ stub _o_iswblank -@ stub _o_iswcntrl -@ stub _o_iswctype -@ stub _o_iswdigit -@ stub _o_iswgraph -@ stub _o_iswlower -@ stub _o_iswprint -@ stub _o_iswpunct -@ stub _o_iswspace -@ stub _o_iswupper -@ stub _o_iswxdigit -@ stub _o_isxdigit -@ stub _o_ldexp -@ stub _o_lgamma -@ stub _o_lgammaf -@ stub _o_lgammal -@ stub _o_llrint -@ stub _o_llrintf -@ stub _o_llrintl -@ stub _o_llround -@ stub _o_llroundf -@ stub _o_llroundl -@ stub _o_localeconv -@ stub _o_log -@ stub _o_log10 -@ stub _o_log10f -@ stub _o_log1p -@ stub _o_log1pf -@ stub _o_log1pl -@ stub _o_log2 -@ stub _o_log2f -@ stub _o_log2l -@ stub _o_logb -@ stub _o_logbf -@ stub _o_logbl -@ stub _o_logf -@ stub _o_lrint -@ stub _o_lrintf -@ stub _o_lrintl -@ stub _o_lround -@ stub _o_lroundf -@ stub _o_lroundl -@ stub _o_malloc -@ stub _o_mblen -@ stub _o_mbrlen -@ stub _o_mbrtoc16 -@ stub _o_mbrtoc32 -@ stub _o_mbrtowc -@ stub _o_mbsrtowcs -@ stub _o_mbsrtowcs_s -@ stub _o_mbstowcs -@ stub _o_mbstowcs_s -@ stub _o_mbtowc -@ stub _o_memset -@ stub _o_modf -@ stub _o_modff -@ stub _o_nan -@ stub _o_nanf -@ stub _o_nanl -@ stub _o_nearbyint -@ stub _o_nearbyintf -@ stub _o_nearbyintl -@ stub _o_nextafter -@ stub _o_nextafterf -@ stub _o_nextafterl -@ stub _o_nexttoward -@ stub _o_nexttowardf -@ stub _o_nexttowardl -@ stub _o_pow -@ stub _o_powf -@ stub _o_putc -@ stub _o_putchar -@ stub _o_puts -@ stub _o_putwc -@ stub _o_putwchar -@ stub _o_qsort -@ stub _o_qsort_s -@ stub _o_raise -@ stub _o_rand -@ stub _o_rand_s -@ stub _o_realloc -@ stub _o_remainder -@ stub _o_remainderf -@ stub _o_remainderl -@ stub _o_remove -@ stub _o_remquo -@ stub _o_remquof -@ stub _o_remquol -@ stub _o_rewind -@ stub _o_rint -@ stub _o_rintf -@ stub _o_rintl -@ stub _o_round -@ stub _o_roundf -@ stub _o_roundl -@ stub _o_scalbln -@ stub _o_scalblnf -@ stub _o_scalblnl -@ stub _o_scalbn -@ stub _o_scalbnf -@ stub _o_scalbnl -@ stub _o_set_terminate -@ stub _o_setbuf -@ stub _o_setvbuf -@ stub _o_sin -@ stub _o_sinf -@ stub _o_sinh -@ stub _o_sinhf -@ stub _o_sqrt -@ stub _o_sqrtf -@ stub _o_srand -@ stub _o_strcat_s -@ stub _o_strcoll -@ stub _o_strcpy_s -@ stub _o_strerror -@ stub _o_strerror_s -@ stub _o_strftime -@ stub _o_strncat_s -@ stub _o_strncpy_s -@ stub _o_strtod -@ stub _o_strtof -@ stub _o_strtok -@ stub _o_strtok_s -@ stub _o_strtol -@ stub _o_strtold -@ stub _o_strtoll -@ stub _o_strtoul -@ stub _o_strtoull -@ stub _o_system -@ stub _o_tan -@ stub _o_tanf -@ stub _o_tanh -@ stub _o_tanhf -@ stub _o_terminate -@ stub _o_tgamma -@ stub _o_tgammaf -@ stub _o_tgammal -@ stub _o_tmpfile_s -@ stub _o_tmpnam_s -@ stub _o_tolower -@ stub _o_toupper -@ stub _o_towlower -@ stub _o_towupper -@ stub _o_ungetc -@ stub _o_ungetwc -@ stub _o_wcrtomb -@ stub _o_wcrtomb_s -@ stub _o_wcscat_s -@ stub _o_wcscoll -@ stub _o_wcscpy -@ stub _o_wcscpy_s -@ stub _o_wcsftime -@ stub _o_wcsncat_s -@ stub _o_wcsncpy_s -@ stub _o_wcsrtombs -@ stub _o_wcsrtombs_s -@ stub _o_wcstod -@ stub _o_wcstof -@ stub _o_wcstok -@ stub _o_wcstok_s -@ stub _o_wcstol -@ stub _o_wcstold -@ stub _o_wcstoll -@ stub _o_wcstombs -@ stub _o_wcstombs_s -@ stub _o_wcstoul -@ stub _o_wcstoull -@ stub _o_wctob -@ stub _o_wctomb -@ stub _o_wctomb_s -@ stub _o_wmemcpy_s -@ stub _o_wmemmove_s -@ cdecl _purecall() ucrtbase._purecall -@ stdcall -arch=i386 _seh_longjmp_unwind(ptr) ucrtbase._seh_longjmp_unwind -@ stdcall -arch=i386 _seh_longjmp_unwind4(ptr) ucrtbase._seh_longjmp_unwind4 -@ cdecl _set_purecall_handler(ptr) ucrtbase._set_purecall_handler -@ cdecl _set_se_translator(ptr) ucrtbase._set_se_translator -@ cdecl -arch=i386 -norelay _setjmp3(ptr long) ucrtbase._setjmp3 -@ cdecl -arch=i386,x86_64,arm longjmp(ptr long) ucrtbase.longjmp -@ cdecl memchr(ptr long long) ucrtbase.memchr -@ cdecl memcmp(ptr ptr long) ucrtbase.memcmp -@ cdecl memcpy(ptr ptr long) ucrtbase.memcpy -@ cdecl memmove(ptr ptr long) ucrtbase.memmove -@ cdecl set_unexpected(ptr) ucrtbase.set_unexpected -@ cdecl -norelay -private setjmp(ptr) ucrtbase.setjmp -@ cdecl strchr(str long) ucrtbase.strchr -@ cdecl strrchr(str long) ucrtbase.strrchr -@ cdecl strstr(str str) ucrtbase.strstr -@ stub unexpected -@ cdecl wcschr(wstr long) ucrtbase.wcschr -@ cdecl wcsrchr(wstr long) ucrtbase.wcsrchr -@ cdecl wcsstr(wstr wstr) ucrtbase.wcsstr diff --git a/wrappers/api-sets/api-ms-win-downlevel-shlwapi-l2-1-0.spec b/wrappers/api-sets/api-ms-win-downlevel-shlwapi-l2-1-0.spec index 63e9fd8af4..eca5197c35 100644 --- a/wrappers/api-sets/api-ms-win-downlevel-shlwapi-l2-1-0.spec +++ b/wrappers/api-sets/api-ms-win-downlevel-shlwapi-l2-1-0.spec @@ -1,10 +1,10 @@ -@ stub IStream_Copy ;(ptr ptr long) shlwapi.IStream_Copy +@ stdcall IStream_Copy(ptr ptr long) shlwapi.IStream_Copy @ stdcall IStream_Read(ptr ptr long) shlwapi.IStream_Read -@ stub IStream_ReadStr ;(ptr wstr) shlwapi.IStream_ReadStr +@ stdcall IStream_ReadStr(ptr wstr) shlwapi.IStream_ReadStr @ stdcall IStream_Reset(ptr) shlwapi.IStream_Reset @ stdcall IStream_Size(ptr ptr) shlwapi.IStream_Size @ stdcall IStream_Write(ptr ptr long) shlwapi.IStream_Write -@ stub IStream_WriteStr ;(ptr wstr) shlwapi.IStream_WriteStr +@ stdcall IStream_WriteStr(ptr wstr) shlwapi.IStream_WriteStr @ stdcall IUnknown_AtomicRelease(long) shlwapi.IUnknown_AtomicRelease @ stdcall IUnknown_GetSite(ptr ptr ptr) shlwapi.IUnknown_GetSite @ stdcall IUnknown_QueryService(ptr ptr ptr ptr) shlwapi.IUnknown_QueryService diff --git a/wrappers/api-sets/api-ms-win-dx-d3dkmt-l1-1-0.spec b/wrappers/api-sets/api-ms-win-dx-d3dkmt-l1-1-0.spec index 15a2d1dedd..9967066771 100644 --- a/wrappers/api-sets/api-ms-win-dx-d3dkmt-l1-1-0.spec +++ b/wrappers/api-sets/api-ms-win-dx-d3dkmt-l1-1-0.spec @@ -1,60 +1,60 @@ -@ stub D3DKMTAcquireKeyedMutex +@ stdcall D3DKMTAcquireKeyedMutex(ptr) d3dkmt.D3DKMTAcquireKeyedMutex @ stub D3DKMTAcquireKeyedMutex2 @ stub D3DKMTCacheHybridQueryValue @ stub D3DKMTCheckExclusiveOwnership -@ stub D3DKMTCheckMonitorPowerState +@ stdcall D3DKMTCheckMonitorPowerState(ptr) gdi32.D3DKMTCheckMonitorPowerState @ stub D3DKMTCheckOcclusion -@ stub D3DKMTCheckSharedResourceAccess -@ stub D3DKMTCheckVidPnExclusiveOwnership -@ stub D3DKMTCloseAdapter -@ stub D3DKMTConfigureSharedResource -@ stub D3DKMTCreateAllocation -@ stub D3DKMTCreateAllocation2 -@ stub D3DKMTCreateContext +@ stdcall D3DKMTCheckSharedResourceAccess(ptr) gdi32.D3DKMTCheckSharedResourceAccess +@ stdcall D3DKMTCheckVidPnExclusiveOwnership(ptr) gdi32.D3DKMTCheckVidPnExclusiveOwnership +@ stdcall D3DKMTCloseAdapter(ptr) d3dkmt.D3DKMTCloseAdapter +@ stdcall D3DKMTConfigureSharedResource(ptr) d3dkmt.D3DKMTConfigureSharedResource +@ stdcall D3DKMTCreateAllocation(ptr) d3dkmt.D3DKMTCreateAllocation +@ stdcall D3DKMTCreateAllocation2(ptr) d3dkmt.D3DKMTCreateAllocation2 +@ stdcall D3DKMTCreateContext(ptr) d3dkmt.D3DKMTCreateContext @ stdcall D3DKMTCreateDCFromMemory(ptr) gdi32.D3DKMTCreateDCFromMemory -@ stub D3DKMTCreateDevice +@ stdcall D3DKMTCreateDevice(ptr) d3dkmt.D3DKMTCreateDevice @ stub D3DKMTCreateKeyedMutex @ stub D3DKMTCreateKeyedMutex2 @ stub D3DKMTCreateOutputDupl @ stub D3DKMTCreateOverlay -@ stub D3DKMTCreateSynchronizationObject -@ stub D3DKMTCreateSynchronizationObject2 -@ stub D3DKMTDestroyAllocation -@ stub D3DKMTDestroyContext +@ stdcall D3DKMTCreateSynchronizationObject(ptr) d3dkmt.D3DKMTCreateSynchronizationObject +@ stdcall D3DKMTCreateSynchronizationObject2(ptr) d3dkmt.D3DKMTCreateSynchronizationObject2 +@ stdcall D3DKMTDestroyAllocation(ptr) d3dkmt.D3DKMTDestroyAllocation +@ stdcall D3DKMTDestroyContext(ptr) d3dkmt.D3DKMTDestroyContext @ stdcall D3DKMTDestroyDCFromMemory(ptr) gdi32.D3DKMTDestroyDCFromMemory -@ stub D3DKMTDestroyDevice -@ stub D3DKMTDestroyKeyedMutex +@ stdcall D3DKMTDestroyDevice(ptr) d3dkmt.D3DKMTDestroyDevice +@ stdcall D3DKMTDestroyKeyedMutex(ptr) d3dkmt.D3DKMTDestroyKeyedMutex @ stub D3DKMTDestroyOutputDupl @ stub D3DKMTDestroyOverlay -@ stub D3DKMTDestroySynchronizationObject +@ stdcall D3DKMTDestroySynchronizationObject(ptr) d3dkmt.D3DKMTDestroySynchronizationObject @ stdcall D3DKMTEscape(ptr) gdi32.D3DKMTEscape @ stub D3DKMTFlipOverlay @ stub D3DKMTGetCachedHybridQueryValue -@ stub D3DKMTGetContextSchedulingPriority -@ stub D3DKMTGetDeviceState -@ stub D3DKMTGetDisplayModeList -@ stub D3DKMTGetMultisampleMethodList +@ stdcall D3DKMTGetContextSchedulingPriority(ptr) d3dkmt.D3DKMTGetContextSchedulingPriority +@ stdcall D3DKMTGetDeviceState(ptr) d3dkmt.D3DKMTGetDeviceState +@ stdcall D3DKMTGetDisplayModeList(ptr) d3dkmt.D3DKMTGetDisplayModeList +@ stdcall D3DKMTGetMultisampleMethodList(ptr) d3dkmt.D3DKMTGetMultisampleMethodList @ stub D3DKMTGetOverlayState @ stub D3DKMTGetPresentHistory @ stub D3DKMTGetPresentQueueEvent @ stub D3DKMTGetProcessSchedulingPriorityClass -@ stub D3DKMTGetRuntimeData +@ stdcall D3DKMTGetRuntimeData(ptr) d3dkmt.D3DKMTGetRuntimeData @ stub D3DKMTGetScanLine -@ stub D3DKMTGetSharedPrimaryHandle +@ stdcall D3DKMTGetSharedPrimaryHandle(ptr) d3dkmt.D3DKMTGetSharedPrimaryHandle @ stub D3DKMTGetSharedResourceAdapterLuid @ stub D3DKMTInvalidateActiveVidPn -@ stub D3DKMTLock +@ stdcall D3DKMTLock(ptr) d3dkmt.D3DKMTLock @ stub D3DKMTOfferAllocations -@ stub D3DKMTOpenAdapterFromDeviceName -@ stub D3DKMTOpenAdapterFromGdiDisplayName +@ stdcall D3DKMTOpenAdapterFromDeviceName(ptr) d3dkmt.D3DKMTOpenAdapterFromDeviceName +@ stdcall D3DKMTOpenAdapterFromGdiDisplayName(ptr) d3dkmt.D3DKMTOpenAdapterFromGdiDisplayName @ stdcall D3DKMTOpenAdapterFromHdc(ptr) gdi32.D3DKMTOpenAdapterFromHdc -@ stub D3DKMTOpenKeyedMutex -@ stub D3DKMTOpenKeyedMutex2 +@ stdcall D3DKMTOpenKeyedMutex(ptr) gdi32.D3DKMTOpenKeyedMutex +;@ stdcall D3DKMTOpenKeyedMutex2(ptr) gdi32.D3DKMTOpenKeyedMutex2 @ stub D3DKMTOpenNtHandleFromName -@ stub D3DKMTOpenResource -@ stub D3DKMTOpenResource2 +@ stdcall D3DKMTOpenResource(ptr) d3dkmt.D3DKMTOpenResource +@ stdcall D3DKMTOpenResource2(ptr) d3dkmt.D3DKMTOpenResource2 @ stub D3DKMTOpenResourceFromNtHandle -@ stub D3DKMTOpenSynchronizationObject +@ stdcall D3DKMTOpenSynchronizationObject(ptr) d3dkmt.D3DKMTOpenSynchronizationObject @ stub D3DKMTOpenSyncObjectFromNtHandle @ stub D3DKMTOutputDuplGetFrameInfo @ stub D3DKMTOutputDuplGetMetaData @@ -62,36 +62,36 @@ @ stub D3DKMTOutputDuplPresent @ stub D3DKMTOutputDuplReleaseFrame @ stub D3DKMTPollDisplayChildren -@ stub D3DKMTPresent -@ stub D3DKMTQueryAdapterInfo -@ stub D3DKMTQueryAllocationResidency +@ stdcall D3DKMTPresent(ptr) d3dkmt.D3DKMTPresent +@ stdcall D3DKMTQueryAdapterInfo(ptr) d3dkmt.D3DKMTQueryAdapterInfo +@ stdcall D3DKMTQueryAllocationResidency(ptr) d3dkmt.D3DKMTQueryAllocationResidency @ stub D3DKMTQueryRemoteVidPnSourceFromGdiDisplayName @ stub D3DKMTQueryResourceInfo @ stub D3DKMTQueryResourceInfoFromNtHandle -@ stub D3DKMTQueryStatistics +@ stdcall D3DKMTQueryStatistics(ptr) gdi32.D3DKMTQueryStatistics @ stub D3DKMTReclaimAllocations -@ stub D3DKMTReleaseKeyedMutex +@ stdcall D3DKMTReleaseKeyedMutex(ptr) d3dkmt.D3DKMTReleaseKeyedMutex @ stub D3DKMTReleaseKeyedMutex2 @ stub D3DKMTReleaseProcessVidPnSourceOwners -@ stub D3DKMTRender -@ stub D3DKMTSetAllocationPriority -@ stub D3DKMTSetContextSchedulingPriority -@ stub D3DKMTSetDisplayMode -@ stub D3DKMTSetDisplayPrivateDriverFormat -@ stub D3DKMTSetGammaRamp -@ stub D3DKMTSetProcessSchedulingPriorityClass -@ stub D3DKMTSetQueuedLimit +@ stdcall D3DKMTRender(ptr) d3dkmt.D3DKMTRender +@ stdcall D3DKMTSetAllocationPriority(ptr) d3dkmt.D3DKMTSetAllocationPriority +@ stdcall D3DKMTSetContextSchedulingPriority(ptr) d3dkmt.D3DKMTSetContextSchedulingPriority +@ stdcall D3DKMTSetDisplayMode(ptr) d3dkmt.D3DKMTSetDisplayMode +@ stdcall D3DKMTSetDisplayPrivateDriverFormat(ptr) d3dkmt.D3DKMTSetDisplayPrivateDriverFormat +@ stdcall D3DKMTSetGammaRamp(ptr) d3dkmt.D3DKMTSetGammaRamp +@ stdcall D3DKMTSetProcessSchedulingPriorityClass(long long) gdi32.D3DKMTSetProcessSchedulingPriorityClass +@ stdcall D3DKMTSetQueuedLimit(ptr) gdi32.D3DKMTSetQueuedLimit @ stub D3DKMTSetStereoEnabled -@ stub D3DKMTSetVidPnSourceOwner +@ stdcall D3DKMTSetVidPnSourceOwner(ptr) d3dkmt.D3DKMTSetVidPnSourceOwner @ stub D3DKMTSharedPrimaryLockNotification @ stub D3DKMTSharedPrimaryUnLockNotification @ stub D3DKMTShareObjects -@ stub D3DKMTSignalSynchronizationObject -@ stub D3DKMTSignalSynchronizationObject2 -@ stub D3DKMTUnlock +@ stdcall D3DKMTSignalSynchronizationObject(ptr) d3dkmt.D3DKMTSignalSynchronizationObject +@ stdcall D3DKMTSignalSynchronizationObject2(ptr) d3dkmt.D3DKMTSignalSynchronizationObject2 +@ stdcall D3DKMTUnlock(ptr) d3dkmt.D3DKMTUnlock @ stub D3DKMTUpdateOverlay @ stub D3DKMTWaitForIdle -@ stub D3DKMTWaitForSynchronizationObject -@ stub D3DKMTWaitForSynchronizationObject2 -@ stub D3DKMTWaitForVerticalBlankEvent +@ stdcall D3DKMTWaitForSynchronizationObject(ptr) d3dkmt.D3DKMTWaitForSynchronizationObject +@ stdcall D3DKMTWaitForSynchronizationObject2(ptr) d3dkmt.D3DKMTWaitForSynchronizationObject2 +@ stdcall D3DKMTWaitForVerticalBlankEvent(ptr) d3dkmt.D3DKMTWaitForVerticalBlankEvent @ stdcall GdiEntry13() gdi32.GdiEntry13 diff --git a/wrappers/api-sets/api-ms-win-shcore-scaling-l1-1-1.spec b/wrappers/api-sets/api-ms-win-shcore-scaling-l1-1-1.spec index 6194c8ce9d..65feb052a3 100644 --- a/wrappers/api-sets/api-ms-win-shcore-scaling-l1-1-1.spec +++ b/wrappers/api-sets/api-ms-win-shcore-scaling-l1-1-1.spec @@ -1,9 +1,9 @@ @ stdcall GetDpiForMonitor(long long ptr ptr) shcore.GetDpiForMonitor @ stdcall GetProcessDpiAwareness(long ptr) shcore.GetProcessDpiAwareness -@ stub GetScaleFactorForDevice -@ stub GetScaleFactorForMonitor -@ stub RegisterScaleChangeEvent -@ stub RegisterScaleChangeNotifications +@ stdcall GetScaleFactorForDevice(long) shcore.GetScaleFactorForDevice +@ stdcall GetScaleFactorForMonitor(long ptr) shcore.GetScaleFactorForMonitor +@ stdcall RegisterScaleChangeEvent(ptr ptr) shcore.RegisterScaleChangeEvent +@ stdcall RegisterScaleChangeNotifications(long ptr long ptr) shcore.RegisterScaleChangeNotifications @ stub RevokeScaleChangeNotifications @ stdcall SetProcessDpiAwareness(long) shcore.SetProcessDpiAwareness @ stub UnregisterScaleChangeEvent diff --git a/wrappers/api-sets/api-ms-win-shcore-stream-l1-1-0.spec b/wrappers/api-sets/api-ms-win-shcore-stream-l1-1-0.spec index 1ee9dd335b..0115fd3faa 100644 --- a/wrappers/api-sets/api-ms-win-shcore-stream-l1-1-0.spec +++ b/wrappers/api-sets/api-ms-win-shcore-stream-l1-1-0.spec @@ -1,10 +1,10 @@ -@ stub IStream_Copy +@ stdcall IStream_Copy(ptr ptr long) shcore.IStream_Copy @ stdcall IStream_Read(ptr ptr long) shcore.IStream_Read -@ stub IStream_ReadStr +@ stdcall IStream_ReadStr(ptr wstr) shcore.IStream_ReadStr @ stdcall IStream_Reset(ptr) shcore.IStream_Reset @ stdcall IStream_Size(ptr ptr) shcore.IStream_Size @ stdcall IStream_Write(ptr ptr long) shcore.IStream_Write -@ stub IStream_WriteStr +@ stdcall IStream_WriteStr(ptr wstr) shcore.IStream_WriteStr @ stdcall SHCreateMemStream(ptr long) shcore.SHCreateMemStream @ stdcall SHCreateStreamOnFileA(str long ptr) shcore.SHCreateStreamOnFileA @ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) shcore.SHCreateStreamOnFileEx diff --git a/wrappers/api-sets/api-ms-win-shcore-thread-l1-1-0.spec b/wrappers/api-sets/api-ms-win-shcore-thread-l1-1-0.spec index 15330050de..0cbacc850a 100644 --- a/wrappers/api-sets/api-ms-win-shcore-thread-l1-1-0.spec +++ b/wrappers/api-sets/api-ms-win-shcore-thread-l1-1-0.spec @@ -1,8 +1,8 @@ -@ stub GetProcessReference +@ stdcall GetProcessReference(ptr) shcore.GetProcessReference @ stdcall SHCreateThread(ptr ptr long ptr) shcore.SHCreateThread @ stdcall SHCreateThreadRef(ptr ptr) shcore.SHCreateThreadRef @ stub SHCreateThreadWithHandle @ stdcall SHGetThreadRef(ptr) shcore.SHGetThreadRef @ stdcall SHReleaseThreadRef() shcore.SHReleaseThreadRef @ stdcall SHSetThreadRef(ptr) shcore.SHSetThreadRef -@ stub SetProcessReference +@ stdcall SetProcessReference(ptr) shcore.SetProcessReference diff --git a/wrappers/base/CMakeLists.txt b/wrappers/base/CMakeLists.txt index bd4ab8daa9..4aec3701f8 100644 --- a/wrappers/base/CMakeLists.txt +++ b/wrappers/base/CMakeLists.txt @@ -1,4 +1,5 @@ -#add_subdirectory(comdlg32_wrapper) +add_subdirectory(comdlg32_wrapper) +add_subdirectory(dwrite_wrapper) add_subdirectory(gdi32_wrapper) #add_subdirectory(iphlpapi_wrapper) #add_subdirectory(netapi32_wrapper) @@ -8,12 +9,12 @@ add_subdirectory(gdi32_wrapper) add_subdirectory(progwrp_wrapper) #add_subdirectory(rpcrt4_wrapper) #add_subdirectory(secur32_wrapper) -#add_subdirectory(setupapi_wrapper) +add_subdirectory(setupapi_wrapper) #add_subdirectory(shell32_wrapper) -#add_subdirectory(shlwapi_wrapper) +add_subdirectory(shlwapi_wrapper) #add_subdirectory(winsta_wrapper) #add_subdirectory(winttp_wrapper) -#add_subdirectory(ws2_32_wrapper) +add_subdirectory(ws2_32_wrapper) add_subdirectory(user32_wrapper) #add_subdirectory(userenv_wrapper) -#add_subdirectory(uxtheme_wrapper) \ No newline at end of file +add_subdirectory(uxtheme_wrapper) #For wow64 \ No newline at end of file diff --git a/wrappers/base/user32_wrapper/input.c b/wrappers/base/user32_wrapper/input.c index 58733c33c8..233ce782ec 100644 --- a/wrappers/base/user32_wrapper/input.c +++ b/wrappers/base/user32_wrapper/input.c @@ -29,4 +29,20 @@ BOOL WINAPI EnableMouseInPointer(BOOL enable) SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; -} \ No newline at end of file +} + +// HSYNTHETICPOINTERDEVICE WINAPI CreateSyntheticPointerDevice(POINTER_INPUT_TYPE type, ULONG max_count, POINTER_FEEDBACK_MODE mode) +// { + // FIXME( "type %ld, max_count %ld, mode %d stub!\n", type, max_count, mode); + // SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); + // return NULL; +// } + +// BOOL WINAPI InjectSyntheticPointerInput( + // HSYNTHETICPOINTERDEVICE device, + // const POINTER_TYPE_INFO *pointerInfo, + // UINT32 count +// ) +// { + // return FALSE; +// } diff --git a/wrappers/base/user32_wrapper/main.h b/wrappers/base/user32_wrapper/main.h index 0c7a2c98de..0e3bcbc9e1 100644 --- a/wrappers/base/user32_wrapper/main.h +++ b/wrappers/base/user32_wrapper/main.h @@ -102,6 +102,8 @@ typedef HANDLE HTOUCHINPUT; typedef HANDLE HGESTUREINFO; +DECLARE_HANDLE(HSYNTHETICPOINTERDEVICE); + typedef struct _PROCESSINFO *PPROCESSINFO; typedef struct _D3DMATRIX { diff --git a/wrappers/base/user32_wrapper/touch.c b/wrappers/base/user32_wrapper/touch.c index 30c92a612a..796838599b 100644 --- a/wrappers/base/user32_wrapper/touch.c +++ b/wrappers/base/user32_wrapper/touch.c @@ -90,58 +90,12 @@ BOOL WINAPI LockUMHandleList(PRTL_CRITICAL_SECTION CriticalSectionObject) BOOL WINAPI CloseTouchInputHandle(HTOUCHINPUT a1) { - BOOL result; // eax@2 - PBOOL v2; // eax@4 - PBOOL v3; // edi@4 - - if ( a1 ) - { - result = LockUMHandleList(&CriticalSectionObject); - if ( result ) - { - v2 = UMHandleActiveEntryFromHandle(CriticalSectionObject, a1); - v3 = v2; - if ( v2 ) - FreeUMHandleEntry(&CriticalSectionObject, v2); - else - SetLastError(6); - UnlockUMHandleList(&CriticalSectionObject); - result = v3 != FALSE; - } - } - else - { - result = FALSE; - } - return result; + return FALSE; } BOOL WINAPI CloseGestureInfoHandle(HGESTUREINFO hGestureInfo) { - BOOL result; // eax@2 - PBOOL hwnd; // eax@4 - PBOOL compare; // edi@4 - - if ( hGestureInfo ) - { - result = LockUMHandleList(&CriticalSectionObject); - if ( result ) - { - hwnd = UMHandleActiveEntryFromHandle(CriticalSectionObject, (HANDLE)(PBOOL)hGestureInfo); - compare = hwnd; - if ( hwnd ) - FreeUMHandleEntry(&CriticalSectionObject, hwnd); - else - SetLastError(6); - UnlockUMHandleList(&CriticalSectionObject); - result = compare != FALSE; - } - } - else - { - result = FALSE; - } - return result; + return FALSE; } BOOL WINAPI RegisterTouchWindow( @@ -240,17 +194,18 @@ BOOL WINAPI GetTouchInputInfo( _In_ int cbSize ) { - BOOL result; // eax@2 - if ( cbSize == 40 ) - { - result = GetTouchInputInfoWorker(hTouchInput, cInputs, pInputs, 0); - } - else - { - RtlSetLastWin32Error(87); - result = 0; - } - return result; + // BOOL result; // eax@2 + // if ( cbSize == 40 ) + // { + // result = GetTouchInputInfoWorker(hTouchInput, cInputs, pInputs, 0); + // } + // else + // { + // RtlSetLastWin32Error(87); + // result = 0; + // } + // return result; + return FALSE; } BOOL WINAPI IsTouchWindow( @@ -258,7 +213,8 @@ BOOL WINAPI IsTouchWindow( _Out_opt_ PULONG pulFlags ) { - DbgPrint("IsTouchWindow is UNIMPLEMENTED\n"); + DbgPrint("IsTouchWindow is UNIMPLEMENTED\n"); + SetLastError(0); return FALSE; } @@ -290,172 +246,6 @@ BOOL WINAPI PtInRect(const RECT *lprc, POINT pt) { return lprc && pt.x >= lprc->left && pt.x < lprc->right && pt.y >= lprc->top && pt.y < lprc->bottom; } -/* -__int32 WINAPI TouchTargetingCreateContact(const TOUCH_HIT_TESTING_INPUT *this, const RECT *lprc) -{ - POINT one; // ST04_8@1 - BOOL verification; // eax@1 - BOOLEAN compare; // zf@1 - LONG two; // edx@3 - LONG three; // edi@3 - __int32 result; // eax@3 - LONG eight; // esi@8 - LONG nine; // ecx@8 - int ten; // ST18_4@8 - int eleven; // ecx@8 - LONG twelven; // ST20_4@8 - LONG threeten; // ebx@8 - LONG v14; // eax@8 - LONG v15; // ST28_4@8 - LONG v16; // edi@8 - signed int v17; // eax@8 - int v18; // edx@8 - int v19; // ST2C_4@8 - LONG v20; // eax@8 - LONG v21; // edx@8 - __int32 v22; // eax@8 - LONG v23; // ebx@8 - LONG v24; // ecx@8 - LONG v25; // edx@8 - LONG v26; // eax@8 - LONG v27; // ecx@11 - LONG v28; // esi@11 - int v29; // ST18_4@11 - LONG v30; // edi@11 - LONG v31; // esi@11 - signed int v32; // kr00_4@11 - LONG v33; // ecx@11 - LONG v34; // ebx@11 - LONG v35; // ecx@11 - LONG v36; // ebx@11 - LONG v37; // ecx@12 - LONG v38; // [sp+10h] [bp-14h]@3 - RECT *v39; // [sp+18h] [bp-Ch]@1 - __int32 v40; // [sp+1Ch] [bp-8h]@3 - - lprc[2].left = this->point.x; - lprc[2].top = this->point.y; - lprc[11].top = 1; - lprc[2].right = this->orientation; - lprc[1].left = this->boundingBox.left; - lprc[1].top = this->boundingBox.top; - lprc[1].right = this->boundingBox.right; - lprc[1].bottom = this->boundingBox.bottom; - lprc->left = this->nonOccludedBoundingBox.left; - lprc->top = this->nonOccludedBoundingBox.top; - lprc->right = this->nonOccludedBoundingBox.right; - lprc->bottom = this->nonOccludedBoundingBox.bottom; - one.y = this->point.y; - v39 = (RECT *)&lprc[1]; - one.x = this->point.x; - verification = PtInRect(lprc, one); - compare = lprc[11].right == 0; - lprc[11].left = verification; - if ( compare ) - { - lprc[11].bottom = 26458; - lprc[11].right = 26458; - } - two = lprc[1].right; - three = v39->left; - result = lprc[1].right - v39->left; - lprc[2].bottom = 12; - v38 = two; - v40 = result; - if ( result < 4 || (result = lprc[1].bottom - lprc[1].top, result < 4) ) - lprc[2].bottom = 4; - switch ( lprc[2].bottom ) - { - case 4: - v37 = lprc[1].top; - result = lprc[1].bottom; - lprc[3].left = three; - lprc[3].top = v37; - lprc[3].right = three; - lprc[3].bottom = result; - lprc[4].left = two; - lprc[4].top = result; - lprc[4].right = two; - lprc[4].bottom = v37; - break; - case 8: - v27 = lprc[1].bottom; - v28 = lprc[1].top; - lprc[3].left = three; - lprc[3].top = (v28 + v27) / 2; - v29 = (v28 + v27) / 2; - v30 = 15 * v40 / 100 + three; - lprc[3].right = v30; - v31 = 15 * (v28 - v27) / 100 + v27; - lprc[3].bottom = v31; - v32 = two + v39->left; - lprc[4].top = v27; - v33 = v39->left; - v34 = lprc[1].right; - lprc[5].left = v34; - v35 = v34 + v33 - v30; - lprc[5].top = v29; - v36 = lprc[1].top; - lprc[4].bottom = v31; - lprc[4].left = v32 / 2; - lprc[4].right = v35; - lprc[5].right = v35; - result = lprc[1].bottom + v36 - v31; - lprc[6].left = v32 / 2; - lprc[5].bottom = result; - lprc[6].top = v36; - lprc[6].right = v30; - lprc[6].bottom = result; - break; - case 0xC: - eight = lprc[1].bottom; - nine = lprc[1].top; - lprc[3].top = (eight + nine) / 2; - ten = (eight + nine) / 2; - eleven = nine - eight; - lprc[3].left = three; - lprc[3].right = three + 7 * v40 / 100; - twelven = three + 7 * v40 / 100; - threeten = 25 * eleven / 100 + eight; - lprc[3].bottom = threeten; - v14 = lprc[1].left + 25 * v40 / 100; - lprc[4].left = v14; - v15 = v14; - v16 = 7 * eleven / 100 + lprc[1].bottom; - v17 = lprc[1].right + lprc[1].left; - lprc[4].top = v16; - lprc[4].bottom = lprc[1].bottom; - lprc[4].right = v17 / 2; - v18 = v39->left - v15; - v19 = v17 / 2; - v20 = v38 + v39->left - twelven; - lprc[5].right = v20; - v21 = v38 + v18; - lprc[5].bottom = threeten; - lprc[5].left = v21; - lprc[6].left = v38; - lprc[5].top = v16; - lprc[6].top = ten; - lprc[6].right = v20; - v22 = lprc[1].top - threeten; - v23 = lprc[1].bottom; - v24 = v22 + v23; - lprc[7].left = v21; - v25 = lprc[1].top; - lprc[6].bottom = v22 + v23; - v26 = v23 + v25 - v16; - lprc[7].top = v26; - lprc[7].bottom = v25; - lprc[8].top = v26; - result = twelven; - lprc[7].right = v19; - lprc[8].left = v15; - lprc[8].right = twelven; - lprc[8].bottom = v24; - break; - } - return result; -}*/ BOOL WINAPI _ValidatePointerTargetingInput(const TOUCH_HIT_TESTING_INPUT *testingInput) { @@ -477,15 +267,6 @@ BOOL WINAPI _ValidatePointerTargetingInput(const TOUCH_HIT_TESTING_INPUT *testin && testingInput->boundingBox.top <= testingInput->nonOccludedBoundingBox.top && testingInput->boundingBox.bottom >= testingInput->nonOccludedBoundingBox.bottom; } -/* -BOOL WINAPI EvaluateProximityToRect( - _In_ const RECT *controlBoundingBox, - _In_ const TOUCH_HIT_TESTING_INPUT *pHitTestingInput, - _Out_ TOUCH_HIT_TESTING_PROXIMITY_EVALUATION *pProximityEval -) -{ - -}*/ BOOL WINAPI GetGestureInfo( _In_ HGESTUREINFO hGestureInfo, diff --git a/wrappers/base/user32_wrapper/user32_wrapper.spec b/wrappers/base/user32_wrapper/user32_wrapper.spec index 8a01dd2889..2d474173dd 100644 --- a/wrappers/base/user32_wrapper/user32_wrapper.spec +++ b/wrappers/base/user32_wrapper/user32_wrapper.spec @@ -907,17 +907,19 @@ @ stdcall UnregisterSuspendResumeNotification(ptr) #Win10 functions -@ stdcall GetAwarenessFromDpiAwarenessContext(long) @ stdcall AdjustWindowRectExForDpi(ptr long long long long) @ stdcall AreDpiAwarenessContextsEqual(long long) +;@ stdcall CreateSyntheticPointerDevice(long long long) @ stdcall EnableNonClientDpiScaling(long) -@ stdcall IsValidDpiAwarenessContext(long) -@ stdcall IsWindowArranged(long) -@ stdcall GetSystemMetricsForDpi(long long) +@ stdcall GetAwarenessFromDpiAwarenessContext(long) @ stdcall GetDpiForSystem() @ stdcall GetDpiForWindow(long) -;@ stdcall GetThreadDpiAwarenessContext() +@ stdcall GetSystemMetricsForDpi(long long) +@ stdcall GetThreadDpiAwarenessContext() @ stdcall GetWindowDpiAwarenessContext(long) +;@ stdcall InjectSyntheticPointerInput(ptr ptr long) +@ stdcall IsValidDpiAwarenessContext(long) +@ stdcall IsWindowArranged(long) @ stdcall SetProcessRestrictionExemption(long) @ stdcall SetThreadDpiAwarenessContext(ptr) @ stdcall SystemParametersInfoForDpi(long long ptr long long) \ No newline at end of file diff --git a/wrappers/directx/wine/d2d1/CMakeLists.txt b/wrappers/directx/wine/d2d1/CMakeLists.txt index 4ee91b14a9..05d8535d25 100644 --- a/wrappers/directx/wine/d2d1/CMakeLists.txt +++ b/wrappers/directx/wine/d2d1/CMakeLists.txt @@ -11,6 +11,7 @@ list(APPEND SOURCE bitmap.c bitmap_render_target.c brush.c + command_list.c dc_render_target.c device.c effect.c diff --git a/wrappers/directx/wine/d2d1/bitmap.c b/wrappers/directx/wine/d2d1/bitmap.c index 7ed57052b9..e504861151 100644 --- a/wrappers/directx/wine/d2d1/bitmap.c +++ b/wrappers/directx/wine/d2d1/bitmap.c @@ -26,6 +26,25 @@ static inline struct d2d_bitmap *impl_from_ID2D1Bitmap1(ID2D1Bitmap1 *iface) return CONTAINING_RECORD(iface, struct d2d_bitmap, ID2D1Bitmap1_iface); } +static HRESULT d2d_bitmap_unmap(struct d2d_bitmap *bitmap) +{ + ID3D11DeviceContext *context; + ID3D11Device *device; + + if (!bitmap->mapped_resource.pData) + return D2DERR_WRONG_STATE; + + ID3D11Resource_GetDevice(bitmap->resource, &device); + ID3D11Device_GetImmediateContext(device, &context); + ID3D11DeviceContext_Unmap(context, bitmap->resource, 0); + ID3D11DeviceContext_Release(context); + ID3D11Device_Release(device); + + memset(&bitmap->mapped_resource, 0, sizeof(bitmap->mapped_resource)); + + return S_OK; +} + static HRESULT STDMETHODCALLTYPE d2d_bitmap_QueryInterface(ID2D1Bitmap1 *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); @@ -52,7 +71,7 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_AddRef(ID2D1Bitmap1 *iface) struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap1(iface); ULONG refcount = InterlockedIncrement(&bitmap->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -62,19 +81,19 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_Release(ID2D1Bitmap1 *iface) struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap1(iface); ULONG refcount = InterlockedDecrement(&bitmap->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { if (bitmap->srv) - ID3D10ShaderResourceView_Release(bitmap->srv); + ID3D11ShaderResourceView_Release(bitmap->srv); if (bitmap->rtv) - ID3D10RenderTargetView_Release(bitmap->rtv); + ID3D11RenderTargetView_Release(bitmap->rtv); if (bitmap->surface) IDXGISurface_Release(bitmap->surface); - ID3D10Resource_Release(bitmap->resource); + ID3D11Resource_Release(bitmap->resource); ID2D1Factory_Release(bitmap->factory); - heap_free(bitmap); + free(bitmap); } return refcount; @@ -133,9 +152,33 @@ static void STDMETHODCALLTYPE d2d_bitmap_GetDpi(ID2D1Bitmap1 *iface, float *dpi_ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromBitmap(ID2D1Bitmap1 *iface, const D2D1_POINT_2U *dst_point, ID2D1Bitmap *bitmap, const D2D1_RECT_U *src_rect) { - FIXME("iface %p, dst_point %p, bitmap %p, src_rect %p stub!\n", iface, dst_point, bitmap, src_rect); + struct d2d_bitmap *src_bitmap = unsafe_impl_from_ID2D1Bitmap(bitmap); + struct d2d_bitmap *dst_bitmap = impl_from_ID2D1Bitmap1(iface); + ID3D11DeviceContext *context; + ID3D11Device *device; + D3D11_BOX box; - return E_NOTIMPL; + TRACE("iface %p, dst_point %p, bitmap %p, src_rect %p.\n", iface, dst_point, bitmap, src_rect); + + if (src_rect) + { + box.left = src_rect->left; + box.top = src_rect->top; + box.front = 0; + box.right = src_rect->right; + box.bottom = src_rect->bottom; + box.back = 1; + } + + ID3D11Resource_GetDevice(dst_bitmap->resource, &device); + ID3D11Device_GetImmediateContext(device, &context); + ID3D11DeviceContext_CopySubresourceRegion(context, dst_bitmap->resource, 0, + dst_point ? dst_point->x : 0, dst_point ? dst_point->y : 0, 0, + src_bitmap->resource, 0, src_rect ? &box : NULL); + ID3D11DeviceContext_Release(context); + ID3D11Device_Release(device); + + return S_OK; } static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromRenderTarget(ID2D1Bitmap1 *iface, @@ -150,8 +193,9 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromMemory(ID2D1Bitmap1 *iface, const D2D1_RECT_U *dst_rect, const void *src_data, UINT32 pitch) { struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap1(iface); - ID3D10Device *device; - D3D10_BOX box; + ID3D11DeviceContext *context; + ID3D11Device *device; + D3D11_BOX box; TRACE("iface %p, dst_rect %p, src_data %p, pitch %u.\n", iface, dst_rect, src_data, pitch); @@ -165,9 +209,11 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromMemory(ID2D1Bitmap1 *iface, box.back = 1; } - ID3D10Resource_GetDevice(bitmap->resource, &device); - ID3D10Device_UpdateSubresource(device, bitmap->resource, 0, dst_rect ? &box : NULL, src_data, pitch, 0); - ID3D10Device_Release(device); + ID3D11Resource_GetDevice(bitmap->resource, &device); + ID3D11Device_GetImmediateContext(device, &context); + ID3D11DeviceContext_UpdateSubresource(context, bitmap->resource, 0, dst_rect ? &box : NULL, src_data, pitch, 0); + ID3D11DeviceContext_Release(context); + ID3D11Device_Release(device); return S_OK; } @@ -202,16 +248,64 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_GetSurface(ID2D1Bitmap1 *iface, IDXG static HRESULT STDMETHODCALLTYPE d2d_bitmap_Map(ID2D1Bitmap1 *iface, D2D1_MAP_OPTIONS options, D2D1_MAPPED_RECT *mapped_rect) { - FIXME("iface %p, options %#x, mapped_rect %p stub!\n", iface, options, mapped_rect); + struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap1(iface); + D3D11_MAPPED_SUBRESOURCE mapped_resource; + ID3D11DeviceContext *context; + ID3D11Device *device; + D3D11_MAP map_type; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, options %#x, mapped_rect %p.\n", iface, options, mapped_rect); + + if (!(bitmap->options & D2D1_BITMAP_OPTIONS_CPU_READ)) + return E_INVALIDARG; + + if (bitmap->mapped_resource.pData) + return D2DERR_WRONG_STATE; + + if (options == D2D1_MAP_OPTIONS_READ) + map_type = D3D11_MAP_READ; + else if (options == D2D1_MAP_OPTIONS_WRITE) + map_type = D3D11_MAP_WRITE; + else if (options == (D2D1_MAP_OPTIONS_READ | D2D1_MAP_OPTIONS_WRITE)) + map_type = D3D11_MAP_READ_WRITE; + else if (options == (D2D1_MAP_OPTIONS_WRITE | D2D1_MAP_OPTIONS_DISCARD)) + map_type = D3D11_MAP_WRITE_DISCARD; + else + { + WARN("Invalid mapping options %#x.\n", options); + return E_INVALIDARG; + } + + ID3D11Resource_GetDevice(bitmap->resource, &device); + ID3D11Device_GetImmediateContext(device, &context); + if (SUCCEEDED(hr = ID3D11DeviceContext_Map(context, bitmap->resource, 0, map_type, + 0, &mapped_resource))) + { + bitmap->mapped_resource = mapped_resource; + } + ID3D11DeviceContext_Release(context); + ID3D11Device_Release(device); + + if (FAILED(hr)) + { + WARN("Failed to map resource, hr %#lx.\n", hr); + return E_INVALIDARG; + } + + mapped_rect->pitch = bitmap->mapped_resource.RowPitch; + mapped_rect->bits = bitmap->mapped_resource.pData; + + return S_OK; } static HRESULT STDMETHODCALLTYPE d2d_bitmap_Unmap(ID2D1Bitmap1 *iface) { - FIXME("iface %p stub!\n", iface); + struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap1(iface); - return E_NOTIMPL; + TRACE("iface %p.\n", iface); + + return d2d_bitmap_unmap(bitmap); } static const struct ID2D1Bitmap1Vtbl d2d_bitmap_vtbl = @@ -270,15 +364,15 @@ static BOOL format_supported(const D2D1_PIXEL_FORMAT *format) } static void d2d_bitmap_init(struct d2d_bitmap *bitmap, struct d2d_device_context *context, - ID3D10Resource *resource, D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES1 *desc) + ID3D11Resource *resource, D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES1 *desc) { - ID3D10Device *d3d_device; + ID3D11Device *d3d_device; HRESULT hr; bitmap->ID2D1Bitmap1_iface.lpVtbl = &d2d_bitmap_vtbl; bitmap->refcount = 1; ID2D1Factory_AddRef(bitmap->factory = context->factory); - ID3D10Resource_AddRef(bitmap->resource = resource); + ID3D11Resource_AddRef(bitmap->resource = resource); bitmap->pixel_size = size; bitmap->format = desc->pixelFormat; bitmap->dpi_x = desc->dpiX; @@ -286,21 +380,21 @@ static void d2d_bitmap_init(struct d2d_bitmap *bitmap, struct d2d_device_context bitmap->options = desc->bitmapOptions; if (d2d_device_context_is_dxgi_target(context)) - ID3D10Resource_QueryInterface(resource, &IID_IDXGISurface, (void **)&bitmap->surface); + ID3D11Resource_QueryInterface(resource, &IID_IDXGISurface, (void **)&bitmap->surface); - ID3D10Resource_GetDevice(resource, &d3d_device); + ID3D11Resource_GetDevice(resource, &d3d_device); if (bitmap->options & D2D1_BITMAP_OPTIONS_TARGET) { - if (FAILED(hr = ID3D10Device_CreateRenderTargetView(d3d_device, resource, NULL, &bitmap->rtv))) - WARN("Failed to create RTV, hr %#x.\n", hr); + if (FAILED(hr = ID3D11Device_CreateRenderTargetView(d3d_device, resource, NULL, &bitmap->rtv))) + WARN("Failed to create RTV, hr %#lx.\n", hr); } if (!(bitmap->options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW)) { - if (FAILED(hr = ID3D10Device_CreateShaderResourceView(d3d_device, resource, NULL, &bitmap->srv))) - WARN("Failed to create SRV, hr %#x.\n", hr); + if (FAILED(hr = ID3D11Device_CreateShaderResourceView(d3d_device, resource, NULL, &bitmap->srv))) + WARN("Failed to create SRV, hr %#lx.\n", hr); } - ID3D10Device_Release(d3d_device); + ID3D11Device_Release(d3d_device); if (bitmap->dpi_x == 0.0f && bitmap->dpi_y == 0.0f) { @@ -309,13 +403,30 @@ static void d2d_bitmap_init(struct d2d_bitmap *bitmap, struct d2d_device_context } } +static BOOL check_bitmap_options(unsigned int options) +{ + switch (options) + { + case D2D1_BITMAP_OPTIONS_NONE: + case D2D1_BITMAP_OPTIONS_TARGET: + case D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW: + case D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE: + case D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE: + case D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ: + return TRUE; + default: + WARN("Invalid bitmap options %#x.\n", options); + return FALSE; + } +} + HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap) { - D3D10_SUBRESOURCE_DATA resource_data; + D3D11_SUBRESOURCE_DATA resource_data; D2D1_BITMAP_PROPERTIES1 bitmap_desc; - D3D10_TEXTURE2D_DESC texture_desc; - ID3D10Texture2D *texture; + D3D11_TEXTURE2D_DESC texture_desc; + ID3D11Texture2D *texture; HRESULT hr; if (!format_supported(&desc->pixelFormat)) @@ -337,6 +448,9 @@ HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size, return E_INVALIDARG; } + if (!check_bitmap_options(desc->bitmapOptions)) + return E_INVALIDARG; + texture_desc.Width = size.width; texture_desc.Height = size.height; if (!texture_desc.Width || !texture_desc.Height) @@ -346,37 +460,65 @@ HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size, texture_desc.Format = desc->pixelFormat.format; texture_desc.SampleDesc.Count = 1; texture_desc.SampleDesc.Quality = 0; - texture_desc.Usage = D3D10_USAGE_DEFAULT; + texture_desc.Usage = D3D11_USAGE_DEFAULT; + if (desc->bitmapOptions & D2D1_BITMAP_OPTIONS_CPU_READ) + texture_desc.Usage = D3D11_USAGE_STAGING; texture_desc.BindFlags = 0; if (desc->bitmapOptions & D2D1_BITMAP_OPTIONS_TARGET) - texture_desc.BindFlags |= D3D10_BIND_RENDER_TARGET; + texture_desc.BindFlags |= D3D11_BIND_RENDER_TARGET; if (!(desc->bitmapOptions & D2D1_BITMAP_OPTIONS_CANNOT_DRAW)) - texture_desc.BindFlags |= D3D10_BIND_SHADER_RESOURCE; + texture_desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; texture_desc.CPUAccessFlags = 0; + if (desc->bitmapOptions & D2D1_BITMAP_OPTIONS_CPU_READ) + texture_desc.CPUAccessFlags |= D3D11_CPU_ACCESS_READ; texture_desc.MiscFlags = 0; if (desc->bitmapOptions & D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE) - texture_desc.MiscFlags |= D3D10_RESOURCE_MISC_GDI_COMPATIBLE; + texture_desc.MiscFlags |= D3D11_RESOURCE_MISC_GDI_COMPATIBLE; resource_data.pSysMem = src_data; resource_data.SysMemPitch = pitch; - if (FAILED(hr = ID3D10Device_CreateTexture2D(context->d3d_device, &texture_desc, + if (FAILED(hr = ID3D11Device1_CreateTexture2D(context->d3d_device, &texture_desc, src_data ? &resource_data : NULL, &texture))) { - ERR("Failed to create texture, hr %#x.\n", hr); + ERR("Failed to create texture, hr %#lx.\n", hr); return hr; } - if ((*bitmap = heap_alloc_zero(sizeof(**bitmap)))) + if ((*bitmap = calloc(1, sizeof(**bitmap)))) { - d2d_bitmap_init(*bitmap, context, (ID3D10Resource *)texture, size, desc); + d2d_bitmap_init(*bitmap, context, (ID3D11Resource *)texture, size, desc); TRACE("Created bitmap %p.\n", *bitmap); } - ID3D10Texture2D_Release(texture); + ID3D11Texture2D_Release(texture); return *bitmap ? S_OK : E_OUTOFMEMORY; } +unsigned int d2d_get_bitmap_options_for_surface(IDXGISurface *surface) +{ + D3D11_TEXTURE2D_DESC desc; + unsigned int options = 0; + ID3D11Texture2D *texture; + + if (FAILED(IDXGISurface_QueryInterface(surface, &IID_ID3D11Texture2D, (void **)&texture))) + return 0; + + ID3D11Texture2D_GetDesc(texture, &desc); + ID3D11Texture2D_Release(texture); + + if (desc.BindFlags & D3D11_BIND_RENDER_TARGET) + options |= D2D1_BITMAP_OPTIONS_TARGET; + if (!(desc.BindFlags & D3D11_BIND_SHADER_RESOURCE)) + options |= D2D1_BITMAP_OPTIONS_CANNOT_DRAW; + if (desc.MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE) + options |= D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE; + if (desc.Usage == D3D11_USAGE_STAGING && desc.CPUAccessFlags & D3D11_CPU_ACCESS_READ) + options |= D2D1_BITMAP_OPTIONS_CPU_READ; + + return options; +} + HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap) { @@ -385,7 +527,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, if (IsEqualGUID(iid, &IID_ID2D1Bitmap)) { struct d2d_bitmap *src_impl = unsafe_impl_from_ID2D1Bitmap(data); - ID3D10Device *device; + ID3D11Device *device; HRESULT hr = S_OK; if (src_impl->factory != context->factory) @@ -394,23 +536,31 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, goto failed; } - ID3D10Resource_GetDevice(src_impl->resource, &device); - ID3D10Device_Release(device); - if (device != context->d3d_device) + ID3D11Resource_GetDevice(src_impl->resource, &device); + ID3D11Device_Release(device); + if (device != (ID3D11Device *)context->d3d_device) { hr = D2DERR_UNSUPPORTED_OPERATION; goto failed; } - if (!desc) + if (desc) + { + d = *desc; + if (d.pixelFormat.format == DXGI_FORMAT_UNKNOWN) + d.pixelFormat.format = src_impl->format.format; + if (d.pixelFormat.alphaMode == D2D1_ALPHA_MODE_UNKNOWN) + d.pixelFormat.alphaMode = src_impl->format.alphaMode; + } + else { d.pixelFormat = src_impl->format; d.dpiX = src_impl->dpi_x; d.dpiY = src_impl->dpi_y; d.bitmapOptions = src_impl->options; d.colorContext = NULL; - desc = &d; } + desc = &d; if (!format_supported(&desc->pixelFormat)) { @@ -420,7 +570,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, goto failed; } - if (!(*bitmap = heap_alloc_zero(sizeof(**bitmap)))) + if (!(*bitmap = calloc(1, sizeof(**bitmap)))) { hr = E_OUTOFMEMORY; goto failed; @@ -437,36 +587,36 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, { DXGI_SURFACE_DESC surface_desc; IDXGISurface *surface = data; - ID3D10Resource *resource; + ID3D11Resource *resource; D2D1_SIZE_U pixel_size; - ID3D10Device *device; + ID3D11Device *device; HRESULT hr; - if (FAILED(IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource))) + if (FAILED(IDXGISurface_QueryInterface(surface, &IID_ID3D11Resource, (void **)&resource))) { WARN("Failed to get d3d resource from dxgi surface.\n"); return E_FAIL; } - ID3D10Resource_GetDevice(resource, &device); - ID3D10Device_Release(device); - if (device != context->d3d_device) + ID3D11Resource_GetDevice(resource, &device); + ID3D11Device_Release(device); + if (device != (ID3D11Device *)context->d3d_device) { - ID3D10Resource_Release(resource); + ID3D11Resource_Release(resource); return D2DERR_UNSUPPORTED_OPERATION; } - if (!(*bitmap = heap_alloc_zero(sizeof(**bitmap)))) + if (!(*bitmap = calloc(1, sizeof(**bitmap)))) { - ID3D10Resource_Release(resource); + ID3D11Resource_Release(resource); return E_OUTOFMEMORY; } if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc))) { - WARN("Failed to get surface desc, hr %#x.\n", hr); - ID3D10Resource_Release(resource); + WARN("Failed to get surface desc, hr %#lx.\n", hr); + ID3D11Resource_Release(resource); return hr; } @@ -474,6 +624,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, { memset(&d, 0, sizeof(d)); d.pixelFormat.format = surface_desc.Format; + d.bitmapOptions = d2d_get_bitmap_options_for_surface(surface); } else { @@ -494,7 +645,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, pixel_size.height = surface_desc.Height; d2d_bitmap_init(*bitmap, context, resource, pixel_size, &d); - ID3D10Resource_Release(resource); + ID3D11Resource_Release(resource); TRACE("Created bitmap %p.\n", *bitmap); return S_OK; @@ -529,11 +680,12 @@ HRESULT d2d_bitmap_create_from_wic_bitmap(struct d2d_device_context *context, IW {&GUID_WICPixelFormat32bppPBGRA, {DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED}}, {&GUID_WICPixelFormat32bppPRGBA, {DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED}}, {&GUID_WICPixelFormat32bppBGR, {DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE}}, + {&GUID_WICPixelFormat32bppRGB, {DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_IGNORE}}, }; if (FAILED(hr = IWICBitmapSource_GetSize(bitmap_source, &size.width, &size.height))) { - WARN("Failed to get bitmap size, hr %#x.\n", hr); + WARN("Failed to get bitmap size, hr %#lx.\n", hr); return hr; } @@ -553,7 +705,7 @@ HRESULT d2d_bitmap_create_from_wic_bitmap(struct d2d_device_context *context, IW if (FAILED(hr = IWICBitmapSource_GetPixelFormat(bitmap_source, &wic_format))) { - WARN("Failed to get bitmap format, hr %#x.\n", hr); + WARN("Failed to get bitmap format, hr %#lx.\n", hr); return hr; } @@ -592,7 +744,7 @@ HRESULT d2d_bitmap_create_from_wic_bitmap(struct d2d_device_context *context, IW pitch = ((bpp * size.width) + 15) & ~15; if (pitch / bpp < size.width) return E_OUTOFMEMORY; - if (!(data = heap_calloc(size.height, pitch))) + if (!(data = calloc(size.height, pitch))) return E_OUTOFMEMORY; data_size = size.height * pitch; @@ -602,14 +754,14 @@ HRESULT d2d_bitmap_create_from_wic_bitmap(struct d2d_device_context *context, IW rect.Height = size.height; if (FAILED(hr = IWICBitmapSource_CopyPixels(bitmap_source, &rect, pitch, data_size, data))) { - WARN("Failed to copy bitmap pixels, hr %#x.\n", hr); - heap_free(data); + WARN("Failed to copy bitmap pixels, hr %#lx.\n", hr); + free(data); return hr; } hr = d2d_bitmap_create(context, size, data, pitch, &bitmap_desc, bitmap); - heap_free(data); + free(data); return hr; } diff --git a/wrappers/directx/wine/d2d1/bitmap_render_target.c b/wrappers/directx/wine/d2d1/bitmap_render_target.c index 373c373566..ce8b8965d3 100644 --- a/wrappers/directx/wine/d2d1/bitmap_render_target.c +++ b/wrappers/directx/wine/d2d1/bitmap_render_target.c @@ -51,7 +51,7 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_render_target_AddRef(ID2D1BitmapRender struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); ULONG refcount = InterlockedIncrement(&render_target->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -61,14 +61,14 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_render_target_Release(ID2D1BitmapRende struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); ULONG refcount = InterlockedDecrement(&render_target->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { IUnknown_Release(render_target->dxgi_inner); if (render_target->bitmap) ID2D1Bitmap_Release(render_target->bitmap); - heap_free(render_target); + free(render_target); } return refcount; @@ -787,7 +787,7 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta parent_target->ops ? &d2d_bitmap_render_target_ops : NULL, &dxgi_rt_desc, (void **)&render_target->dxgi_inner))) { - WARN("Failed to create DXGI surface render target, hr %#x.\n", hr); + WARN("Failed to create DXGI surface render target, hr %#lx.\n", hr); return hr; } @@ -798,7 +798,7 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta if (FAILED(hr = IUnknown_QueryInterface(render_target->dxgi_inner, &IID_ID2D1RenderTarget, (void **)&render_target->dxgi_target))) { - WARN("Failed to retrieve ID2D1RenderTarget interface, hr %#x.\n", hr); + WARN("Failed to retrieve ID2D1RenderTarget interface, hr %#lx.\n", hr); IUnknown_Release(render_target->dxgi_inner); return hr; } @@ -816,7 +816,7 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta ID2D1DeviceContext_Release(context); if (FAILED(hr)) { - WARN("Failed to create target bitmap, hr %#x.\n", hr); + WARN("Failed to create target bitmap, hr %#lx.\n", hr); IUnknown_Release(render_target->dxgi_inner); return hr; } diff --git a/wrappers/directx/wine/d2d1/brush.c b/wrappers/directx/wine/d2d1/brush.c index 1fe9b5e8f7..75cd72b5b9 100644 --- a/wrappers/directx/wine/d2d1/brush.c +++ b/wrappers/directx/wine/d2d1/brush.c @@ -50,7 +50,7 @@ static ULONG STDMETHODCALLTYPE d2d_gradient_AddRef(ID2D1GradientStopCollection * struct d2d_gradient *gradient = impl_from_ID2D1GradientStopCollection(iface); ULONG refcount = InterlockedIncrement(&gradient->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -60,14 +60,14 @@ static ULONG STDMETHODCALLTYPE d2d_gradient_Release(ID2D1GradientStopCollection struct d2d_gradient *gradient = impl_from_ID2D1GradientStopCollection(iface); ULONG refcount = InterlockedDecrement(&gradient->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { - heap_free(gradient->stops); - ID3D10ShaderResourceView_Release(gradient->view); + free(gradient->stops); + ID3D11ShaderResourceView_Release(gradient->view); ID2D1Factory_Release(gradient->factory); - heap_free(gradient); + free(gradient); } return refcount; @@ -127,19 +127,21 @@ static const struct ID2D1GradientStopCollectionVtbl d2d_gradient_vtbl = d2d_gradient_GetExtendMode, }; -HRESULT d2d_gradient_create(ID2D1Factory *factory, ID3D10Device *device, const D2D1_GRADIENT_STOP *stops, - UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode, struct d2d_gradient **gradient) +HRESULT d2d_gradient_create(ID2D1Factory *factory, ID3D11Device1 *device, const D2D1_GRADIENT_STOP *stops, + UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode, struct d2d_gradient **out) { - D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc; - D3D10_SUBRESOURCE_DATA buffer_data; - ID3D10ShaderResourceView *view; - D3D10_BUFFER_DESC buffer_desc; + D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc; + D3D11_SUBRESOURCE_DATA buffer_data; + ID3D11ShaderResourceView *view; + struct d2d_gradient *gradient; + D3D11_BUFFER_DESC buffer_desc; struct d2d_vec4 *data; - ID3D10Buffer *buffer; + ID3D11Buffer *buffer; unsigned int i; HRESULT hr; - if (!(data = heap_calloc(stop_count, 2 * sizeof(*data)))) + *out = NULL; + if (!(data = calloc(stop_count, 2 * sizeof(*data)))) { ERR("Failed to allocate data.\n"); return E_OUTOFMEMORY; @@ -155,8 +157,8 @@ HRESULT d2d_gradient_create(ID2D1Factory *factory, ID3D10Device *device, const D } buffer_desc.ByteWidth = 2 * stop_count * sizeof(*data); - buffer_desc.Usage = D3D10_USAGE_DEFAULT; - buffer_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; + buffer_desc.Usage = D3D11_USAGE_DEFAULT; + buffer_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; buffer_desc.CPUAccessFlags = 0; buffer_desc.MiscFlags = 0; @@ -164,30 +166,30 @@ HRESULT d2d_gradient_create(ID2D1Factory *factory, ID3D10Device *device, const D buffer_data.SysMemPitch = 0; buffer_data.SysMemSlicePitch = 0; - hr = ID3D10Device_CreateBuffer(device, &buffer_desc, &buffer_data, &buffer); - heap_free(data); + hr = ID3D11Device1_CreateBuffer(device, &buffer_desc, &buffer_data, &buffer); + free(data); if (FAILED(hr)) { - ERR("Failed to create buffer, hr %#x.\n", hr); + ERR("Failed to create buffer, hr %#lx.\n", hr); return hr; } srv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - srv_desc.ViewDimension = D3D10_SRV_DIMENSION_BUFFER; + srv_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; srv_desc.Buffer.ElementOffset = 0; srv_desc.Buffer.ElementWidth = 2 * stop_count; - hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)buffer, &srv_desc, &view); - ID3D10Buffer_Release(buffer); + hr = ID3D11Device1_CreateShaderResourceView(device, (ID3D11Resource *)buffer, &srv_desc, &view); + ID3D11Buffer_Release(buffer); if (FAILED(hr)) { - ERR("Failed to create view, hr %#x.\n", hr); + ERR("Failed to create view, hr %#lx.\n", hr); return hr; } - if (!(*gradient = heap_alloc_zero(sizeof(**gradient)))) + if (!(gradient = calloc(1, sizeof(*gradient)))) { - ID3D10ShaderResourceView_Release(view); + ID3D11ShaderResourceView_Release(view); return E_OUTOFMEMORY; } @@ -196,21 +198,22 @@ HRESULT d2d_gradient_create(ID2D1Factory *factory, ID3D10Device *device, const D if (extend_mode != D2D1_EXTEND_MODE_CLAMP) FIXME("Ignoring extend mode %#x.\n", extend_mode); - (*gradient)->ID2D1GradientStopCollection_iface.lpVtbl = &d2d_gradient_vtbl; - (*gradient)->refcount = 1; - ID2D1Factory_AddRef((*gradient)->factory = factory); - (*gradient)->view = view; + gradient->ID2D1GradientStopCollection_iface.lpVtbl = &d2d_gradient_vtbl; + gradient->refcount = 1; + ID2D1Factory_AddRef(gradient->factory = factory); + gradient->view = view; - (*gradient)->stop_count = stop_count; - if (!((*gradient)->stops = heap_calloc(stop_count, sizeof(*stops)))) + gradient->stop_count = stop_count; + if (!(gradient->stops = calloc(stop_count, sizeof(*stops)))) { - ID3D10ShaderResourceView_Release(view); - heap_free(*gradient); + ID3D11ShaderResourceView_Release(view); + free(gradient); return E_OUTOFMEMORY; } - memcpy((*gradient)->stops, stops, stop_count * sizeof(*stops)); + memcpy(gradient->stops, stops, stop_count * sizeof(*stops)); - TRACE("Created gradient %p.\n", *gradient); + TRACE("Created gradient %p.\n", gradient); + *out = gradient; return S_OK; } @@ -222,15 +225,18 @@ static struct d2d_gradient *unsafe_impl_from_ID2D1GradientStopCollection(ID2D1Gr return CONTAINING_RECORD(iface, struct d2d_gradient, ID2D1GradientStopCollection_iface); } -static void d2d_gradient_bind(struct d2d_gradient *gradient, ID3D10Device *device, unsigned int brush_idx) +static void d2d_gradient_bind(struct d2d_gradient *gradient, ID3D11Device1 *device, unsigned int brush_idx) { - ID3D10Device_PSSetShaderResources(device, 2 + brush_idx, 1, &gradient->view); + ID3D11DeviceContext *context; + ID3D11Device1_GetImmediateContext(device, &context); + ID3D11DeviceContext_PSSetShaderResources(context, 2 + brush_idx, 1, &gradient->view); + ID3D11DeviceContext_Release(context); } static void d2d_brush_destroy(struct d2d_brush *brush) { ID2D1Factory_Release(brush->factory); - heap_free(brush); + free(brush); } static void d2d_brush_init(struct d2d_brush *brush, ID2D1Factory *factory, @@ -282,7 +288,7 @@ static ULONG STDMETHODCALLTYPE d2d_solid_color_brush_AddRef(ID2D1SolidColorBrush struct d2d_brush *brush = impl_from_ID2D1SolidColorBrush(iface); ULONG refcount = InterlockedIncrement(&brush->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -292,7 +298,7 @@ static ULONG STDMETHODCALLTYPE d2d_solid_color_brush_Release(ID2D1SolidColorBrus struct d2d_brush *brush = impl_from_ID2D1SolidColorBrush(iface); ULONG refcount = InterlockedDecrement(&brush->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) d2d_brush_destroy(brush); @@ -383,7 +389,7 @@ static const struct ID2D1SolidColorBrushVtbl d2d_solid_color_brush_vtbl = HRESULT d2d_solid_color_brush_create(ID2D1Factory *factory, const D2D1_COLOR_F *color, const D2D1_BRUSH_PROPERTIES *desc, struct d2d_brush **brush) { - if (!(*brush = heap_alloc_zero(sizeof(**brush)))) + if (!(*brush = calloc(1, sizeof(**brush)))) return E_OUTOFMEMORY; d2d_brush_init(*brush, factory, D2D_BRUSH_TYPE_SOLID, desc, @@ -425,7 +431,7 @@ static ULONG STDMETHODCALLTYPE d2d_linear_gradient_brush_AddRef(ID2D1LinearGradi struct d2d_brush *brush = impl_from_ID2D1LinearGradientBrush(iface); ULONG refcount = InterlockedIncrement(&brush->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -435,7 +441,7 @@ static ULONG STDMETHODCALLTYPE d2d_linear_gradient_brush_Release(ID2D1LinearGrad struct d2d_brush *brush = impl_from_ID2D1LinearGradientBrush(iface); ULONG refcount = InterlockedDecrement(&brush->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { @@ -567,7 +573,7 @@ HRESULT d2d_linear_gradient_brush_create(ID2D1Factory *factory, const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1GradientStopCollection *gradient, struct d2d_brush **brush) { - if (!(*brush = heap_alloc_zero(sizeof(**brush)))) + if (!(*brush = calloc(1, sizeof(**brush)))) return E_OUTOFMEMORY; d2d_brush_init(*brush, factory, D2D_BRUSH_TYPE_LINEAR, brush_desc, @@ -612,7 +618,7 @@ static ULONG STDMETHODCALLTYPE d2d_radial_gradient_brush_AddRef(ID2D1RadialGradi struct d2d_brush *brush = impl_from_ID2D1RadialGradientBrush(iface); ULONG refcount = InterlockedIncrement(&brush->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -622,7 +628,7 @@ static ULONG STDMETHODCALLTYPE d2d_radial_gradient_brush_Release(ID2D1RadialGrad struct d2d_brush *brush = impl_from_ID2D1RadialGradientBrush(iface); ULONG refcount = InterlockedDecrement(&brush->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { @@ -796,7 +802,7 @@ HRESULT d2d_radial_gradient_brush_create(ID2D1Factory *factory, { struct d2d_brush *b; - if (!(b = heap_alloc_zero(sizeof(*b)))) + if (!(b = calloc(1, sizeof(*b)))) return E_OUTOFMEMORY; d2d_brush_init(b, factory, D2D_BRUSH_TYPE_RADIAL, brush_desc, (ID2D1BrushVtbl *)&d2d_radial_gradient_brush_vtbl); @@ -845,7 +851,7 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_brush_AddRef(ID2D1BitmapBrush1 *iface) struct d2d_brush *brush = impl_from_ID2D1BitmapBrush1(iface); ULONG refcount = InterlockedIncrement(&brush->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -855,7 +861,7 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_brush_Release(ID2D1BitmapBrush1 *iface struct d2d_brush *brush = impl_from_ID2D1BitmapBrush1(iface); ULONG refcount = InterlockedDecrement(&brush->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { @@ -1071,7 +1077,7 @@ HRESULT d2d_bitmap_brush_create(ID2D1Factory *factory, ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES1 *bitmap_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, struct d2d_brush **brush) { - if (!(*brush = heap_alloc_zero(sizeof(**brush)))) + if (!(*brush = calloc(1, sizeof(**brush)))) return E_OUTOFMEMORY; d2d_brush_init(*brush, factory, D2D_BRUSH_TYPE_BITMAP, @@ -1095,6 +1101,246 @@ HRESULT d2d_bitmap_brush_create(ID2D1Factory *factory, ID2D1Bitmap *bitmap, return S_OK; } +static inline struct d2d_brush *impl_from_ID2D1ImageBrush(ID2D1ImageBrush *iface) +{ + return CONTAINING_RECORD((ID2D1Brush *)iface, struct d2d_brush, ID2D1Brush_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_image_brush_QueryInterface(ID2D1ImageBrush *iface, + REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1ImageBrush) + || IsEqualGUID(iid, &IID_ID2D1Brush) + || IsEqualGUID(iid, &IID_ID2D1Resource) + || IsEqualGUID(iid, &IID_IUnknown)) + { + ID2D1ImageBrush_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_image_brush_AddRef(ID2D1ImageBrush *iface) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + ULONG refcount = InterlockedIncrement(&brush->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_image_brush_Release(ID2D1ImageBrush *iface) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + ULONG refcount = InterlockedDecrement(&brush->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + { + if (brush->u.image.image) + ID2D1Image_Release(brush->u.image.image); + d2d_brush_destroy(brush); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d2d_image_brush_GetFactory(ID2D1ImageBrush *iface, + ID2D1Factory **factory) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p, factory %p.\n", iface, factory); + + ID2D1Factory_AddRef(*factory = brush->factory); +} + +static void STDMETHODCALLTYPE d2d_image_brush_SetOpacity(ID2D1ImageBrush *iface, float opacity) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p, opacity %.8e.\n", iface, opacity); + + brush->opacity = opacity; +} + +static void STDMETHODCALLTYPE d2d_image_brush_SetTransform(ID2D1ImageBrush *iface, + const D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + brush->transform = *transform; +} + +static float STDMETHODCALLTYPE d2d_image_brush_GetOpacity(ID2D1ImageBrush *iface) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p.\n", iface); + + return brush->opacity; +} + +static void STDMETHODCALLTYPE d2d_image_brush_GetTransform(ID2D1ImageBrush *iface, + D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + *transform = brush->transform; +} + +static void STDMETHODCALLTYPE d2d_image_brush_SetImage(ID2D1ImageBrush *iface, ID2D1Image *image) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p, image %p.\n", iface, image); + + if (image) + ID2D1Image_AddRef(image); + if (brush->u.image.image) + ID2D1Image_Release(brush->u.image.image); + brush->u.image.image = image; +} + +static void STDMETHODCALLTYPE d2d_image_brush_SetExtendModeX(ID2D1ImageBrush *iface, D2D1_EXTEND_MODE mode) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p, mode %#x.\n", iface, mode); + + brush->u.image.extend_mode_x = mode; +} + +static void STDMETHODCALLTYPE d2d_image_brush_SetExtendModeY(ID2D1ImageBrush *iface, D2D1_EXTEND_MODE mode) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p, mode %#x.\n", iface, mode); + + brush->u.image.extend_mode_y = mode; +} + +static void STDMETHODCALLTYPE d2d_image_brush_SetInterpolationMode(ID2D1ImageBrush *iface, + D2D1_INTERPOLATION_MODE mode) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p, mode %#x.\n", iface, mode); + + brush->u.image.interpolation_mode = mode; +} + +static void STDMETHODCALLTYPE d2d_image_brush_SetSourceRectangle(ID2D1ImageBrush *iface, const D2D1_RECT_F *rect) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p, rect %s.\n", iface, debug_d2d_rect_f(rect)); + + brush->u.image.source_rect = *rect; +} + +static void STDMETHODCALLTYPE d2d_image_brush_GetImage(ID2D1ImageBrush *iface, ID2D1Image **image) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p, image %p.\n", iface, image); + + if ((*image = brush->u.image.image)) + ID2D1Image_AddRef(*image); +} + +static D2D1_EXTEND_MODE STDMETHODCALLTYPE d2d_image_brush_GetExtendModeX(ID2D1ImageBrush *iface) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p.\n", iface); + + return brush->u.image.extend_mode_x; +} + +static D2D1_EXTEND_MODE STDMETHODCALLTYPE d2d_image_brush_GetExtendModeY(ID2D1ImageBrush *iface) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p.\n", iface); + + return brush->u.image.extend_mode_y; +} + +static D2D1_INTERPOLATION_MODE STDMETHODCALLTYPE d2d_image_brush_GetInterpolationMode(ID2D1ImageBrush *iface) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p.\n", iface); + + return brush->u.image.interpolation_mode; +} + +static void STDMETHODCALLTYPE d2d_image_brush_GetSourceRectangle(ID2D1ImageBrush *iface, D2D1_RECT_F *rect) +{ + struct d2d_brush *brush = impl_from_ID2D1ImageBrush(iface); + + TRACE("iface %p, rect %p.\n", iface, rect); + + *rect = brush->u.image.source_rect; +} + +static const struct ID2D1ImageBrushVtbl d2d_image_brush_vtbl = +{ + d2d_image_brush_QueryInterface, + d2d_image_brush_AddRef, + d2d_image_brush_Release, + d2d_image_brush_GetFactory, + d2d_image_brush_SetOpacity, + d2d_image_brush_SetTransform, + d2d_image_brush_GetOpacity, + d2d_image_brush_GetTransform, + d2d_image_brush_SetImage, + d2d_image_brush_SetExtendModeX, + d2d_image_brush_SetExtendModeY, + d2d_image_brush_SetInterpolationMode, + d2d_image_brush_SetSourceRectangle, + d2d_image_brush_GetImage, + d2d_image_brush_GetExtendModeX, + d2d_image_brush_GetExtendModeY, + d2d_image_brush_GetInterpolationMode, + d2d_image_brush_GetSourceRectangle +}; + +HRESULT d2d_image_brush_create(ID2D1Factory *factory, ID2D1Image *image, + const D2D1_IMAGE_BRUSH_PROPERTIES *image_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, + struct d2d_brush **brush) +{ + if (!(*brush = calloc(1, sizeof(**brush)))) + return E_OUTOFMEMORY; + + d2d_brush_init(*brush, factory, D2D_BRUSH_TYPE_IMAGE, + brush_desc, (ID2D1BrushVtbl *)&d2d_image_brush_vtbl); + if (((*brush)->u.image.image = image)) + ID2D1Image_AddRef((*brush)->u.image.image); + + (*brush)->u.image.source_rect = image_brush_desc->sourceRectangle; + (*brush)->u.image.extend_mode_x = image_brush_desc->extendModeX; + (*brush)->u.image.extend_mode_y = image_brush_desc->extendModeY; + (*brush)->u.image.interpolation_mode = image_brush_desc->interpolationMode; + + TRACE("Created brush %p.\n", *brush); + return S_OK; +} + struct d2d_brush *unsafe_impl_from_ID2D1Brush(ID2D1Brush *iface) { if (!iface) @@ -1102,23 +1348,24 @@ struct d2d_brush *unsafe_impl_from_ID2D1Brush(ID2D1Brush *iface) assert(iface->lpVtbl == (const ID2D1BrushVtbl *)&d2d_solid_color_brush_vtbl || iface->lpVtbl == (const ID2D1BrushVtbl *)&d2d_linear_gradient_brush_vtbl || iface->lpVtbl == (const ID2D1BrushVtbl *)&d2d_radial_gradient_brush_vtbl - || iface->lpVtbl == (const ID2D1BrushVtbl *)&d2d_bitmap_brush_vtbl); + || iface->lpVtbl == (const ID2D1BrushVtbl *)&d2d_bitmap_brush_vtbl + || iface->lpVtbl == (const ID2D1BrushVtbl *)&d2d_image_brush_vtbl); return CONTAINING_RECORD(iface, struct d2d_brush, ID2D1Brush_iface); } -static D3D10_TEXTURE_ADDRESS_MODE texture_address_mode_from_extend_mode(D2D1_EXTEND_MODE mode) +static D3D11_TEXTURE_ADDRESS_MODE texture_address_mode_from_extend_mode(D2D1_EXTEND_MODE mode) { switch (mode) { case D2D1_EXTEND_MODE_CLAMP: - return D3D10_TEXTURE_ADDRESS_CLAMP; + return D3D11_TEXTURE_ADDRESS_CLAMP; case D2D1_EXTEND_MODE_WRAP: - return D3D10_TEXTURE_ADDRESS_WRAP; + return D3D11_TEXTURE_ADDRESS_WRAP; case D2D1_EXTEND_MODE_MIRROR: - return D3D10_TEXTURE_ADDRESS_MIRROR; + return D3D11_TEXTURE_ADDRESS_MIRROR; default: FIXME("Unhandled extend mode %#x.\n", mode); - return D3D10_TEXTURE_ADDRESS_CLAMP; + return D3D11_TEXTURE_ADDRESS_CLAMP; } } @@ -1203,7 +1450,23 @@ BOOL d2d_brush_fill_cb(const struct d2d_brush *brush, struct d2d_brush_cb *cb) return TRUE; case D2D_BRUSH_TYPE_BITMAP: - bitmap = brush->u.bitmap.bitmap; + case D2D_BRUSH_TYPE_IMAGE: + { + ID2D1Bitmap *image_bitmap = NULL; + + if (brush->type == D2D_BRUSH_TYPE_BITMAP) + bitmap = brush->u.bitmap.bitmap; + else + { + if (FAILED(ID2D1Image_QueryInterface(brush->u.image.image, &IID_ID2D1Bitmap, (void **)&image_bitmap))) + { + FIXME("Only image brushes with bitmaps are supported.\n"); + return FALSE; + } + + bitmap = unsafe_impl_from_ID2D1Bitmap(image_bitmap); + cb->type = D2D_BRUSH_TYPE_BITMAP; + } /* Scale for bitmap size and dpi. */ b = brush->transform; @@ -1230,7 +1493,11 @@ BOOL d2d_brush_fill_cb(const struct d2d_brush *brush, struct d2d_brush_cb *cb) cb->u.bitmap.ignore_alpha = bitmap->format.alphaMode == D2D1_ALPHA_MODE_IGNORE; + if (image_bitmap) + ID2D1Bitmap_Release(image_bitmap); + return TRUE; + } default: FIXME("Unhandled brush type %#x.\n", brush->type); @@ -1238,33 +1505,36 @@ BOOL d2d_brush_fill_cb(const struct d2d_brush *brush, struct d2d_brush_cb *cb) } } -static void d2d_brush_bind_bitmap(struct d2d_brush *brush, struct d2d_device_context *context, - unsigned int brush_idx) +static void d2d_brush_bind_bitmap(struct d2d_bitmap *bitmap, struct d2d_device_context *context, + D2D1_EXTEND_MODE extend_mode_x, D2D1_EXTEND_MODE extend_mode_y, + D2D1_INTERPOLATION_MODE interpolation_mode, unsigned int brush_idx) { - ID3D10SamplerState **sampler_state; + ID3D11SamplerState **sampler_state; + ID3D11DeviceContext *d3d_context; HRESULT hr; - ID3D10Device_PSSetShaderResources(context->d3d_device, brush_idx, 1, &brush->u.bitmap.bitmap->srv); + ID3D11Device1_GetImmediateContext(context->d3d_device, &d3d_context); + ID3D11DeviceContext_PSSetShaderResources(d3d_context, brush_idx, 1, &bitmap->srv); sampler_state = &context->sampler_states - [brush->u.bitmap.interpolation_mode % D2D_SAMPLER_INTERPOLATION_MODE_COUNT] - [brush->u.bitmap.extend_mode_x % D2D_SAMPLER_EXTEND_MODE_COUNT] - [brush->u.bitmap.extend_mode_y % D2D_SAMPLER_EXTEND_MODE_COUNT]; + [interpolation_mode % D2D_SAMPLER_INTERPOLATION_MODE_COUNT] + [extend_mode_x % D2D_SAMPLER_EXTEND_MODE_COUNT] + [extend_mode_y % D2D_SAMPLER_EXTEND_MODE_COUNT]; if (!*sampler_state) { - D3D10_SAMPLER_DESC sampler_desc; + D3D11_SAMPLER_DESC sampler_desc; - if (brush->u.bitmap.interpolation_mode == D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR) - sampler_desc.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT; + if (interpolation_mode == D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR) + sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; else - sampler_desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR; - sampler_desc.AddressU = texture_address_mode_from_extend_mode(brush->u.bitmap.extend_mode_x); - sampler_desc.AddressV = texture_address_mode_from_extend_mode(brush->u.bitmap.extend_mode_y); - sampler_desc.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP; + sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + sampler_desc.AddressU = texture_address_mode_from_extend_mode(extend_mode_x); + sampler_desc.AddressV = texture_address_mode_from_extend_mode(extend_mode_y); + sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; sampler_desc.MipLODBias = 0.0f; sampler_desc.MaxAnisotropy = 0; - sampler_desc.ComparisonFunc = D3D10_COMPARISON_NEVER; + sampler_desc.ComparisonFunc = D3D11_COMPARISON_NEVER; sampler_desc.BorderColor[0] = 0.0f; sampler_desc.BorderColor[1] = 0.0f; sampler_desc.BorderColor[2] = 0.0f; @@ -1272,10 +1542,32 @@ static void d2d_brush_bind_bitmap(struct d2d_brush *brush, struct d2d_device_con sampler_desc.MinLOD = 0.0f; sampler_desc.MaxLOD = 0.0f; - if (FAILED(hr = ID3D10Device_CreateSamplerState(context->d3d_device, &sampler_desc, sampler_state))) - ERR("Failed to create sampler state, hr %#x.\n", hr); + if (FAILED(hr = ID3D11Device1_CreateSamplerState(context->d3d_device, &sampler_desc, sampler_state))) + ERR("Failed to create sampler state, hr %#lx.\n", hr); } - ID3D10Device_PSSetSamplers(context->d3d_device, brush_idx, 1, sampler_state); + + ID3D11DeviceContext_PSSetSamplers(d3d_context, brush_idx, 1, sampler_state); + ID3D11DeviceContext_Release(d3d_context); +} + +static void d2d_brush_bind_image(struct d2d_brush *brush, struct d2d_device_context *context, + unsigned int brush_idx) +{ + ID2D1Bitmap *image_bitmap; + struct d2d_bitmap *bitmap; + + if (FAILED(ID2D1Image_QueryInterface(brush->u.image.image, &IID_ID2D1Bitmap, (void **)&image_bitmap))) + { + FIXME("Only image brushes with bitmaps are supported.\n"); + return; + } + + bitmap = unsafe_impl_from_ID2D1Bitmap(image_bitmap); + + d2d_brush_bind_bitmap(bitmap, context, brush->u.image.extend_mode_x, brush->u.image.extend_mode_y, + brush->u.image.interpolation_mode, brush_idx); + + ID2D1Bitmap_Release(image_bitmap); } void d2d_brush_bind_resources(struct d2d_brush *brush, struct d2d_device_context *context, unsigned int brush_idx) @@ -1294,7 +1586,12 @@ void d2d_brush_bind_resources(struct d2d_brush *brush, struct d2d_device_context break; case D2D_BRUSH_TYPE_BITMAP: - d2d_brush_bind_bitmap(brush, context, brush_idx); + d2d_brush_bind_bitmap(brush->u.bitmap.bitmap, context, brush->u.bitmap.extend_mode_x, + brush->u.bitmap.extend_mode_y, brush->u.bitmap.interpolation_mode, brush_idx); + break; + + case D2D_BRUSH_TYPE_IMAGE: + d2d_brush_bind_image(brush, context, brush_idx); break; default: diff --git a/wrappers/directx/wine/d2d1/d2d1_private.h b/wrappers/directx/wine/d2d1/d2d1_private.h index f50b13641b..58507fd2c0 100644 --- a/wrappers/directx/wine/d2d1/d2d1_private.h +++ b/wrappers/directx/wine/d2d1/d2d1_private.h @@ -20,16 +20,17 @@ #define __WINE_D2D1_PRIVATE_H #include "wine/debug.h" -#include "wine/heap.h" -#include "wine/config.h" -#include "wine/port.h" +#include "wine/list.h" #include #include +#include +#include #include #define COBJMACROS -#include "d2d1_2.h" -#include "d3d11.h" +#include "d2d1_3.h" +#include "d2d1effectauthor.h" +#include "d3d11_1.h" #ifdef D2D1_INIT_GUID #include "initguid.h" #endif @@ -41,6 +42,7 @@ enum d2d_brush_type D2D_BRUSH_TYPE_LINEAR, D2D_BRUSH_TYPE_RADIAL, D2D_BRUSH_TYPE_BITMAP, + D2D_BRUSH_TYPE_IMAGE, D2D_BRUSH_TYPE_COUNT, }; @@ -58,7 +60,7 @@ struct d2d_settings { unsigned int max_version_factory; }; -extern struct d2d_settings d2d_settings DECLSPEC_HIDDEN; +extern struct d2d_settings d2d_settings; struct d2d_clip_stack { @@ -75,8 +77,8 @@ struct d2d_error_state struct d2d_shape_resources { - ID3D10InputLayout *il; - ID3D10VertexShader *vs; + ID3D11InputLayout *il; + ID3D11VertexShader *vs; }; struct d2d_brush_cb @@ -150,9 +152,27 @@ enum d2d_device_context_sampler_limits D2D_SAMPLER_EXTEND_MODE_COUNT = 3, }; +enum d2d_device_context_target_type +{ + D2D_TARGET_UNKNOWN = 0, + D2D_TARGET_BITMAP, + D2D_TARGET_COMMAND_LIST, +}; + +struct d2d_indexed_objects +{ + struct + { + GUID id; + IUnknown *object; + } *elements; + size_t size; + size_t count; +}; + struct d2d_device_context { - ID2D1DeviceContext ID2D1DeviceContext_iface; + ID2D1DeviceContext6 ID2D1DeviceContext6_iface; ID2D1GdiInteropRenderTarget ID2D1GdiInteropRenderTarget_iface; IDWriteTextRenderer IDWriteTextRenderer_iface; IUnknown IUnknown_iface; @@ -162,20 +182,31 @@ struct d2d_device_context const struct d2d_device_context_ops *ops; ID2D1Factory *factory; - ID2D1Device *device; - ID3D10Device *d3d_device; - struct d2d_bitmap *target; - ID3D10StateBlock *stateblock; + CRITICAL_SECTION *cs; + struct d2d_device *device; + ID3D11Device1 *d3d_device; + ID3DDeviceContextState *d3d_state; + struct + { + ID2D1Image *object; + enum d2d_device_context_target_type type; + union + { + struct d2d_bitmap *bitmap; + struct d2d_command_list *command_list; + }; + HDC hdc; + } target; struct d2d_shape_resources shape_resources[D2D_SHAPE_TYPE_COUNT]; - ID3D10Buffer *vs_cb; - ID3D10PixelShader *ps; - ID3D10Buffer *ps_cb; - ID3D10Buffer *ib; + ID3D11Buffer *vs_cb; + ID3D11PixelShader *ps; + ID3D11Buffer *ps_cb; + ID3D11Buffer *ib; unsigned int vb_stride; - ID3D10Buffer *vb; - ID3D10RasterizerState *rs; - ID3D10BlendState *bs; - ID3D10SamplerState *sampler_states + ID3D11Buffer *vb; + ID3D11RasterizerState *rs; + ID3D11BlendState *bs; + ID3D11SamplerState *sampler_states [D2D_SAMPLER_INTERPOLATION_MODE_COUNT] [D2D_SAMPLER_EXTEND_MODE_COUNT] [D2D_SAMPLER_EXTEND_MODE_COUNT]; @@ -188,11 +219,13 @@ struct d2d_device_context D2D1_RENDER_TARGET_PROPERTIES desc; D2D1_SIZE_U pixel_size; struct d2d_clip_stack clip_stack; + + struct d2d_indexed_objects vertex_buffers; }; -HRESULT d2d_d3d_create_render_target(ID2D1Device *device, IDXGISurface *surface, IUnknown *outer_unknown, +HRESULT d2d_d3d_create_render_target(struct d2d_device *device, IDXGISurface *surface, IUnknown *outer_unknown, const struct d2d_device_context_ops *ops, const D2D1_RENDER_TARGET_PROPERTIES *desc, - void **render_target) DECLSPEC_HIDDEN; + void **render_target); static inline BOOL d2d_device_context_is_dxgi_target(const struct d2d_device_context *context) { @@ -216,7 +249,7 @@ struct d2d_wic_render_target }; HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, ID2D1Factory1 *factory, - ID3D10Device1 *d3d_device, IWICBitmap *bitmap, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN; + ID3D10Device1 *d3d_device, IWICBitmap *bitmap, const D2D1_RENDER_TARGET_PROPERTIES *desc); struct d2d_dc_render_target { @@ -224,17 +257,18 @@ struct d2d_dc_render_target LONG refcount; IDXGISurface1 *dxgi_surface; - D2D1_PIXEL_FORMAT pixel_format; ID3D10Device1 *d3d_device; ID2D1RenderTarget *dxgi_target; IUnknown *dxgi_inner; RECT dst_rect; HDC hdc; + + D2D1_RENDER_TARGET_PROPERTIES desc; }; HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID2D1Factory1 *factory, - ID3D10Device1 *d3d_device, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN; + ID3D10Device1 *d3d_device, const D2D1_RENDER_TARGET_PROPERTIES *desc); struct d2d_hwnd_render_target { @@ -246,11 +280,13 @@ struct d2d_hwnd_render_target IDXGISwapChain *swapchain; UINT sync_interval; HWND hwnd; + + D2D1_RENDER_TARGET_PROPERTIES desc; }; HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target, ID2D1Factory1 *factory, ID3D10Device1 *d3d_device, const D2D1_RENDER_TARGET_PROPERTIES *desc, - const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_desc) DECLSPEC_HIDDEN; + const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_desc); struct d2d_bitmap_render_target { @@ -265,7 +301,7 @@ struct d2d_bitmap_render_target HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_target, const struct d2d_device_context *parent_target, const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format, - D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options) DECLSPEC_HIDDEN; + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options); struct d2d_gradient { @@ -273,14 +309,14 @@ struct d2d_gradient LONG refcount; ID2D1Factory *factory; - ID3D10ShaderResourceView *view; + ID3D11ShaderResourceView *view; D2D1_GRADIENT_STOP *stops; UINT32 stop_count; }; -HRESULT d2d_gradient_create(ID2D1Factory *factory, ID3D10Device *device, const D2D1_GRADIENT_STOP *stops, +HRESULT d2d_gradient_create(ID2D1Factory *factory, ID3D11Device1 *device, const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode, - struct d2d_gradient **gradient) DECLSPEC_HIDDEN; + struct d2d_gradient **gradient); struct d2d_brush { @@ -318,38 +354,50 @@ struct d2d_brush D2D1_EXTEND_MODE extend_mode_y; D2D1_INTERPOLATION_MODE interpolation_mode; } bitmap; + struct + { + ID2D1Image *image; + D2D1_EXTEND_MODE extend_mode_x; + D2D1_EXTEND_MODE extend_mode_y; + D2D1_INTERPOLATION_MODE interpolation_mode; + D2D1_RECT_F source_rect; + } image; } u; }; HRESULT d2d_solid_color_brush_create(ID2D1Factory *factory, const D2D1_COLOR_F *color, - const D2D1_BRUSH_PROPERTIES *desc, struct d2d_brush **brush) DECLSPEC_HIDDEN; + const D2D1_BRUSH_PROPERTIES *desc, struct d2d_brush **brush); HRESULT d2d_linear_gradient_brush_create(ID2D1Factory *factory, const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, - ID2D1GradientStopCollection *gradient, struct d2d_brush **brush) DECLSPEC_HIDDEN; + ID2D1GradientStopCollection *gradient, struct d2d_brush **brush); HRESULT d2d_radial_gradient_brush_create(ID2D1Factory *factory, const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, - ID2D1GradientStopCollection *gradient, struct d2d_brush **brush) DECLSPEC_HIDDEN; + ID2D1GradientStopCollection *gradient, struct d2d_brush **brush); HRESULT d2d_bitmap_brush_create(ID2D1Factory *factory, ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES1 *bitmap_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, - struct d2d_brush **brush) DECLSPEC_HIDDEN; + struct d2d_brush **brush); +HRESULT d2d_image_brush_create(ID2D1Factory *factory, ID2D1Image *image, + const D2D1_IMAGE_BRUSH_PROPERTIES *image_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, + struct d2d_brush **brush); void d2d_brush_bind_resources(struct d2d_brush *brush, struct d2d_device_context *context, - unsigned int brush_idx) DECLSPEC_HIDDEN; -BOOL d2d_brush_fill_cb(const struct d2d_brush *brush, struct d2d_brush_cb *cb) DECLSPEC_HIDDEN; -struct d2d_brush *unsafe_impl_from_ID2D1Brush(ID2D1Brush *iface) DECLSPEC_HIDDEN; + unsigned int brush_idx); +BOOL d2d_brush_fill_cb(const struct d2d_brush *brush, struct d2d_brush_cb *cb); +struct d2d_brush *unsafe_impl_from_ID2D1Brush(ID2D1Brush *iface); struct d2d_stroke_style { - ID2D1StrokeStyle ID2D1StrokeStyle_iface; + ID2D1StrokeStyle1 ID2D1StrokeStyle1_iface; LONG refcount; ID2D1Factory *factory; - D2D1_STROKE_STYLE_PROPERTIES desc; + D2D1_STROKE_STYLE_PROPERTIES1 desc; float *dashes; UINT32 dash_count; }; HRESULT d2d_stroke_style_init(struct d2d_stroke_style *style, ID2D1Factory *factory, - const D2D1_STROKE_STYLE_PROPERTIES *desc, const float *dashes, UINT32 dash_count) DECLSPEC_HIDDEN; + const D2D1_STROKE_STYLE_PROPERTIES1 *desc, const float *dashes, UINT32 dash_count); +struct d2d_stroke_style *unsafe_impl_from_ID2D1StrokeStyle(ID2D1StrokeStyle *iface); struct d2d_layer { @@ -360,7 +408,7 @@ struct d2d_layer D2D1_SIZE_F size; }; -HRESULT d2d_layer_create(ID2D1Factory *factory, const D2D1_SIZE_F *size, struct d2d_layer **layer) DECLSPEC_HIDDEN; +HRESULT d2d_layer_create(ID2D1Factory *factory, const D2D1_SIZE_F *size, struct d2d_layer **layer); struct d2d_mesh { @@ -370,7 +418,7 @@ struct d2d_mesh ID2D1Factory *factory; }; -HRESULT d2d_mesh_create(ID2D1Factory *factory, struct d2d_mesh **mesh) DECLSPEC_HIDDEN; +HRESULT d2d_mesh_create(ID2D1Factory *factory, struct d2d_mesh **mesh); struct d2d_bitmap { @@ -378,10 +426,11 @@ struct d2d_bitmap LONG refcount; ID2D1Factory *factory; - ID3D10ShaderResourceView *srv; - ID3D10RenderTargetView *rtv; + ID3D11ShaderResourceView *srv; + ID3D11RenderTargetView *rtv; IDXGISurface *surface; - ID3D10Resource *resource; + ID3D11Resource *resource; + D3D11_MAPPED_SUBRESOURCE mapped_resource; D2D1_SIZE_U pixel_size; D2D1_PIXEL_FORMAT format; float dpi_x; @@ -390,12 +439,13 @@ struct d2d_bitmap }; HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size, const void *src_data, - UINT32 pitch, const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; + UINT32 pitch, const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap); HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, void *data, - const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; + const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap); HRESULT d2d_bitmap_create_from_wic_bitmap(struct d2d_device_context *context, IWICBitmapSource *bitmap_source, - const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; -struct d2d_bitmap *unsafe_impl_from_ID2D1Bitmap(ID2D1Bitmap *iface) DECLSPEC_HIDDEN; + const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap); +unsigned int d2d_get_bitmap_options_for_surface(IDXGISurface *surface); +struct d2d_bitmap *unsafe_impl_from_ID2D1Bitmap(ID2D1Bitmap *iface); struct d2d_state_block { @@ -408,8 +458,8 @@ struct d2d_state_block }; void d2d_state_block_init(struct d2d_state_block *state_block, ID2D1Factory *factory, - const D2D1_DRAWING_STATE_DESCRIPTION1 *desc, IDWriteRenderingParams *text_rendering_params) DECLSPEC_HIDDEN; -struct d2d_state_block *unsafe_impl_from_ID2D1DrawingStateBlock(ID2D1DrawingStateBlock *iface) DECLSPEC_HIDDEN; + const D2D1_DRAWING_STATE_DESCRIPTION1 *desc, IDWriteRenderingParams *text_rendering_params); +struct d2d_state_block *unsafe_impl_from_ID2D1DrawingStateBlock(ID2D1DrawingStateBlock *iface); enum d2d_geometry_state { @@ -545,35 +595,300 @@ struct d2d_geometry }; HRESULT d2d_ellipse_geometry_init(struct d2d_geometry *geometry, - ID2D1Factory *factory, const D2D1_ELLIPSE *ellipse) DECLSPEC_HIDDEN; -void d2d_path_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *factory) DECLSPEC_HIDDEN; + ID2D1Factory *factory, const D2D1_ELLIPSE *ellipse); +void d2d_path_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *factory); HRESULT d2d_rectangle_geometry_init(struct d2d_geometry *geometry, - ID2D1Factory *factory, const D2D1_RECT_F *rect) DECLSPEC_HIDDEN; + ID2D1Factory *factory, const D2D1_RECT_F *rect); HRESULT d2d_rounded_rectangle_geometry_init(struct d2d_geometry *geometry, - ID2D1Factory *factory, const D2D1_ROUNDED_RECT *rounded_rect) DECLSPEC_HIDDEN; + ID2D1Factory *factory, const D2D1_ROUNDED_RECT *rounded_rect); void d2d_transformed_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *factory, - ID2D1Geometry *src_geometry, const D2D_MATRIX_3X2_F *transform) DECLSPEC_HIDDEN; + ID2D1Geometry *src_geometry, const D2D_MATRIX_3X2_F *transform); HRESULT d2d_geometry_group_init(struct d2d_geometry *geometry, ID2D1Factory *factory, - D2D1_FILL_MODE fill_mode, ID2D1Geometry **src_geometries, unsigned int geometry_count) DECLSPEC_HIDDEN; -struct d2d_geometry *unsafe_impl_from_ID2D1Geometry(ID2D1Geometry *iface) DECLSPEC_HIDDEN; + D2D1_FILL_MODE fill_mode, ID2D1Geometry **src_geometries, unsigned int geometry_count); +struct d2d_geometry *unsafe_impl_from_ID2D1Geometry(ID2D1Geometry *iface); struct d2d_device { - ID2D1Device ID2D1Device_iface; + ID2D1Device6 ID2D1Device6_iface; LONG refcount; ID2D1Factory1 *factory; IDXGIDevice *dxgi_device; + + struct d2d_indexed_objects shaders; +}; + +struct d2d_device *unsafe_impl_from_ID2D1Device(ID2D1Device1 *iface); +HRESULT d2d_device_add_indexed_object(struct d2d_indexed_objects *objects, const GUID *id, + IUnknown *object); +BOOL d2d_device_get_indexed_object(struct d2d_indexed_objects *objects, const GUID *id, + IUnknown **object); +void d2d_device_indexed_objects_clear(struct d2d_indexed_objects *objects); + +struct d2d_effect_context +{ + ID2D1EffectContext ID2D1EffectContext_iface; + LONG refcount; + + struct d2d_device_context *device_context; +}; + +void d2d_effect_context_init(struct d2d_effect_context *effect_context, + struct d2d_device_context *device_context); + +struct d2d_effect_property +{ + WCHAR *name; + D2D1_PROPERTY_TYPE type; + UINT32 index; + BOOL readonly; + union + { + size_t offset; + void *ptr; + } data; + UINT32 size; + PD2D1_PROPERTY_SET_FUNCTION set_function; + PD2D1_PROPERTY_GET_FUNCTION get_function; + struct d2d_effect_properties *subproperties; +}; + +struct d2d_effect_properties +{ + ID2D1Properties ID2D1Properties_iface; + LONG refcount; + struct d2d_effect *effect; + + struct d2d_effect_property *properties; + size_t offset; + size_t size; + size_t count; + size_t custom_count; + struct + { + BYTE *ptr; + size_t size; + size_t count; + } data; +}; + +struct d2d_effect_registration +{ + struct list entry; + PD2D1_EFFECT_FACTORY factory; + UINT32 registration_count; + BOOL builtin; + CLSID id; + + struct d2d_effect_properties *properties; +}; + +struct d2d_factory +{ + ID2D1Factory7 ID2D1Factory7_iface; + ID2D1Multithread ID2D1Multithread_iface; + LONG refcount; + + ID3D10Device1 *device; + + float dpi_x; + float dpi_y; + + struct list effects; + INIT_ONCE init_builtins; + + CRITICAL_SECTION cs; + D2D1_FACTORY_TYPE factory_type; +}; + +static inline struct d2d_factory *unsafe_impl_from_ID2D1Factory(ID2D1Factory *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_factory, ID2D1Factory7_iface); +} + +void d2d_effects_init_builtins(struct d2d_factory *factory); +struct d2d_effect_registration * d2d_factory_get_registered_effect(ID2D1Factory *factory, + const GUID *effect_id); +void d2d_factory_register_effect(struct d2d_factory *factory, + struct d2d_effect_registration *effect); +HRESULT d2d_effect_property_get_uint32_value(const struct d2d_effect_properties *properties, + const struct d2d_effect_property *prop, UINT32 *value); +void d2d_device_init(struct d2d_device *device, struct d2d_factory *factory, IDXGIDevice *dxgi_device); + +struct d2d_transform +{ + ID2D1TransformNode ID2D1TransformNode_iface; + LONG refcount; + + union + { + D2D1_POINT_2L offset; + D2D1_BLEND_DESCRIPTION blend_desc; + struct + { + D2D1_EXTEND_MODE mode_x; + D2D1_EXTEND_MODE mode_y; + } border; + D2D1_RECT_L bounds; + }; + + UINT32 input_count; +}; + +enum d2d_render_info_mask +{ + D2D_RENDER_INFO_PIXEL_SHADER = 0x1, }; -void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *factory, IDXGIDevice *dxgi_device) DECLSPEC_HIDDEN; +struct d2d_render_info +{ + ID2D1DrawInfo ID2D1DrawInfo_iface; + LONG refcount; + + unsigned int mask; + GUID pixel_shader; +}; + +struct d2d_transform_node +{ + struct list entry; + ID2D1TransformNode *object; + struct d2d_render_info *render_info; + struct d2d_transform_node **inputs; + unsigned int input_count; + struct d2d_transform_node *output; +}; + +struct d2d_transform_node_connection +{ + struct d2d_transform_node *node; + unsigned int index; +}; + +struct d2d_transform_graph +{ + ID2D1TransformGraph ID2D1TransformGraph_iface; + LONG refcount; + + struct d2d_transform_node_connection *inputs; + unsigned int input_count; + + struct d2d_transform_node *output; + + bool passthrough; + unsigned int passthrough_input; + + struct list nodes; +}; struct d2d_effect { ID2D1Effect ID2D1Effect_iface; + ID2D1Image ID2D1Image_iface; + LONG refcount; + + ID2D1EffectImpl *impl; + struct d2d_effect_properties properties; + struct d2d_effect_context *effect_context; + struct d2d_transform_graph *graph; + ID2D1Image **inputs; + size_t inputs_size; + size_t input_count; +}; + +HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effect_id, + ID2D1Effect **effect); +void d2d_effect_init_properties(struct d2d_effect *effect, struct d2d_effect_properties *properties); +HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCHAR *name, + UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value); +HRESULT d2d_effect_subproperties_add(struct d2d_effect_properties *props, const WCHAR *name, + UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value); +struct d2d_effect_property * d2d_effect_properties_get_property_by_name( + const struct d2d_effect_properties *properties, const WCHAR *name); +void d2d_effect_properties_cleanup(struct d2d_effect_properties *props); +HRESULT d2d_factory_register_builtin_effect(struct d2d_factory *factory, REFCLSID effect_id, + const WCHAR *property_xml, const D2D1_PROPERTY_BINDING *bindings, UINT32 binding_count, + PD2D1_EFFECT_FACTORY effect_factory); + +struct d2d_vertex_buffer +{ + ID2D1VertexBuffer ID2D1VertexBuffer_iface; + LONG refcount; +}; + +enum d2d_command_list_state +{ + D2D_COMMAND_LIST_STATE_INITIAL = 0, + D2D_COMMAND_LIST_STATE_ERROR, + D2D_COMMAND_LIST_STATE_OPEN, + D2D_COMMAND_LIST_STATE_CLOSED, +}; + +struct d2d_command_list +{ + ID2D1CommandList ID2D1CommandList_iface; LONG refcount; + + ID2D1Factory *factory; + enum d2d_command_list_state state; + unsigned int flags; + + size_t size; + size_t capacity; + void *data; + + size_t objects_count; + size_t objects_capacity; + IUnknown **objects; }; -void d2d_effect_init(struct d2d_effect *effect) DECLSPEC_HIDDEN; +HRESULT d2d_command_list_create(ID2D1Factory *factory, struct d2d_command_list **command_list); +struct d2d_command_list *unsafe_impl_from_ID2D1CommandList(ID2D1CommandList *iface); +void d2d_command_list_begin_draw(struct d2d_command_list *command_list, const struct d2d_device_context *context); +void d2d_command_list_set_antialias_mode(struct d2d_command_list *command_list, D2D1_ANTIALIAS_MODE mode); +void d2d_command_list_set_primitive_blend(struct d2d_command_list *command_list, + D2D1_PRIMITIVE_BLEND primitive_blend); +void d2d_command_list_set_unit_mode(struct d2d_command_list *command_list, D2D1_UNIT_MODE mode); +void d2d_command_list_set_text_antialias_mode(struct d2d_command_list *command_list, + D2D1_TEXT_ANTIALIAS_MODE mode); +void d2d_command_list_set_tags(struct d2d_command_list *command_list, D2D1_TAG tag1, D2D1_TAG tag2); +void d2d_command_list_set_transform(struct d2d_command_list *command_list, + const D2D1_MATRIX_3X2_F *transform); +void d2d_command_list_push_clip(struct d2d_command_list *command_list, const D2D1_RECT_F *rect, + D2D1_ANTIALIAS_MODE antialias_mode); +void d2d_command_list_pop_clip(struct d2d_command_list *command_list); +void d2d_command_list_clear(struct d2d_command_list *command_list, const D2D1_COLOR_F *color); +void d2d_command_list_draw_line(struct d2d_command_list *command_list, const struct d2d_device_context *context, + D2D1_POINT_2F p0, D2D1_POINT_2F p1, ID2D1Brush *orig_brush, float stroke_width, + ID2D1StrokeStyle *stroke_style); +void d2d_command_list_draw_geometry(struct d2d_command_list *command_list, + const struct d2d_device_context *context, ID2D1Geometry *geometry, ID2D1Brush *orig_brush, + float stroke_width, ID2D1StrokeStyle *stroke_style); +void d2d_command_list_draw_rectangle(struct d2d_command_list *command_list, const struct d2d_device_context *context, + const D2D1_RECT_F *rect, ID2D1Brush *orig_brush, float stroke_width, ID2D1StrokeStyle *stroke_style); +void d2d_command_list_fill_geometry(struct d2d_command_list *command_list, + const struct d2d_device_context *context, ID2D1Geometry *geometry, ID2D1Brush *orig_brush, + ID2D1Brush *orig_opacity_brush); +void d2d_command_list_fill_rectangle(struct d2d_command_list *command_list, + const struct d2d_device_context *context, const D2D1_RECT_F *rect, ID2D1Brush *orig_brush); +void d2d_command_list_set_text_rendering_params(struct d2d_command_list *command_list, + IDWriteRenderingParams *params); +void d2d_command_list_draw_glyph_run(struct d2d_command_list *command_list, + const struct d2d_device_context *context, D2D1_POINT_2F origin, const DWRITE_GLYPH_RUN *run, + const DWRITE_GLYPH_RUN_DESCRIPTION *run_desc, ID2D1Brush *orig_brush, + DWRITE_MEASURING_MODE measuring_mode); +void d2d_command_list_draw_bitmap(struct d2d_command_list *command_list, ID2D1Bitmap *bitmap, + const D2D1_RECT_F *dst_rect, float opacity, D2D1_INTERPOLATION_MODE interpolation_mode, + const D2D1_RECT_F *src_rect, const D2D1_MATRIX_4X4_F *perspective_transform); +void d2d_command_list_draw_image(struct d2d_command_list *command_list, ID2D1Image *image, + const D2D1_POINT_2F *target_offset, const D2D1_RECT_F *image_rect, D2D1_INTERPOLATION_MODE interpolation_mode, + D2D1_COMPOSITE_MODE composite_mode); +void d2d_command_list_fill_mesh(struct d2d_command_list *command_list, const struct d2d_device_context *context, + ID2D1Mesh *mesh, ID2D1Brush *orig_brush); +void d2d_command_list_fill_opacity_mask(struct d2d_command_list *command_list, const struct d2d_device_context *context, + ID2D1Bitmap *bitmap, ID2D1Brush *orig_brush, const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect); +void d2d_command_list_push_layer(struct d2d_command_list *command_list, const struct d2d_device_context *context, + const D2D1_LAYER_PARAMETERS1 *params, ID2D1Layer *layer); +void d2d_command_list_pop_layer(struct d2d_command_list *command_list); static inline BOOL d2d_array_reserve(void **elements, size_t *capacity, size_t count, size_t size) { @@ -593,7 +908,7 @@ static inline BOOL d2d_array_reserve(void **elements, size_t *capacity, size_t c if (new_capacity < count) new_capacity = max_capacity; - if (!(new_elements = heap_realloc(*elements, new_capacity * size))) + if (!(new_elements = realloc(*elements, new_capacity * size))) return FALSE; *elements = new_elements; @@ -678,6 +993,13 @@ static inline const char *debug_d2d_point_2f(const D2D1_POINT_2F *point) return wine_dbg_sprintf("{%.8e, %.8e}", point->x, point->y); } +static inline const char *debug_d2d_point_2l(const D2D1_POINT_2L *point) +{ + if (!point) + return "(null)"; + return wine_dbg_sprintf("{%ld, %ld}", point->x, point->y); +} + static inline const char *debug_d2d_rect_f(const D2D1_RECT_F *rect) { if (!rect) @@ -685,6 +1007,13 @@ static inline const char *debug_d2d_rect_f(const D2D1_RECT_F *rect) return wine_dbg_sprintf("(%.8e, %.8e)-(%.8e, %.8e)", rect->left, rect->top, rect->right, rect->bottom); } +static inline const char *debug_d2d_rect_l(const D2D1_RECT_L *rect) +{ + if (!rect) + return "(null)"; + return wine_dbg_sprintf("(%ld, %ld)-(%ld, %ld)", rect->left, rect->top, rect->right, rect->bottom); +} + static inline const char *debug_d2d_rounded_rect(const D2D1_ROUNDED_RECT *rounded_rect) { if (!rounded_rect) diff --git a/wrappers/directx/wine/d2d1/dc_render_target.c b/wrappers/directx/wine/d2d1/dc_render_target.c index 47aa99697d..aa0c715baa 100644 --- a/wrappers/directx/wine/d2d1/dc_render_target.c +++ b/wrappers/directx/wine/d2d1/dc_render_target.c @@ -39,7 +39,7 @@ static HRESULT d2d_dc_render_target_present(IUnknown *outer_unknown) if (FAILED(hr = IDXGISurface1_GetDC(render_target->dxgi_surface, FALSE, &src_hdc))) { - WARN("GetDC() failed, %#x.\n", hr); + WARN("GetDC() failed, %#lx.\n", hr); return S_OK; } @@ -81,7 +81,7 @@ static ULONG STDMETHODCALLTYPE d2d_dc_render_target_AddRef(ID2D1DCRenderTarget * struct d2d_dc_render_target *render_target = impl_from_ID2D1DCRenderTarget(iface); ULONG refcount = InterlockedIncrement(&render_target->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -91,7 +91,7 @@ static ULONG STDMETHODCALLTYPE d2d_dc_render_target_Release(ID2D1DCRenderTarget struct d2d_dc_render_target *render_target = impl_from_ID2D1DCRenderTarget(iface); ULONG refcount = InterlockedDecrement(&render_target->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { @@ -99,7 +99,7 @@ static ULONG STDMETHODCALLTYPE d2d_dc_render_target_Release(ID2D1DCRenderTarget if (render_target->dxgi_surface) IDXGISurface1_Release(render_target->dxgi_surface); ID3D10Device1_Release(render_target->d3d_device); - heap_free(render_target); + free(render_target); } return refcount; @@ -673,10 +673,32 @@ static BOOL STDMETHODCALLTYPE d2d_dc_render_target_IsSupported(ID2D1DCRenderTarg const D2D1_RENDER_TARGET_PROPERTIES *desc) { struct d2d_dc_render_target *render_target = impl_from_ID2D1DCRenderTarget(iface); + const D2D1_RENDER_TARGET_PROPERTIES *target_desc = &render_target->desc; + D2D1_PIXEL_FORMAT pixel_format; TRACE("iface %p, desc %p.\n", iface, desc); - return ID2D1RenderTarget_IsSupported(render_target->dxgi_target, desc); + if (desc->type != D2D1_RENDER_TARGET_TYPE_DEFAULT + && target_desc->type != desc->type) + { + return FALSE; + } + + pixel_format = ID2D1RenderTarget_GetPixelFormat(render_target->dxgi_target); + + if (desc->pixelFormat.format != DXGI_FORMAT_UNKNOWN + && pixel_format.format != desc->pixelFormat.format) + { + return FALSE; + } + + if (desc->pixelFormat.alphaMode != D2D1_ALPHA_MODE_UNKNOWN + && pixel_format.alphaMode != desc->pixelFormat.alphaMode) + { + return FALSE; + } + + return (target_desc->usage & desc->usage) == desc->usage; } static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget *iface, @@ -689,11 +711,13 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget ID2D1DeviceContext *context; D2D1_SIZE_U bitmap_size; ID2D1Bitmap *bitmap; + DWORD obj_type; HRESULT hr; TRACE("iface %p, hdc %p, rect %s.\n", iface, hdc, wine_dbgstr_rect(rect)); - if (!hdc) + obj_type = GetObjectType(hdc); + if (obj_type != OBJ_DC && obj_type != OBJ_ENHMETADC && obj_type != OBJ_MEMDC) return E_INVALIDARG; /* Switch dxgi target to new surface. */ @@ -703,19 +727,19 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget bitmap_size.height = rect->bottom - rect->top; memset(&bitmap_desc, 0, sizeof(bitmap_desc)); - bitmap_desc.pixelFormat = render_target->pixel_format; + bitmap_desc.pixelFormat = render_target->desc.pixelFormat; bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE; if (FAILED(hr = ID2D1DeviceContext_CreateBitmap(context, bitmap_size, NULL, 0, &bitmap_desc, (ID2D1Bitmap1 **)&bitmap))) { - WARN("Failed to create target bitmap, hr %#x.\n", hr); + WARN("Failed to create target bitmap, hr %#lx.\n", hr); ID2D1DeviceContext_Release(context); return hr; } bitmap_impl = unsafe_impl_from_ID2D1Bitmap(bitmap); - ID3D10Resource_QueryInterface(bitmap_impl->resource, &IID_IDXGISurface1, (void **)&dxgi_surface); + ID3D11Resource_QueryInterface(bitmap_impl->resource, &IID_IDXGISurface1, (void **)&dxgi_surface); ID2D1DeviceContext_SetTarget(context, (ID2D1Image *)bitmap); ID2D1Bitmap_Release(bitmap); @@ -811,7 +835,9 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID SetRectEmpty(&render_target->dst_rect); render_target->hdc = NULL; - render_target->pixel_format = desc->pixelFormat; + render_target->desc = *desc; + render_target->desc.usage |= D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; + switch (desc->pixelFormat.format) { case DXGI_FORMAT_B8G8R8A8_UNORM: @@ -826,7 +852,7 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID if (FAILED(hr = ID3D10Device1_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&dxgi_device))) { - WARN("Failed to get DXGI device interface, hr %#x.\n", hr); + WARN("Failed to get DXGI device interface, hr %#lx.\n", hr); return hr; } @@ -834,23 +860,24 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID IDXGIDevice_Release(dxgi_device); if (FAILED(hr)) { - WARN("Failed to create D2D device, hr %#x.\n", hr); + WARN("Failed to create D2D device, hr %#lx.\n", hr); return hr; } - hr = d2d_d3d_create_render_target(device, NULL, (IUnknown *)&render_target->ID2D1DCRenderTarget_iface, - &d2d_dc_render_target_ops, desc, (void **)&render_target->dxgi_inner); + hr = d2d_d3d_create_render_target(unsafe_impl_from_ID2D1Device((ID2D1Device1* )device), NULL, + (IUnknown *)&render_target->ID2D1DCRenderTarget_iface, &d2d_dc_render_target_ops, + desc, (void **)&render_target->dxgi_inner); ID2D1Device_Release(device); if (FAILED(hr)) { - WARN("Failed to create DXGI surface render target, hr %#x.\n", hr); + WARN("Failed to create DXGI surface render target, hr %#lx.\n", hr); return hr; } if (FAILED(hr = IUnknown_QueryInterface(render_target->dxgi_inner, &IID_ID2D1RenderTarget, (void **)&render_target->dxgi_target))) { - WARN("Failed to retrieve ID2D1RenderTarget interface, hr %#x.\n", hr); + WARN("Failed to retrieve ID2D1RenderTarget interface, hr %#lx.\n", hr); IUnknown_Release(render_target->dxgi_inner); return hr; } diff --git a/wrappers/directx/wine/d2d1/device.c b/wrappers/directx/wine/d2d1/device.c index 2a0c094fb7..75da15c99a 100644 --- a/wrappers/directx/wine/d2d1/device.c +++ b/wrappers/directx/wine/d2d1/device.c @@ -17,6 +17,7 @@ */ #include "d2d1_private.h" +#include WINE_DEFAULT_DEBUG_CHANNEL(d2d); @@ -35,13 +36,11 @@ struct d2d_draw_text_layout_ctx D2D1_DRAW_TEXT_OPTIONS options; }; -static inline struct d2d_device *impl_from_ID2D1Device(ID2D1Device *iface) +static inline struct d2d_device *impl_from_ID2D1Device(ID2D1Device6 *iface) { - return CONTAINING_RECORD(iface, struct d2d_device, ID2D1Device_iface); + return CONTAINING_RECORD(iface, struct d2d_device, ID2D1Device6_iface); } -static struct d2d_device *unsafe_impl_from_ID2D1Device(ID2D1Device *iface); - static ID2D1Brush *d2d_draw_get_text_brush(struct d2d_draw_text_layout_ctx *context, IUnknown *effect) { ID2D1Brush *brush = NULL; @@ -81,7 +80,7 @@ static void d2d_size_set(D2D1_SIZE_U *dst, float width, float height) static BOOL d2d_clip_stack_init(struct d2d_clip_stack *stack) { - if (!(stack->stack = heap_alloc(INITIAL_CLIP_STACK_SIZE * sizeof(*stack->stack)))) + if (!(stack->stack = malloc(INITIAL_CLIP_STACK_SIZE * sizeof(*stack->stack)))) return FALSE; stack->size = INITIAL_CLIP_STACK_SIZE; @@ -92,7 +91,7 @@ static BOOL d2d_clip_stack_init(struct d2d_clip_stack *stack) static void d2d_clip_stack_cleanup(struct d2d_clip_stack *stack) { - heap_free(stack->stack); + free(stack->stack); } static BOOL d2d_clip_stack_push(struct d2d_clip_stack *stack, const D2D1_RECT_F *rect) @@ -118,15 +117,17 @@ static void d2d_clip_stack_pop(struct d2d_clip_stack *stack) } static void d2d_device_context_draw(struct d2d_device_context *render_target, enum d2d_shape_type shape_type, - ID3D10Buffer *ib, unsigned int index_count, ID3D10Buffer *vb, unsigned int vb_stride, + ID3D11Buffer *ib, unsigned int index_count, ID3D11Buffer *vb, unsigned int vb_stride, struct d2d_brush *brush, struct d2d_brush *opacity_brush) { struct d2d_shape_resources *shape_resources = &render_target->shape_resources[shape_type]; - ID3D10Device *device = render_target->d3d_device; - D3D10_RECT scissor_rect; + ID3DDeviceContextState *prev_state; + ID3D11Device1 *device = render_target->d3d_device; + ID3D11DeviceContext1 *context; + ID3D11Buffer *vs_cb = render_target->vs_cb, *ps_cb = render_target->ps_cb; + D3D11_RECT scissor_rect; unsigned int offset; - D3D10_VIEWPORT vp; - HRESULT hr; + D3D11_VIEWPORT vp; vp.TopLeftX = 0; vp.TopLeftY = 0; @@ -135,24 +136,22 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; - if (FAILED(hr = render_target->stateblock->lpVtbl->Capture(render_target->stateblock))) - { - WARN("Failed to capture stateblock, hr %#x.\n", hr); - return; - } + if (render_target->cs) + EnterCriticalSection(render_target->cs); - ID3D10Device_ClearState(device); + ID3D11Device1_GetImmediateContext1(device, &context); + ID3D11DeviceContext1_SwapDeviceContextState(context, render_target->d3d_state, &prev_state); - ID3D10Device_IASetInputLayout(device, shape_resources->il); - ID3D10Device_IASetPrimitiveTopology(device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D10Device_IASetIndexBuffer(device, ib, DXGI_FORMAT_R16_UINT, 0); + ID3D11DeviceContext1_IASetInputLayout(context, shape_resources->il); + ID3D11DeviceContext1_IASetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D11DeviceContext1_IASetIndexBuffer(context, ib, DXGI_FORMAT_R16_UINT, 0); offset = 0; - ID3D10Device_IASetVertexBuffers(device, 0, 1, &vb, &vb_stride, &offset); - ID3D10Device_VSSetConstantBuffers(device, 0, 1, &render_target->vs_cb); - ID3D10Device_VSSetShader(device, shape_resources->vs); - ID3D10Device_PSSetConstantBuffers(device, 0, 1, &render_target->ps_cb); - ID3D10Device_PSSetShader(device, render_target->ps); - ID3D10Device_RSSetViewports(device, 1, &vp); + ID3D11DeviceContext1_IASetVertexBuffers(context, 0, 1, &vb, &vb_stride, &offset); + ID3D11DeviceContext1_VSSetConstantBuffers(context, 0, 1, &vs_cb); + ID3D11DeviceContext1_VSSetShader(context, shape_resources->vs, NULL, 0); + ID3D11DeviceContext1_PSSetConstantBuffers(context, 0, 1, &ps_cb); + ID3D11DeviceContext1_PSSetShader(context, render_target->ps, NULL, 0); + ID3D11DeviceContext1_RSSetViewports(context, 1, &vp); if (render_target->clip_stack.count) { const D2D1_RECT_F *clip_rect; @@ -170,24 +169,32 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en scissor_rect.right = render_target->pixel_size.width; scissor_rect.bottom = render_target->pixel_size.height; } - ID3D10Device_RSSetScissorRects(device, 1, &scissor_rect); - ID3D10Device_RSSetState(device, render_target->rs); - ID3D10Device_OMSetRenderTargets(device, 1, &render_target->target->rtv, NULL); + ID3D11DeviceContext1_RSSetScissorRects(context, 1, &scissor_rect); + ID3D11DeviceContext1_RSSetState(context, render_target->rs); + ID3D11DeviceContext1_OMSetRenderTargets(context, 1, &render_target->target.bitmap->rtv, NULL); if (brush) { - ID3D10Device_OMSetBlendState(device, render_target->bs, NULL, D3D10_DEFAULT_SAMPLE_MASK); + ID3D11DeviceContext1_OMSetBlendState(context, render_target->bs, NULL, D3D11_DEFAULT_SAMPLE_MASK); d2d_brush_bind_resources(brush, render_target, 0); } + else + { + ID3D11DeviceContext1_OMSetBlendState(context, NULL, NULL, D3D11_DEFAULT_SAMPLE_MASK); + } if (opacity_brush) d2d_brush_bind_resources(opacity_brush, render_target, 1); if (ib) - ID3D10Device_DrawIndexed(device, index_count, 0, 0); + ID3D11DeviceContext1_DrawIndexed(context, index_count, 0, 0); else - ID3D10Device_Draw(device, index_count, 0); + ID3D11DeviceContext1_Draw(context, index_count, 0); - if (FAILED(hr = render_target->stateblock->lpVtbl->Apply(render_target->stateblock))) - WARN("Failed to apply stateblock, hr %#x.\n", hr); + ID3D11DeviceContext1_SwapDeviceContextState(context, prev_state, NULL); + ID3D11DeviceContext1_Release(context); + ID3DDeviceContextState_Release(prev_state); + + if (render_target->cs) + LeaveCriticalSection(render_target->cs); } static void d2d_device_context_set_error(struct d2d_device_context *context, HRESULT code) @@ -202,9 +209,9 @@ static inline struct d2d_device_context *impl_from_IUnknown(IUnknown *iface) return CONTAINING_RECORD(iface, struct d2d_device_context, IUnknown_iface); } -static inline struct d2d_device_context *impl_from_ID2D1DeviceContext(ID2D1DeviceContext *iface) +static inline struct d2d_device_context *impl_from_ID2D1DeviceContext(ID2D1DeviceContext6 *iface) { - return CONTAINING_RECORD(iface, struct d2d_device_context, ID2D1DeviceContext_iface); + return CONTAINING_RECORD(iface, struct d2d_device_context, ID2D1DeviceContext6_iface); } static HRESULT STDMETHODCALLTYPE d2d_device_context_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out) @@ -213,13 +220,19 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_inner_QueryInterface(IUnknow TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); - if (IsEqualGUID(iid, &IID_ID2D1DeviceContext) + if (IsEqualGUID(iid, &IID_ID2D1DeviceContext6) + || IsEqualGUID(iid, &IID_ID2D1DeviceContext5) + || IsEqualGUID(iid, &IID_ID2D1DeviceContext4) + || IsEqualGUID(iid, &IID_ID2D1DeviceContext3) + || IsEqualGUID(iid, &IID_ID2D1DeviceContext2) + || IsEqualGUID(iid, &IID_ID2D1DeviceContext1) + || IsEqualGUID(iid, &IID_ID2D1DeviceContext) || IsEqualGUID(iid, &IID_ID2D1RenderTarget) || IsEqualGUID(iid, &IID_ID2D1Resource) || IsEqualGUID(iid, &IID_IUnknown)) { - ID2D1DeviceContext_AddRef(&context->ID2D1DeviceContext_iface); - *out = &context->ID2D1DeviceContext_iface; + ID2D1DeviceContext6_AddRef(&context->ID2D1DeviceContext6_iface); + *out = &context->ID2D1DeviceContext6_iface; return S_OK; } else if (IsEqualGUID(iid, &IID_ID2D1GdiInteropRenderTarget)) @@ -240,7 +253,7 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_AddRef(IUnknown *iface) struct d2d_device_context *context = impl_from_IUnknown(iface); ULONG refcount = InterlockedIncrement(&context->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -250,7 +263,7 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface) struct d2d_device_context *context = impl_from_IUnknown(iface); ULONG refcount = InterlockedDecrement(&context->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { @@ -261,17 +274,17 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface) if (context->text_rendering_params) IDWriteRenderingParams_Release(context->text_rendering_params); if (context->bs) - ID3D10BlendState_Release(context->bs); - ID3D10RasterizerState_Release(context->rs); - ID3D10Buffer_Release(context->vb); - ID3D10Buffer_Release(context->ib); - ID3D10Buffer_Release(context->ps_cb); - ID3D10PixelShader_Release(context->ps); - ID3D10Buffer_Release(context->vs_cb); + ID3D11BlendState_Release(context->bs); + ID3D11RasterizerState_Release(context->rs); + ID3D11Buffer_Release(context->vb); + ID3D11Buffer_Release(context->ib); + ID3D11Buffer_Release(context->ps_cb); + ID3D11PixelShader_Release(context->ps); + ID3D11Buffer_Release(context->vs_cb); for (i = 0; i < D2D_SHAPE_TYPE_COUNT; ++i) { - ID3D10VertexShader_Release(context->shape_resources[i].vs); - ID3D10InputLayout_Release(context->shape_resources[i].il); + ID3D11VertexShader_Release(context->shape_resources[i].vs); + ID3D11InputLayout_Release(context->shape_resources[i].il); } for (i = 0; i < D2D_SAMPLER_INTERPOLATION_MODE_COUNT; ++i) { @@ -280,17 +293,19 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface) for (k = 0; k < D2D_SAMPLER_EXTEND_MODE_COUNT; ++k) { if (context->sampler_states[i][j][k]) - ID3D10SamplerState_Release(context->sampler_states[i][j][k]); + ID3D11SamplerState_Release(context->sampler_states[i][j][k]); } } } - context->stateblock->lpVtbl->Release(context->stateblock); - if (context->target) - ID2D1Bitmap1_Release(&context->target->ID2D1Bitmap1_iface); - ID3D10Device_Release(context->d3d_device); + if (context->d3d_state) + ID3DDeviceContextState_Release(context->d3d_state); + if (context->target.object) + IUnknown_Release(context->target.object); + ID3D11Device1_Release(context->d3d_device); ID2D1Factory_Release(context->factory); - ID2D1Device_Release(context->device); - heap_free(context); + ID2D1Device6_Release(&context->device->ID2D1Device6_iface); + d2d_device_indexed_objects_clear(&context->vertex_buffers); + free(context); } return refcount; @@ -303,7 +318,8 @@ static const struct IUnknownVtbl d2d_device_context_inner_unknown_vtbl = d2d_device_context_inner_Release, }; -static HRESULT STDMETHODCALLTYPE d2d_device_context_QueryInterface(ID2D1DeviceContext *iface, REFIID iid, void **out) +static HRESULT STDMETHODCALLTYPE d2d_device_context_QueryInterface(ID2D1DeviceContext6 *iface, + REFIID iid, void **out) { struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); @@ -312,7 +328,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_QueryInterface(ID2D1DeviceCo return IUnknown_QueryInterface(context->outer_unknown, iid, out); } -static ULONG STDMETHODCALLTYPE d2d_device_context_AddRef(ID2D1DeviceContext *iface) +static ULONG STDMETHODCALLTYPE d2d_device_context_AddRef(ID2D1DeviceContext6 *iface) { struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); @@ -321,7 +337,7 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_AddRef(ID2D1DeviceContext *ifa return IUnknown_AddRef(context->outer_unknown); } -static ULONG STDMETHODCALLTYPE d2d_device_context_Release(ID2D1DeviceContext *iface) +static ULONG STDMETHODCALLTYPE d2d_device_context_Release(ID2D1DeviceContext6 *iface) { struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); @@ -330,7 +346,7 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_Release(ID2D1DeviceContext *if return IUnknown_Release(context->outer_unknown); } -static void STDMETHODCALLTYPE d2d_device_context_GetFactory(ID2D1DeviceContext *iface, ID2D1Factory **factory) +static void STDMETHODCALLTYPE d2d_device_context_GetFactory(ID2D1DeviceContext6 *iface, ID2D1Factory **factory) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -340,7 +356,7 @@ static void STDMETHODCALLTYPE d2d_device_context_GetFactory(ID2D1DeviceContext * ID2D1Factory_AddRef(*factory); } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmap(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmap(ID2D1DeviceContext6 *iface, D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) { struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); @@ -364,7 +380,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmap(ID2D1DeviceCont return hr; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromWicBitmap(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromWicBitmap(ID2D1DeviceContext6 *iface, IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) { struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); @@ -388,7 +404,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromWicBitmap(ID return hr; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSharedBitmap(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSharedBitmap(ID2D1DeviceContext6 *iface, REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) { struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); @@ -402,7 +418,10 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSharedBitmap(ID2D1Devi if (desc) { memcpy(&bitmap_desc, desc, sizeof(*desc)); - bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW; + if (IsEqualIID(iid, &IID_IDXGISurface) || IsEqualIID(iid, &IID_IDXGISurface1)) + bitmap_desc.bitmapOptions = d2d_get_bitmap_options_for_surface(data); + else + bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW; bitmap_desc.colorContext = NULL; } @@ -412,7 +431,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSharedBitmap(ID2D1Devi return hr; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapBrush(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapBrush(ID2D1DeviceContext6 *iface, ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush **brush) { @@ -430,7 +449,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapBrush(ID2D1Devic return hr; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSolidColorBrush(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSolidColorBrush(ID2D1DeviceContext6 *iface, const D2D1_COLOR_F *color, const D2D1_BRUSH_PROPERTIES *desc, ID2D1SolidColorBrush **brush) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -445,7 +464,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSolidColorBrush(ID2D1D return hr; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateGradientStopCollection(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateGradientStopCollection(ID2D1DeviceContext6 *iface, const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode, ID2D1GradientStopCollection **gradient) { @@ -463,7 +482,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateGradientStopCollection return hr; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateLinearGradientBrush(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateLinearGradientBrush(ID2D1DeviceContext6 *iface, const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1GradientStopCollection *gradient, ID2D1LinearGradientBrush **brush) { @@ -481,7 +500,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateLinearGradientBrush(ID return hr; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateRadialGradientBrush(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateRadialGradientBrush(ID2D1DeviceContext6 *iface, const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1GradientStopCollection *gradient, ID2D1RadialGradientBrush **brush) { @@ -499,7 +518,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateRadialGradientBrush(ID return hr; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateCompatibleRenderTarget(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateCompatibleRenderTarget(ID2D1DeviceContext6 *iface, const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **rt) { @@ -510,14 +529,14 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateCompatibleRenderTarget TRACE("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p.\n", iface, size, pixel_size, format, options, rt); - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; if (FAILED(hr = d2d_bitmap_render_target_init(object, render_target, size, pixel_size, format, options))) { - WARN("Failed to initialize render target, hr %#x.\n", hr); - heap_free(object); + WARN("Failed to initialise render target, hr %#lx.\n", hr); + free(object); return hr; } @@ -527,7 +546,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateCompatibleRenderTarget return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateLayer(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateLayer(ID2D1DeviceContext6 *iface, const D2D1_SIZE_F *size, ID2D1Layer **layer) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -542,7 +561,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateLayer(ID2D1DeviceConte return hr; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateMesh(ID2D1DeviceContext *iface, ID2D1Mesh **mesh) +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateMesh(ID2D1DeviceContext6 *iface, ID2D1Mesh **mesh) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); struct d2d_mesh *object; @@ -556,10 +575,10 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateMesh(ID2D1DeviceContex return hr; } -static void STDMETHODCALLTYPE d2d_device_context_DrawLine(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_DrawLine(ID2D1DeviceContext6 *iface, D2D1_POINT_2F p0, D2D1_POINT_2F p1, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) { - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); ID2D1PathGeometry *geometry; ID2D1GeometrySink *sink; HRESULT hr; @@ -567,15 +586,21 @@ static void STDMETHODCALLTYPE d2d_device_context_DrawLine(ID2D1DeviceContext *if TRACE("iface %p, p0 %s, p1 %s, brush %p, stroke_width %.8e, stroke_style %p.\n", iface, debug_d2d_point_2f(&p0), debug_d2d_point_2f(&p1), brush, stroke_width, stroke_style); - if (FAILED(hr = ID2D1Factory_CreatePathGeometry(render_target->factory, &geometry))) + if (context->target.type == D2D_TARGET_COMMAND_LIST) + { + d2d_command_list_draw_line(context->target.command_list, context, p0, p1, brush, stroke_width, stroke_style); + return; + } + + if (FAILED(hr = ID2D1Factory_CreatePathGeometry(context->factory, &geometry))) { - WARN("Failed to create path geometry, %#x.\n", hr); + WARN("Failed to create path geometry, hr %#lx.\n", hr); return; } if (FAILED(hr = ID2D1PathGeometry_Open(geometry, &sink))) { - WARN("Open() failed, %#x.\n", hr); + WARN("Failed to open geometry sink, hr %#lx.\n", hr); ID2D1PathGeometry_Release(geometry); return; } @@ -584,53 +609,65 @@ static void STDMETHODCALLTYPE d2d_device_context_DrawLine(ID2D1DeviceContext *if ID2D1GeometrySink_AddLine(sink, p1); ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN); if (FAILED(hr = ID2D1GeometrySink_Close(sink))) - WARN("Close() failed, %#x.\n", hr); + WARN("Failed to close geometry sink, hr %#lx.\n", hr); ID2D1GeometrySink_Release(sink); - ID2D1DeviceContext_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style); + ID2D1DeviceContext6_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style); ID2D1PathGeometry_Release(geometry); } -static void STDMETHODCALLTYPE d2d_device_context_DrawRectangle(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_DrawRectangle(ID2D1DeviceContext6 *iface, const D2D1_RECT_F *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) { - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); ID2D1RectangleGeometry *geometry; HRESULT hr; TRACE("iface %p, rect %s, brush %p, stroke_width %.8e, stroke_style %p.\n", iface, debug_d2d_rect_f(rect), brush, stroke_width, stroke_style); - if (FAILED(hr = ID2D1Factory_CreateRectangleGeometry(render_target->factory, rect, &geometry))) + if (context->target.type == D2D_TARGET_COMMAND_LIST) + { + d2d_command_list_draw_rectangle(context->target.command_list, context, rect, brush, stroke_width, stroke_style); + return; + } + + if (FAILED(hr = ID2D1Factory_CreateRectangleGeometry(context->factory, rect, &geometry))) { - ERR("Failed to create geometry, hr %#x.\n", hr); + ERR("Failed to create geometry, hr %#lx.\n", hr); return; } - ID2D1DeviceContext_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style); + ID2D1DeviceContext6_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style); ID2D1RectangleGeometry_Release(geometry); } -static void STDMETHODCALLTYPE d2d_device_context_FillRectangle(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_FillRectangle(ID2D1DeviceContext6 *iface, const D2D1_RECT_F *rect, ID2D1Brush *brush) { - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); ID2D1RectangleGeometry *geometry; HRESULT hr; TRACE("iface %p, rect %s, brush %p.\n", iface, debug_d2d_rect_f(rect), brush); - if (FAILED(hr = ID2D1Factory_CreateRectangleGeometry(render_target->factory, rect, &geometry))) + if (context->target.type == D2D_TARGET_COMMAND_LIST) + { + d2d_command_list_fill_rectangle(context->target.command_list, context, rect, brush); + return; + } + + if (FAILED(hr = ID2D1Factory_CreateRectangleGeometry(context->factory, rect, &geometry))) { - ERR("Failed to create geometry, hr %#x.\n", hr); + ERR("Failed to create geometry, hr %#lx.\n", hr); return; } - ID2D1DeviceContext_FillGeometry(iface, (ID2D1Geometry *)geometry, brush, NULL); + ID2D1DeviceContext6_FillGeometry(iface, (ID2D1Geometry *)geometry, brush, NULL); ID2D1RectangleGeometry_Release(geometry); } -static void STDMETHODCALLTYPE d2d_device_context_DrawRoundedRectangle(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_DrawRoundedRectangle(ID2D1DeviceContext6 *iface, const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -642,15 +679,15 @@ static void STDMETHODCALLTYPE d2d_device_context_DrawRoundedRectangle(ID2D1Devic if (FAILED(hr = ID2D1Factory_CreateRoundedRectangleGeometry(render_target->factory, rect, &geometry))) { - ERR("Failed to create geometry, hr %#x.\n", hr); + ERR("Failed to create geometry, hr %#lx.\n", hr); return; } - ID2D1DeviceContext_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style); + ID2D1DeviceContext6_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style); ID2D1RoundedRectangleGeometry_Release(geometry); } -static void STDMETHODCALLTYPE d2d_device_context_FillRoundedRectangle(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_FillRoundedRectangle(ID2D1DeviceContext6 *iface, const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -661,15 +698,15 @@ static void STDMETHODCALLTYPE d2d_device_context_FillRoundedRectangle(ID2D1Devic if (FAILED(hr = ID2D1Factory_CreateRoundedRectangleGeometry(render_target->factory, rect, &geometry))) { - ERR("Failed to create geometry, hr %#x.\n", hr); + ERR("Failed to create geometry, hr %#lx.\n", hr); return; } - ID2D1DeviceContext_FillGeometry(iface, (ID2D1Geometry *)geometry, brush, NULL); + ID2D1DeviceContext6_FillGeometry(iface, (ID2D1Geometry *)geometry, brush, NULL); ID2D1RoundedRectangleGeometry_Release(geometry); } -static void STDMETHODCALLTYPE d2d_device_context_DrawEllipse(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_DrawEllipse(ID2D1DeviceContext6 *iface, const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -681,15 +718,15 @@ static void STDMETHODCALLTYPE d2d_device_context_DrawEllipse(ID2D1DeviceContext if (FAILED(hr = ID2D1Factory_CreateEllipseGeometry(render_target->factory, ellipse, &geometry))) { - ERR("Failed to create geometry, hr %#x.\n", hr); + ERR("Failed to create geometry, hr %#lx.\n", hr); return; } - ID2D1DeviceContext_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style); + ID2D1DeviceContext6_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style); ID2D1EllipseGeometry_Release(geometry); } -static void STDMETHODCALLTYPE d2d_device_context_FillEllipse(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_FillEllipse(ID2D1DeviceContext6 *iface, const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -700,26 +737,33 @@ static void STDMETHODCALLTYPE d2d_device_context_FillEllipse(ID2D1DeviceContext if (FAILED(hr = ID2D1Factory_CreateEllipseGeometry(render_target->factory, ellipse, &geometry))) { - ERR("Failed to create geometry, hr %#x.\n", hr); + ERR("Failed to create geometry, hr %#lx.\n", hr); return; } - ID2D1DeviceContext_FillGeometry(iface, (ID2D1Geometry *)geometry, brush, NULL); + ID2D1DeviceContext6_FillGeometry(iface, (ID2D1Geometry *)geometry, brush, NULL); ID2D1EllipseGeometry_Release(geometry); } static HRESULT d2d_device_context_update_ps_cb(struct d2d_device_context *context, struct d2d_brush *brush, struct d2d_brush *opacity_brush, BOOL outline, BOOL is_arc) { + D3D11_MAPPED_SUBRESOURCE map_desc; + ID3D11DeviceContext *d3d_context; struct d2d_ps_cb *cb_data; HRESULT hr; - if (FAILED(hr = ID3D10Buffer_Map(context->ps_cb, D3D10_MAP_WRITE_DISCARD, 0, (void **)&cb_data))) + ID3D11Device1_GetImmediateContext(context->d3d_device, &d3d_context); + + if (FAILED(hr = ID3D11DeviceContext_Map(d3d_context, (ID3D11Resource *)context->ps_cb, + 0, D3D11_MAP_WRITE_DISCARD, 0, &map_desc))) { - WARN("Failed to map constant buffer, hr %#x.\n", hr); + WARN("Failed to map constant buffer, hr %#lx.\n", hr); + ID3D11DeviceContext_Release(d3d_context); return hr; } + cb_data = map_desc.pData; cb_data->outline = outline; cb_data->is_arc = is_arc; cb_data->pad[0] = 0; @@ -729,7 +773,8 @@ static HRESULT d2d_device_context_update_ps_cb(struct d2d_device_context *contex if (!d2d_brush_fill_cb(opacity_brush, &cb_data->opacity_brush)) WARN("Failed to initialize opacity brush buffer.\n"); - ID3D10Buffer_Unmap(context->ps_cb); + ID3D11DeviceContext_Unmap(d3d_context, (ID3D11Resource *)context->ps_cb, 0); + ID3D11DeviceContext_Release(d3d_context); return hr; } @@ -737,17 +782,24 @@ static HRESULT d2d_device_context_update_ps_cb(struct d2d_device_context *contex static HRESULT d2d_device_context_update_vs_cb(struct d2d_device_context *context, const D2D_MATRIX_3X2_F *geometry_transform, float stroke_width) { + D3D11_MAPPED_SUBRESOURCE map_desc; + ID3D11DeviceContext *d3d_context; const D2D1_MATRIX_3X2_F *w; struct d2d_vs_cb *cb_data; float tmp_x, tmp_y; HRESULT hr; - if (FAILED(hr = ID3D10Buffer_Map(context->vs_cb, D3D10_MAP_WRITE_DISCARD, 0, (void **)&cb_data))) + ID3D11Device1_GetImmediateContext(context->d3d_device, &d3d_context); + + if (FAILED(hr = ID3D11DeviceContext_Map(d3d_context, (ID3D11Resource *)context->vs_cb, + 0, D3D11_MAP_WRITE_DISCARD, 0, &map_desc))) { - WARN("Failed to map constant buffer, hr %#x.\n", hr); + WARN("Failed to map constant buffer, hr %#lx.\n", hr); + ID3D11DeviceContext_Release(d3d_context); return hr; } + cb_data = map_desc.pData; cb_data->transform_geometry._11 = geometry_transform->_11; cb_data->transform_geometry._21 = geometry_transform->_21; cb_data->transform_geometry._31 = geometry_transform->_31; @@ -771,7 +823,8 @@ static HRESULT d2d_device_context_update_vs_cb(struct d2d_device_context *contex cb_data->transform_rty.z = w->_32 * tmp_y; cb_data->transform_rty.w = -2.0f / context->pixel_size.height; - ID3D10Buffer_Unmap(context->vs_cb); + ID3D11DeviceContext_Unmap(d3d_context, (ID3D11Resource *)context->vs_cb, 0); + ID3D11DeviceContext_Release(d3d_context); return S_OK; } @@ -779,24 +832,24 @@ static HRESULT d2d_device_context_update_vs_cb(struct d2d_device_context *contex static void d2d_device_context_draw_geometry(struct d2d_device_context *render_target, const struct d2d_geometry *geometry, struct d2d_brush *brush, float stroke_width) { - D3D10_SUBRESOURCE_DATA buffer_data; - D3D10_BUFFER_DESC buffer_desc; - ID3D10Buffer *ib, *vb; + D3D11_SUBRESOURCE_DATA buffer_data; + D3D11_BUFFER_DESC buffer_desc; + ID3D11Buffer *ib, *vb; HRESULT hr; if (FAILED(hr = d2d_device_context_update_vs_cb(render_target, &geometry->transform, stroke_width))) { - WARN("Failed to update vs constant buffer, hr %#x.\n", hr); + WARN("Failed to update vs constant buffer, hr %#lx.\n", hr); return; } if (FAILED(hr = d2d_device_context_update_ps_cb(render_target, brush, NULL, TRUE, FALSE))) { - WARN("Failed to update ps constant buffer, hr %#x.\n", hr); + WARN("Failed to update ps constant buffer, hr %#lx.\n", hr); return; } - buffer_desc.Usage = D3D10_USAGE_DEFAULT; + buffer_desc.Usage = D3D11_USAGE_DEFAULT; buffer_desc.CPUAccessFlags = 0; buffer_desc.MiscFlags = 0; @@ -806,53 +859,53 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t if (geometry->outline.face_count) { buffer_desc.ByteWidth = geometry->outline.face_count * sizeof(*geometry->outline.faces); - buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER; + buffer_desc.BindFlags = D3D11_BIND_INDEX_BUFFER; buffer_data.pSysMem = geometry->outline.faces; - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib))) + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib))) { - WARN("Failed to create index buffer, hr %#x.\n", hr); + WARN("Failed to create index buffer, hr %#lx.\n", hr); return; } buffer_desc.ByteWidth = geometry->outline.vertex_count * sizeof(*geometry->outline.vertices); - buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; + buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; buffer_data.pSysMem = geometry->outline.vertices; - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) { - ERR("Failed to create vertex buffer, hr %#x.\n", hr); - ID3D10Buffer_Release(ib); + ERR("Failed to create vertex buffer, hr %#lx.\n", hr); + ID3D11Buffer_Release(ib); return; } d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_OUTLINE, ib, 3 * geometry->outline.face_count, vb, sizeof(*geometry->outline.vertices), brush, NULL); - ID3D10Buffer_Release(vb); - ID3D10Buffer_Release(ib); + ID3D11Buffer_Release(vb); + ID3D11Buffer_Release(ib); } if (geometry->outline.bezier_face_count) { buffer_desc.ByteWidth = geometry->outline.bezier_face_count * sizeof(*geometry->outline.bezier_faces); - buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER; + buffer_desc.BindFlags = D3D11_BIND_INDEX_BUFFER; buffer_data.pSysMem = geometry->outline.bezier_faces; - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib))) + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib))) { - WARN("Failed to create beziers index buffer, hr %#x.\n", hr); + WARN("Failed to create curves index buffer, hr %#lx.\n", hr); return; } buffer_desc.ByteWidth = geometry->outline.bezier_count * sizeof(*geometry->outline.beziers); - buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; + buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; buffer_data.pSysMem = geometry->outline.beziers; - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) { - ERR("Failed to create beziers vertex buffer, hr %#x.\n", hr); - ID3D10Buffer_Release(ib); + ERR("Failed to create curves vertex buffer, hr %#lx.\n", hr); + ID3D11Buffer_Release(ib); return; } @@ -860,30 +913,30 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t 3 * geometry->outline.bezier_face_count, vb, sizeof(*geometry->outline.beziers), brush, NULL); - ID3D10Buffer_Release(vb); - ID3D10Buffer_Release(ib); + ID3D11Buffer_Release(vb); + ID3D11Buffer_Release(ib); } if (geometry->outline.arc_face_count) { buffer_desc.ByteWidth = geometry->outline.arc_face_count * sizeof(*geometry->outline.arc_faces); - buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER; + buffer_desc.BindFlags = D3D11_BIND_INDEX_BUFFER; buffer_data.pSysMem = geometry->outline.arc_faces; - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib))) + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib))) { - WARN("Failed to create arcs index buffer, hr %#x.\n", hr); + WARN("Failed to create arcs index buffer, hr %#lx.\n", hr); return; } buffer_desc.ByteWidth = geometry->outline.arc_count * sizeof(*geometry->outline.arcs); - buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; + buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; buffer_data.pSysMem = geometry->outline.arcs; - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) { - ERR("Failed to create arcs vertex buffer, hr %#x.\n", hr); - ID3D10Buffer_Release(ib); + ERR("Failed to create arcs vertex buffer, hr %#lx.\n", hr); + ID3D11Buffer_Release(ib); return; } @@ -892,36 +945,50 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t 3 * geometry->outline.arc_face_count, vb, sizeof(*geometry->outline.arcs), brush, NULL); - ID3D10Buffer_Release(vb); - ID3D10Buffer_Release(ib); + ID3D11Buffer_Release(vb); + ID3D11Buffer_Release(ib); } } -static void STDMETHODCALLTYPE d2d_device_context_DrawGeometry(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_DrawGeometry(ID2D1DeviceContext6 *iface, ID2D1Geometry *geometry, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) { const struct d2d_geometry *geometry_impl = unsafe_impl_from_ID2D1Geometry(geometry); - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); struct d2d_brush *brush_impl = unsafe_impl_from_ID2D1Brush(brush); + struct d2d_stroke_style *stroke_style_impl = unsafe_impl_from_ID2D1StrokeStyle(stroke_style); TRACE("iface %p, geometry %p, brush %p, stroke_width %.8e, stroke_style %p.\n", iface, geometry, brush, stroke_width, stroke_style); + if (context->target.type == D2D_TARGET_COMMAND_LIST) + { + d2d_command_list_draw_geometry(context->target.command_list, context, geometry, brush, + stroke_width, stroke_style); + return; + } + if (stroke_style) FIXME("Ignoring stroke style %p.\n", stroke_style); - d2d_device_context_draw_geometry(render_target, geometry_impl, brush_impl, stroke_width); + if (stroke_style_impl) + { + if (stroke_style_impl->desc.transformType == D2D1_STROKE_TRANSFORM_TYPE_FIXED) + stroke_width /= context->drawing_state.transform.m11; + } + + d2d_device_context_draw_geometry(context, geometry_impl, brush_impl, stroke_width); } static void d2d_device_context_fill_geometry(struct d2d_device_context *render_target, const struct d2d_geometry *geometry, struct d2d_brush *brush, struct d2d_brush *opacity_brush) { - D3D10_SUBRESOURCE_DATA buffer_data; - D3D10_BUFFER_DESC buffer_desc; - ID3D10Buffer *ib, *vb; + D3D11_SUBRESOURCE_DATA buffer_data; + D3D11_BUFFER_DESC buffer_desc; + ID3D11Buffer *ib, *vb; HRESULT hr; - buffer_desc.Usage = D3D10_USAGE_DEFAULT; + buffer_desc.Usage = D3D11_USAGE_DEFAULT; buffer_desc.CPUAccessFlags = 0; buffer_desc.MiscFlags = 0; @@ -930,73 +997,73 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t if (FAILED(hr = d2d_device_context_update_vs_cb(render_target, &geometry->transform, 0.0f))) { - WARN("Failed to update vs constant buffer, hr %#x.\n", hr); + WARN("Failed to update vs constant buffer, hr %#lx.\n", hr); return; } if (FAILED(hr = d2d_device_context_update_ps_cb(render_target, brush, opacity_brush, FALSE, FALSE))) { - WARN("Failed to update ps constant buffer, hr %#x.\n", hr); + WARN("Failed to update ps constant buffer, hr %#lx.\n", hr); return; } if (geometry->fill.face_count) { buffer_desc.ByteWidth = geometry->fill.face_count * sizeof(*geometry->fill.faces); - buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER; + buffer_desc.BindFlags = D3D11_BIND_INDEX_BUFFER; buffer_data.pSysMem = geometry->fill.faces; - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib))) + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib))) { - WARN("Failed to create index buffer, hr %#x.\n", hr); + WARN("Failed to create index buffer, hr %#lx.\n", hr); return; } buffer_desc.ByteWidth = geometry->fill.vertex_count * sizeof(*geometry->fill.vertices); - buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; + buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; buffer_data.pSysMem = geometry->fill.vertices; - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) { - ERR("Failed to create vertex buffer, hr %#x.\n", hr); - ID3D10Buffer_Release(ib); + ERR("Failed to create vertex buffer, hr %#lx.\n", hr); + ID3D11Buffer_Release(ib); return; } d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_TRIANGLE, ib, 3 * geometry->fill.face_count, vb, sizeof(*geometry->fill.vertices), brush, opacity_brush); - ID3D10Buffer_Release(vb); - ID3D10Buffer_Release(ib); + ID3D11Buffer_Release(vb); + ID3D11Buffer_Release(ib); } if (geometry->fill.bezier_vertex_count) { buffer_desc.ByteWidth = geometry->fill.bezier_vertex_count * sizeof(*geometry->fill.bezier_vertices); - buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; + buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; buffer_data.pSysMem = geometry->fill.bezier_vertices; - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) { - ERR("Failed to create beziers vertex buffer, hr %#x.\n", hr); + ERR("Failed to create curves vertex buffer, hr %#lx.\n", hr); return; } d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_CURVE, NULL, geometry->fill.bezier_vertex_count, vb, sizeof(*geometry->fill.bezier_vertices), brush, opacity_brush); - ID3D10Buffer_Release(vb); + ID3D11Buffer_Release(vb); } if (geometry->fill.arc_vertex_count) { buffer_desc.ByteWidth = geometry->fill.arc_vertex_count * sizeof(*geometry->fill.arc_vertices); - buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; + buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; buffer_data.pSysMem = geometry->fill.arc_vertices; - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) { - ERR("Failed to create arc vertex buffer, hr %#x.\n", hr); + ERR("Failed to create arc vertex buffer, hr %#lx.\n", hr); return; } @@ -1004,11 +1071,11 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_CURVE, NULL, geometry->fill.arc_vertex_count, vb, sizeof(*geometry->fill.arc_vertices), brush, opacity_brush); - ID3D10Buffer_Release(vb); + ID3D11Buffer_Release(vb); } } -static void STDMETHODCALLTYPE d2d_device_context_FillGeometry(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_FillGeometry(ID2D1DeviceContext6 *iface, ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush) { const struct d2d_geometry *geometry_impl = unsafe_impl_from_ID2D1Geometry(geometry); @@ -1027,21 +1094,49 @@ static void STDMETHODCALLTYPE d2d_device_context_FillGeometry(ID2D1DeviceContext return; } - d2d_device_context_fill_geometry(context, geometry_impl, brush_impl, opacity_brush_impl); + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_fill_geometry(context->target.command_list, context, geometry, brush, opacity_brush); + else + d2d_device_context_fill_geometry(context, geometry_impl, brush_impl, opacity_brush_impl); } -static void STDMETHODCALLTYPE d2d_device_context_FillMesh(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_FillMesh(ID2D1DeviceContext6 *iface, ID2D1Mesh *mesh, ID2D1Brush *brush) { + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + FIXME("iface %p, mesh %p, brush %p stub!\n", iface, mesh, brush); + + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_fill_mesh(context->target.command_list, context, mesh, brush); } -static void STDMETHODCALLTYPE d2d_device_context_FillOpacityMask(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_FillOpacityMask(ID2D1DeviceContext6 *iface, ID2D1Bitmap *mask, ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content, const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect) { + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + FIXME("iface %p, mask %p, brush %p, content %#x, dst_rect %s, src_rect %s stub!\n", iface, mask, brush, content, debug_d2d_rect_f(dst_rect), debug_d2d_rect_f(src_rect)); + + if (FAILED(context->error.code)) + return; + + if (context->drawing_state.antialiasMode != D2D1_ANTIALIAS_MODE_ALIASED) + { + d2d_device_context_set_error(context, D2DERR_WRONG_STATE); + return; + } + + if ((unsigned int)content > D2D1_OPACITY_MASK_CONTENT_TEXT_GDI_COMPATIBLE) + { + d2d_device_context_set_error(context, E_INVALIDARG); + return; + } + + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_fill_opacity_mask(context->target.command_list, context, mask, brush, dst_rect, src_rect); } static void d2d_device_context_draw_bitmap(struct d2d_device_context *context, ID2D1Bitmap *bitmap, @@ -1104,15 +1199,15 @@ static void d2d_device_context_draw_bitmap(struct d2d_device_context *context, I if (FAILED(hr = d2d_bitmap_brush_create(context->factory, bitmap, &bitmap_brush_desc, &brush_desc, &brush))) { - ERR("Failed to create bitmap brush, hr %#x.\n", hr); + ERR("Failed to create bitmap brush, hr %#lx.\n", hr); return; } - d2d_device_context_FillRectangle(&context->ID2D1DeviceContext_iface, &d, &brush->ID2D1Brush_iface); + d2d_device_context_FillRectangle(&context->ID2D1DeviceContext6_iface, &d, &brush->ID2D1Brush_iface); ID2D1Brush_Release(&brush->ID2D1Brush_iface); } -static void STDMETHODCALLTYPE d2d_device_context_DrawBitmap(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_DrawBitmap(ID2D1DeviceContext6 *iface, ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity, D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, const D2D1_RECT_F *src_rect) { @@ -1128,11 +1223,19 @@ static void STDMETHODCALLTYPE d2d_device_context_DrawBitmap(ID2D1DeviceContext * return; } - d2d_device_context_draw_bitmap(context, bitmap, dst_rect, opacity, d2d1_1_interp_mode_from_d2d1(interpolation_mode), - src_rect, NULL, NULL); + if (context->target.type == D2D_TARGET_COMMAND_LIST) + { + d2d_command_list_draw_bitmap(context->target.command_list, bitmap, dst_rect, opacity, + d2d1_1_interp_mode_from_d2d1(interpolation_mode), src_rect, NULL); + } + else + { + d2d_device_context_draw_bitmap(context, bitmap, dst_rect, opacity, + d2d1_1_interp_mode_from_d2d1(interpolation_mode), src_rect, NULL, NULL); + } } -static void STDMETHODCALLTYPE d2d_device_context_DrawText(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_DrawText(ID2D1DeviceContext6 *iface, const WCHAR *string, UINT32 string_len, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode) { @@ -1151,7 +1254,7 @@ static void STDMETHODCALLTYPE d2d_device_context_DrawText(ID2D1DeviceContext *if if (FAILED(hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown **)&dwrite_factory))) { - ERR("Failed to create dwrite factory, hr %#x.\n", hr); + ERR("Failed to create dwrite factory, hr %#lx.\n", hr); return; } @@ -1167,16 +1270,16 @@ static void STDMETHODCALLTYPE d2d_device_context_DrawText(ID2D1DeviceContext *if IDWriteFactory_Release(dwrite_factory); if (FAILED(hr)) { - ERR("Failed to create text layout, hr %#x.\n", hr); + ERR("Failed to create text layout, hr %#lx.\n", hr); return; } d2d_point_set(&origin, min(layout_rect->left, layout_rect->right), min(layout_rect->top, layout_rect->bottom)); - ID2D1DeviceContext_DrawTextLayout(iface, origin, text_layout, brush, options); + ID2D1DeviceContext1_DrawTextLayout((ID2D1DeviceContext1 *)iface, origin, text_layout, brush, options); IDWriteTextLayout_Release(text_layout); } -static void STDMETHODCALLTYPE d2d_device_context_DrawTextLayout(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_DrawTextLayout(ID2D1DeviceContext6 *iface, D2D1_POINT_2F origin, IDWriteTextLayout *layout, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -1191,7 +1294,7 @@ static void STDMETHODCALLTYPE d2d_device_context_DrawTextLayout(ID2D1DeviceConte if (FAILED(hr = IDWriteTextLayout_Draw(layout, &ctx, &render_target->IDWriteTextRenderer_iface, origin.x, origin.y))) - FIXME("Failed to draw text layout, hr %#x.\n", hr); + FIXME("Failed to draw text layout, hr %#lx.\n", hr); } static D2D1_ANTIALIAS_MODE d2d_device_context_set_aa_mode_from_text_aa_mode(struct d2d_device_context *rt) @@ -1213,13 +1316,13 @@ static void d2d_device_context_draw_glyph_run_outline(struct d2d_device_context if (FAILED(hr = ID2D1Factory_CreatePathGeometry(render_target->factory, &geometry))) { - ERR("Failed to create geometry, hr %#x.\n", hr); + ERR("Failed to create geometry, hr %#lx.\n", hr); return; } if (FAILED(hr = ID2D1PathGeometry_Open(geometry, &sink))) { - ERR("Failed to open geometry sink, hr %#x.\n", hr); + ERR("Failed to open geometry sink, hr %#lx.\n", hr); ID2D1PathGeometry_Release(geometry); return; } @@ -1228,14 +1331,14 @@ static void d2d_device_context_draw_glyph_run_outline(struct d2d_device_context glyph_run->glyphIndices, glyph_run->glyphAdvances, glyph_run->glyphOffsets, glyph_run->glyphCount, glyph_run->isSideways, glyph_run->bidiLevel & 1, (IDWriteGeometrySink *)sink))) { - ERR("Failed to get glyph run outline, hr %#x.\n", hr); + ERR("Failed to get glyph run outline, hr %#lx.\n", hr); ID2D1GeometrySink_Release(sink); ID2D1PathGeometry_Release(geometry); return; } if (FAILED(hr = ID2D1GeometrySink_Close(sink))) - ERR("Failed to close geometry sink, hr %#x.\n", hr); + ERR("Failed to close geometry sink, hr %#lx.\n", hr); ID2D1GeometrySink_Release(sink); transform = &render_target->drawing_state.transform; @@ -1251,7 +1354,7 @@ static void d2d_device_context_draw_glyph_run_outline(struct d2d_device_context ID2D1PathGeometry_Release(geometry); } -static void d2d_device_context_draw_glyph_run_bitmap(struct d2d_device_context *render_target, +static void d2d_device_context_draw_glyph_run_bitmap(struct d2d_device_context *context, D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush, DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode, DWRITE_TEXT_ANTIALIAS_MODE antialias_mode) @@ -1276,18 +1379,18 @@ static void d2d_device_context_draw_glyph_run_bitmap(struct d2d_device_context * if (FAILED(hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory2, (IUnknown **)&dwrite_factory))) { - ERR("Failed to create dwrite factory, hr %#x.\n", hr); + ERR("Failed to create dwrite factory, hr %#lx.\n", hr); return; } - transform = &render_target->drawing_state.transform; + transform = &context->drawing_state.transform; - scale_x = render_target->desc.dpiX / 96.0f; + scale_x = context->desc.dpiX / 96.0f; m._11 = transform->_11 * scale_x; m._21 = transform->_21 * scale_x; m._31 = transform->_31 * scale_x; - scale_y = render_target->desc.dpiY / 96.0f; + scale_y = context->desc.dpiY / 96.0f; m._12 = transform->_12 * scale_y; m._22 = transform->_22 * scale_y; m._32 = transform->_32 * scale_y; @@ -1298,7 +1401,7 @@ static void d2d_device_context_draw_glyph_run_bitmap(struct d2d_device_context * IDWriteFactory2_Release(dwrite_factory); if (FAILED(hr)) { - ERR("Failed to create glyph run analysis, hr %#x.\n", hr); + ERR("Failed to create glyph run analysis, hr %#lx.\n", hr); return; } @@ -1309,7 +1412,7 @@ static void d2d_device_context_draw_glyph_run_bitmap(struct d2d_device_context * if (FAILED(hr = IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis, texture_type, &bounds))) { - ERR("Failed to get alpha texture bounds, hr %#x.\n", hr); + ERR("Failed to get alpha texture bounds, hr %#lx.\n", hr); goto done; } @@ -1322,7 +1425,7 @@ static void d2d_device_context_draw_glyph_run_bitmap(struct d2d_device_context * if (texture_type == DWRITE_TEXTURE_CLEARTYPE_3x1) bitmap_size.width *= 3; - if (!(opacity_values = heap_calloc(bitmap_size.height, bitmap_size.width))) + if (!(opacity_values = calloc(bitmap_size.height, bitmap_size.width))) { ERR("Failed to allocate opacity values.\n"); goto done; @@ -1332,20 +1435,20 @@ static void d2d_device_context_draw_glyph_run_bitmap(struct d2d_device_context * if (FAILED(hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis, texture_type, &bounds, opacity_values, opacity_values_size))) { - ERR("Failed to create alpha texture, hr %#x.\n", hr); + ERR("Failed to create alpha texture, hr %#lx.\n", hr); goto done; } bitmap_desc.pixelFormat.format = DXGI_FORMAT_A8_UNORM; bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; - bitmap_desc.dpiX = render_target->desc.dpiX; + bitmap_desc.dpiX = context->desc.dpiX; if (texture_type == DWRITE_TEXTURE_CLEARTYPE_3x1) bitmap_desc.dpiX *= 3.0f; - bitmap_desc.dpiY = render_target->desc.dpiY; - if (FAILED(hr = d2d_device_context_CreateBitmap(&render_target->ID2D1DeviceContext_iface, + bitmap_desc.dpiY = context->desc.dpiY; + if (FAILED(hr = d2d_device_context_CreateBitmap(&context->ID2D1DeviceContext6_iface, bitmap_size, opacity_values, bitmap_size.width, &bitmap_desc, &opacity_bitmap))) { - ERR("Failed to create opacity bitmap, hr %#x.\n", hr); + ERR("Failed to create opacity bitmap, hr %#lx.\n", hr); goto done; } @@ -1359,22 +1462,22 @@ static void d2d_device_context_draw_glyph_run_bitmap(struct d2d_device_context * brush_desc.transform._22 = 1.0f; brush_desc.transform._31 = run_rect.left; brush_desc.transform._32 = run_rect.top; - if (FAILED(hr = d2d_device_context_CreateBitmapBrush(&render_target->ID2D1DeviceContext_iface, + if (FAILED(hr = d2d_device_context_CreateBitmapBrush(&context->ID2D1DeviceContext6_iface, opacity_bitmap, NULL, &brush_desc, &opacity_brush))) { - ERR("Failed to create opacity bitmap brush, hr %#x.\n", hr); + ERR("Failed to create opacity bitmap brush, hr %#lx.\n", hr); goto done; } - if (FAILED(hr = ID2D1Factory_CreateRectangleGeometry(render_target->factory, &run_rect, &geometry))) + if (FAILED(hr = ID2D1Factory_CreateRectangleGeometry(context->factory, &run_rect, &geometry))) { - ERR("Failed to create geometry, hr %#x.\n", hr); + ERR("Failed to create geometry, hr %#lx.\n", hr); goto done; } m = *transform; *transform = identity; - d2d_device_context_fill_geometry(render_target, unsafe_impl_from_ID2D1Geometry((ID2D1Geometry *)geometry), + d2d_device_context_fill_geometry(context, unsafe_impl_from_ID2D1Geometry((ID2D1Geometry *)geometry), unsafe_impl_from_ID2D1Brush(brush), unsafe_impl_from_ID2D1Brush((ID2D1Brush *)opacity_brush)); *transform = m; @@ -1385,31 +1488,126 @@ static void d2d_device_context_draw_glyph_run_bitmap(struct d2d_device_context * ID2D1BitmapBrush_Release(opacity_brush); if (opacity_bitmap) ID2D1Bitmap_Release(opacity_bitmap); - heap_free(opacity_values); + free(opacity_values); IDWriteGlyphRunAnalysis_Release(analysis); } -static void STDMETHODCALLTYPE d2d_device_context_DrawGlyphRun(ID2D1DeviceContext *iface, +static void d2d_device_context_draw_glyph_run(struct d2d_device_context *context, + D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, + const DWRITE_GLYPH_RUN_DESCRIPTION *glyph_run_desc, ID2D1Brush *brush, DWRITE_MEASURING_MODE measuring_mode) +{ + DWRITE_TEXT_ANTIALIAS_MODE antialias_mode = DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE; + IDWriteRenderingParams *rendering_params; + DWRITE_RENDERING_MODE rendering_mode; + HRESULT hr; + + if (FAILED(context->error.code)) + return; + + if (context->target.type == D2D_TARGET_COMMAND_LIST) + { + d2d_command_list_draw_glyph_run(context->target.command_list, context, baseline_origin, glyph_run, + glyph_run_desc, brush, measuring_mode); + return; + } + + rendering_params = context->text_rendering_params ? context->text_rendering_params + : context->default_text_rendering_params; + + rendering_mode = IDWriteRenderingParams_GetRenderingMode(rendering_params); + + switch (context->drawing_state.textAntialiasMode) + { + case D2D1_TEXT_ANTIALIAS_MODE_ALIASED: + if (rendering_mode == DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL + || rendering_mode == DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC + || rendering_mode == DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL + || rendering_mode == DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC) + d2d_device_context_set_error(context, E_INVALIDARG); + break; + + case D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE: + if (rendering_mode == DWRITE_RENDERING_MODE_ALIASED + || rendering_mode == DWRITE_RENDERING_MODE_OUTLINE) + d2d_device_context_set_error(context, E_INVALIDARG); + break; + + case D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE: + if (rendering_mode == DWRITE_RENDERING_MODE_ALIASED) + d2d_device_context_set_error(context, E_INVALIDARG); + break; + + default: + break; + } + + if (FAILED(context->error.code)) + return; + + rendering_mode = DWRITE_RENDERING_MODE_DEFAULT; + switch (context->drawing_state.textAntialiasMode) + { + case D2D1_TEXT_ANTIALIAS_MODE_DEFAULT: + if (IDWriteRenderingParams_GetClearTypeLevel(rendering_params) > 0.0f) + antialias_mode = DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE; + break; + + case D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE: + antialias_mode = DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE; + break; + + case D2D1_TEXT_ANTIALIAS_MODE_ALIASED: + rendering_mode = DWRITE_RENDERING_MODE_ALIASED; + break; + + default: + break; + } + + if (rendering_mode == DWRITE_RENDERING_MODE_DEFAULT) + { + if (FAILED(hr = IDWriteFontFace_GetRecommendedRenderingMode(glyph_run->fontFace, glyph_run->fontEmSize, + max(context->desc.dpiX, context->desc.dpiY) / 96.0f, + measuring_mode, rendering_params, &rendering_mode))) + { + ERR("Failed to get recommended rendering mode, hr %#lx.\n", hr); + rendering_mode = DWRITE_RENDERING_MODE_OUTLINE; + } + } + + if (rendering_mode == DWRITE_RENDERING_MODE_OUTLINE) + d2d_device_context_draw_glyph_run_outline(context, baseline_origin, glyph_run, brush); + else + d2d_device_context_draw_glyph_run_bitmap(context, baseline_origin, glyph_run, brush, + rendering_mode, measuring_mode, antialias_mode); +} + +static void STDMETHODCALLTYPE d2d_device_context_DrawGlyphRun(ID2D1DeviceContext6 *iface, D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush, DWRITE_MEASURING_MODE measuring_mode) { + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + TRACE("iface %p, baseline_origin %s, glyph_run %p, brush %p, measuring_mode %#x.\n", iface, debug_d2d_point_2f(&baseline_origin), glyph_run, brush, measuring_mode); - ID2D1DeviceContext_DrawGlyphRun(iface, baseline_origin, glyph_run, NULL, brush, measuring_mode); + d2d_device_context_draw_glyph_run(context, baseline_origin, glyph_run, NULL, brush, measuring_mode); } -static void STDMETHODCALLTYPE d2d_device_context_SetTransform(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_SetTransform(ID2D1DeviceContext6 *iface, const D2D1_MATRIX_3X2_F *transform) { - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); TRACE("iface %p, transform %p.\n", iface, transform); - render_target->drawing_state.transform = *transform; + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_set_transform(context->target.command_list, transform); + + context->drawing_state.transform = *transform; } -static void STDMETHODCALLTYPE d2d_device_context_GetTransform(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_GetTransform(ID2D1DeviceContext6 *iface, D2D1_MATRIX_3X2_F *transform) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -1419,17 +1617,20 @@ static void STDMETHODCALLTYPE d2d_device_context_GetTransform(ID2D1DeviceContext *transform = render_target->drawing_state.transform; } -static void STDMETHODCALLTYPE d2d_device_context_SetAntialiasMode(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_SetAntialiasMode(ID2D1DeviceContext6 *iface, D2D1_ANTIALIAS_MODE antialias_mode) { - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); TRACE("iface %p, antialias_mode %#x stub!\n", iface, antialias_mode); - render_target->drawing_state.antialiasMode = antialias_mode; + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_set_antialias_mode(context->target.command_list, antialias_mode); + + context->drawing_state.antialiasMode = antialias_mode; } -static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_device_context_GetAntialiasMode(ID2D1DeviceContext *iface) +static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_device_context_GetAntialiasMode(ID2D1DeviceContext6 *iface) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -1438,17 +1639,20 @@ static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_device_context_GetAntialiasMode return render_target->drawing_state.antialiasMode; } -static void STDMETHODCALLTYPE d2d_device_context_SetTextAntialiasMode(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_SetTextAntialiasMode(ID2D1DeviceContext6 *iface, D2D1_TEXT_ANTIALIAS_MODE antialias_mode) { - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); TRACE("iface %p, antialias_mode %#x.\n", iface, antialias_mode); - render_target->drawing_state.textAntialiasMode = antialias_mode; + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_set_text_antialias_mode(context->target.command_list, antialias_mode); + + context->drawing_state.textAntialiasMode = antialias_mode; } -static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_device_context_GetTextAntialiasMode(ID2D1DeviceContext *iface) +static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_device_context_GetTextAntialiasMode(ID2D1DeviceContext6 *iface) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -1457,21 +1661,24 @@ static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_device_context_GetTextAnti return render_target->drawing_state.textAntialiasMode; } -static void STDMETHODCALLTYPE d2d_device_context_SetTextRenderingParams(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_SetTextRenderingParams(ID2D1DeviceContext6 *iface, IDWriteRenderingParams *text_rendering_params) { - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params); + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_set_text_rendering_params(context->target.command_list, text_rendering_params); + if (text_rendering_params) IDWriteRenderingParams_AddRef(text_rendering_params); - if (render_target->text_rendering_params) - IDWriteRenderingParams_Release(render_target->text_rendering_params); - render_target->text_rendering_params = text_rendering_params; + if (context->text_rendering_params) + IDWriteRenderingParams_Release(context->text_rendering_params); + context->text_rendering_params = text_rendering_params; } -static void STDMETHODCALLTYPE d2d_device_context_GetTextRenderingParams(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_GetTextRenderingParams(ID2D1DeviceContext6 *iface, IDWriteRenderingParams **text_rendering_params) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -1482,17 +1689,20 @@ static void STDMETHODCALLTYPE d2d_device_context_GetTextRenderingParams(ID2D1Dev IDWriteRenderingParams_AddRef(*text_rendering_params); } -static void STDMETHODCALLTYPE d2d_device_context_SetTags(ID2D1DeviceContext *iface, D2D1_TAG tag1, D2D1_TAG tag2) +static void STDMETHODCALLTYPE d2d_device_context_SetTags(ID2D1DeviceContext6 *iface, D2D1_TAG tag1, D2D1_TAG tag2) { - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); TRACE("iface %p, tag1 %s, tag2 %s.\n", iface, wine_dbgstr_longlong(tag1), wine_dbgstr_longlong(tag2)); - render_target->drawing_state.tag1 = tag1; - render_target->drawing_state.tag2 = tag2; + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_set_tags(context->target.command_list, tag1, tag2); + + context->drawing_state.tag1 = tag1; + context->drawing_state.tag2 = tag2; } -static void STDMETHODCALLTYPE d2d_device_context_GetTags(ID2D1DeviceContext *iface, D2D1_TAG *tag1, D2D1_TAG *tag2) +static void STDMETHODCALLTYPE d2d_device_context_GetTags(ID2D1DeviceContext6 *iface, D2D1_TAG *tag1, D2D1_TAG *tag2) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -1502,18 +1712,34 @@ static void STDMETHODCALLTYPE d2d_device_context_GetTags(ID2D1DeviceContext *ifa *tag2 = render_target->drawing_state.tag2; } -static void STDMETHODCALLTYPE d2d_device_context_PushLayer(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_PushLayer(ID2D1DeviceContext6 *iface, const D2D1_LAYER_PARAMETERS *layer_parameters, ID2D1Layer *layer) { + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + FIXME("iface %p, layer_parameters %p, layer %p stub!\n", iface, layer_parameters, layer); + + if (context->target.type == D2D_TARGET_COMMAND_LIST) + { + D2D1_LAYER_PARAMETERS1 parameters; + + memcpy(¶meters, layer_parameters, sizeof(*layer_parameters)); + parameters.layerOptions = D2D1_LAYER_OPTIONS1_NONE; + d2d_command_list_push_layer(context->target.command_list, context, ¶meters, layer); + } } -static void STDMETHODCALLTYPE d2d_device_context_PopLayer(ID2D1DeviceContext *iface) +static void STDMETHODCALLTYPE d2d_device_context_PopLayer(ID2D1DeviceContext6 *iface) { + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + FIXME("iface %p stub!\n", iface); + + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_pop_layer(context->target.command_list); } -static HRESULT STDMETHODCALLTYPE d2d_device_context_Flush(ID2D1DeviceContext *iface, D2D1_TAG *tag1, D2D1_TAG *tag2) +static HRESULT STDMETHODCALLTYPE d2d_device_context_Flush(ID2D1DeviceContext6 *iface, D2D1_TAG *tag1, D2D1_TAG *tag2) { struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); @@ -1525,14 +1751,15 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_Flush(ID2D1DeviceContext *if return E_NOTIMPL; } -static void STDMETHODCALLTYPE d2d_device_context_SaveDrawingState(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_SaveDrawingState(ID2D1DeviceContext6 *iface, ID2D1DrawingStateBlock *state_block) { - struct d2d_state_block *state_block_impl = unsafe_impl_from_ID2D1DrawingStateBlock(state_block); struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_state_block *state_block_impl; TRACE("iface %p, state_block %p.\n", iface, state_block); + if (!(state_block_impl = unsafe_impl_from_ID2D1DrawingStateBlock(state_block))) return; state_block_impl->drawing_state = render_target->drawing_state; if (render_target->text_rendering_params) IDWriteRenderingParams_AddRef(render_target->text_rendering_params); @@ -1541,66 +1768,89 @@ static void STDMETHODCALLTYPE d2d_device_context_SaveDrawingState(ID2D1DeviceCon state_block_impl->text_rendering_params = render_target->text_rendering_params; } -static void STDMETHODCALLTYPE d2d_device_context_RestoreDrawingState(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_RestoreDrawingState(ID2D1DeviceContext6 *iface, ID2D1DrawingStateBlock *state_block) { - struct d2d_state_block *state_block_impl = unsafe_impl_from_ID2D1DrawingStateBlock(state_block); - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + struct d2d_state_block *state_block_impl; TRACE("iface %p, state_block %p.\n", iface, state_block); - render_target->drawing_state = state_block_impl->drawing_state; + if (!(state_block_impl = unsafe_impl_from_ID2D1DrawingStateBlock(state_block))) return; + if (context->target.type == D2D_TARGET_COMMAND_LIST) + { + struct d2d_command_list *command_list = context->target.command_list; + + if (context->drawing_state.antialiasMode != state_block_impl->drawing_state.antialiasMode) + d2d_command_list_set_antialias_mode(command_list, state_block_impl->drawing_state.antialiasMode); + d2d_command_list_set_text_antialias_mode(command_list, state_block_impl->drawing_state.textAntialiasMode); + d2d_command_list_set_tags(command_list, state_block_impl->drawing_state.tag1, state_block_impl->drawing_state.tag2); + d2d_command_list_set_transform(command_list, &state_block_impl->drawing_state.transform); + d2d_command_list_set_primitive_blend(command_list, state_block_impl->drawing_state.primitiveBlend); + d2d_command_list_set_unit_mode(command_list, state_block_impl->drawing_state.unitMode); + d2d_command_list_set_text_rendering_params(command_list, state_block_impl->text_rendering_params); + } + + context->drawing_state = state_block_impl->drawing_state; if (state_block_impl->text_rendering_params) IDWriteRenderingParams_AddRef(state_block_impl->text_rendering_params); - if (render_target->text_rendering_params) - IDWriteRenderingParams_Release(render_target->text_rendering_params); - render_target->text_rendering_params = state_block_impl->text_rendering_params; + if (context->text_rendering_params) + IDWriteRenderingParams_Release(context->text_rendering_params); + context->text_rendering_params = state_block_impl->text_rendering_params; } -static void STDMETHODCALLTYPE d2d_device_context_PushAxisAlignedClip(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_PushAxisAlignedClip(ID2D1DeviceContext6 *iface, const D2D1_RECT_F *clip_rect, D2D1_ANTIALIAS_MODE antialias_mode) { - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); D2D1_RECT_F transformed_rect; float x_scale, y_scale; D2D1_POINT_2F point; TRACE("iface %p, clip_rect %s, antialias_mode %#x.\n", iface, debug_d2d_rect_f(clip_rect), antialias_mode); + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_push_clip(context->target.command_list, clip_rect, antialias_mode); + if (antialias_mode != D2D1_ANTIALIAS_MODE_ALIASED) FIXME("Ignoring antialias_mode %#x.\n", antialias_mode); - x_scale = render_target->desc.dpiX / 96.0f; - y_scale = render_target->desc.dpiY / 96.0f; - d2d_point_transform(&point, &render_target->drawing_state.transform, + x_scale = context->desc.dpiX / 96.0f; + y_scale = context->desc.dpiY / 96.0f; + d2d_point_transform(&point, &context->drawing_state.transform, clip_rect->left * x_scale, clip_rect->top * y_scale); d2d_rect_set(&transformed_rect, point.x, point.y, point.x, point.y); - d2d_point_transform(&point, &render_target->drawing_state.transform, + d2d_point_transform(&point, &context->drawing_state.transform, clip_rect->left * x_scale, clip_rect->bottom * y_scale); d2d_rect_expand(&transformed_rect, &point); - d2d_point_transform(&point, &render_target->drawing_state.transform, + d2d_point_transform(&point, &context->drawing_state.transform, clip_rect->right * x_scale, clip_rect->top * y_scale); d2d_rect_expand(&transformed_rect, &point); - d2d_point_transform(&point, &render_target->drawing_state.transform, + d2d_point_transform(&point, &context->drawing_state.transform, clip_rect->right * x_scale, clip_rect->bottom * y_scale); d2d_rect_expand(&transformed_rect, &point); - if (!d2d_clip_stack_push(&render_target->clip_stack, &transformed_rect)) + if (!d2d_clip_stack_push(&context->clip_stack, &transformed_rect)) WARN("Failed to push clip rect.\n"); } -static void STDMETHODCALLTYPE d2d_device_context_PopAxisAlignedClip(ID2D1DeviceContext *iface) +static void STDMETHODCALLTYPE d2d_device_context_PopAxisAlignedClip(ID2D1DeviceContext6 *iface) { - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); TRACE("iface %p.\n", iface); - d2d_clip_stack_pop(&render_target->clip_stack); + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_pop_clip(context->target.command_list); + + d2d_clip_stack_pop(&context->clip_stack); } -static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface, const D2D1_COLOR_F *colour) +static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext6 *iface, const D2D1_COLOR_F *colour) { - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + D3D11_MAPPED_SUBRESOURCE map_desc; + ID3D11DeviceContext *d3d_context; struct d2d_ps_cb *ps_cb_data; struct d2d_vs_cb *vs_cb_data; D2D1_COLOR_F *c; @@ -1608,13 +1858,23 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface TRACE("iface %p, colour %p.\n", iface, colour); - if (FAILED(hr = ID3D10Buffer_Map(render_target->vs_cb, D3D10_MAP_WRITE_DISCARD, - 0, (void **)&vs_cb_data))) + if (context->target.type == D2D_TARGET_COMMAND_LIST) + { + d2d_command_list_clear(context->target.command_list, colour); + return; + } + + ID3D11Device1_GetImmediateContext(context->d3d_device, &d3d_context); + + if (FAILED(hr = ID3D11DeviceContext_Map(d3d_context, (ID3D11Resource *)context->vs_cb, + 0, D3D11_MAP_WRITE_DISCARD, 0, &map_desc))) { - WARN("Failed to map vs constant buffer, hr %#x.\n", hr); + WARN("Failed to map vs constant buffer, hr %#lx.\n", hr); + ID3D11DeviceContext_Release(d3d_context); return; } + vs_cb_data = map_desc.pData; vs_cb_data->transform_geometry._11 = 1.0f; vs_cb_data->transform_geometry._21 = 0.0f; vs_cb_data->transform_geometry._31 = 0.0f; @@ -1632,15 +1892,17 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface vs_cb_data->transform_rty.z = 1.0f; vs_cb_data->transform_rty.w = -1.0f; - ID3D10Buffer_Unmap(render_target->vs_cb); + ID3D11DeviceContext_Unmap(d3d_context, (ID3D11Resource *)context->vs_cb, 0); - if (FAILED(hr = ID3D10Buffer_Map(render_target->ps_cb, D3D10_MAP_WRITE_DISCARD, - 0, (void **)&ps_cb_data))) + if (FAILED(hr = ID3D11DeviceContext_Map(d3d_context, (ID3D11Resource *)context->ps_cb, + 0, D3D11_MAP_WRITE_DISCARD, 0, &map_desc))) { - WARN("Failed to map ps constant buffer, hr %#x.\n", hr); + WARN("Failed to map ps constant buffer, hr %#lx.\n", hr); + ID3D11DeviceContext_Release(d3d_context); return; } + ps_cb_data = map_desc.pData; memset(ps_cb_data, 0, sizeof(*ps_cb_data)); ps_cb_data->colour_brush.type = D2D_BRUSH_TYPE_SOLID; ps_cb_data->colour_brush.opacity = 1.0f; @@ -1648,28 +1910,32 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface c = &ps_cb_data->colour_brush.u.solid.colour; if (colour) *c = *colour; - if (render_target->desc.pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE) + if (context->desc.pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE) c->a = 1.0f; c->r *= c->a; c->g *= c->a; c->b *= c->a; - ID3D10Buffer_Unmap(render_target->ps_cb); + ID3D11DeviceContext_Unmap(d3d_context, (ID3D11Resource *)context->ps_cb, 0); + ID3D11DeviceContext_Release(d3d_context); - d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_TRIANGLE, render_target->ib, 6, - render_target->vb, render_target->vb_stride, NULL, NULL); + d2d_device_context_draw(context, D2D_SHAPE_TYPE_TRIANGLE, context->ib, 6, + context->vb, context->vb_stride, NULL, NULL); } -static void STDMETHODCALLTYPE d2d_device_context_BeginDraw(ID2D1DeviceContext *iface) +static void STDMETHODCALLTYPE d2d_device_context_BeginDraw(ID2D1DeviceContext6 *iface) { - struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); TRACE("iface %p.\n", iface); - memset(&render_target->error, 0, sizeof(render_target->error)); + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_begin_draw(context->target.command_list, context); + + memset(&context->error, 0, sizeof(context->error)); } -static HRESULT STDMETHODCALLTYPE d2d_device_context_EndDraw(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_EndDraw(ID2D1DeviceContext6 *iface, D2D1_TAG *tag1, D2D1_TAG *tag2) { struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); @@ -1677,6 +1943,12 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_EndDraw(ID2D1DeviceContext * TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + if (context->target.type == D2D_TARGET_COMMAND_LIST) + { + FIXME("Unimplemented for command list target.\n"); + return E_NOTIMPL; + } + if (tag1) *tag1 = context->error.tag1; if (tag2) @@ -1691,7 +1963,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_EndDraw(ID2D1DeviceContext * return context->error.code; } -static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_device_context_GetPixelFormat(ID2D1DeviceContext *iface, +static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_device_context_GetPixelFormat(ID2D1DeviceContext6 *iface, D2D1_PIXEL_FORMAT *format) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -1702,7 +1974,7 @@ static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_device_context_GetPixelFormat(I return format; } -static void STDMETHODCALLTYPE d2d_device_context_SetDpi(ID2D1DeviceContext *iface, float dpi_x, float dpi_y) +static void STDMETHODCALLTYPE d2d_device_context_SetDpi(ID2D1DeviceContext6 *iface, float dpi_x, float dpi_y) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -1720,7 +1992,7 @@ static void STDMETHODCALLTYPE d2d_device_context_SetDpi(ID2D1DeviceContext *ifac render_target->desc.dpiY = dpi_y; } -static void STDMETHODCALLTYPE d2d_device_context_GetDpi(ID2D1DeviceContext *iface, float *dpi_x, float *dpi_y) +static void STDMETHODCALLTYPE d2d_device_context_GetDpi(ID2D1DeviceContext6 *iface, float *dpi_x, float *dpi_y) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -1730,7 +2002,7 @@ static void STDMETHODCALLTYPE d2d_device_context_GetDpi(ID2D1DeviceContext *ifac *dpi_y = render_target->desc.dpiY; } -static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_device_context_GetSize(ID2D1DeviceContext *iface, D2D1_SIZE_F *size) +static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_device_context_GetSize(ID2D1DeviceContext6 *iface, D2D1_SIZE_F *size) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -1741,7 +2013,7 @@ static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_device_context_GetSize(ID2D1DeviceCon return size; } -static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_device_context_GetPixelSize(ID2D1DeviceContext *iface, +static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_device_context_GetPixelSize(ID2D1DeviceContext6 *iface, D2D1_SIZE_U *pixel_size) { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); @@ -1752,14 +2024,14 @@ static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_device_context_GetPixelSize(ID2D1Devi return pixel_size; } -static UINT32 STDMETHODCALLTYPE d2d_device_context_GetMaximumBitmapSize(ID2D1DeviceContext *iface) +static UINT32 STDMETHODCALLTYPE d2d_device_context_GetMaximumBitmapSize(ID2D1DeviceContext6 *iface) { TRACE("iface %p.\n", iface); - return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; + return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; } -static BOOL STDMETHODCALLTYPE d2d_device_context_IsSupported(ID2D1DeviceContext *iface, +static BOOL STDMETHODCALLTYPE d2d_device_context_IsSupported(ID2D1DeviceContext6 *iface, const D2D1_RENDER_TARGET_PROPERTIES *desc) { FIXME("iface %p, desc %p stub!\n", iface, desc); @@ -1767,7 +2039,7 @@ static BOOL STDMETHODCALLTYPE d2d_device_context_IsSupported(ID2D1DeviceContext return FALSE; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateBitmap(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateBitmap(ID2D1DeviceContext6 *iface, D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES1 *desc, ID2D1Bitmap1 **bitmap) { @@ -1785,7 +2057,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateBit } static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateBitmapFromWicBitmap( - ID2D1DeviceContext *iface, IWICBitmapSource *bitmap_source, + ID2D1DeviceContext6 *iface, IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES1 *desc, ID2D1Bitmap1 **bitmap) { struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); @@ -1800,7 +2072,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateBit return hr; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContext(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContext(ID2D1DeviceContext6 *iface, D2D1_COLOR_SPACE space, const BYTE *profile, UINT32 profile_size, ID2D1ColorContext **color_context) { FIXME("iface %p, space %#x, profile %p, profile_size %u, color_context %p stub!\n", @@ -1809,7 +2081,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContext(ID2D1Devi return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContextFromFilename(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContextFromFilename(ID2D1DeviceContext6 *iface, const WCHAR *filename, ID2D1ColorContext **color_context) { FIXME("iface %p, filename %s, color_context %p stub!\n", iface, debugstr_w(filename), color_context); @@ -1817,7 +2089,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContextFromFilena return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContextFromWicColorContext(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContextFromWicColorContext(ID2D1DeviceContext6 *iface, IWICColorContext *wic_color_context, ID2D1ColorContext **color_context) { FIXME("iface %p, wic_color_context %p, color_context %p stub!\n", iface, wic_color_context, color_context); @@ -1825,30 +2097,82 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContextFromWicCol return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromDxgiSurface(ID2D1DeviceContext *iface, +static BOOL d2d_bitmap_check_options_with_surface(unsigned int options, unsigned int surface_options) +{ + switch (options) + { + case D2D1_BITMAP_OPTIONS_NONE: + case D2D1_BITMAP_OPTIONS_TARGET: + case D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW: + case D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE: + case D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE: + case D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ: + case D2D1_BITMAP_OPTIONS_CANNOT_DRAW: + break; + default: + WARN("Invalid bitmap options %#x.\n", options); + return FALSE; + } + + if (options && (options & D2D1_BITMAP_OPTIONS_TARGET) != (surface_options & D2D1_BITMAP_OPTIONS_TARGET)) + return FALSE; + if (!(options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW) && (surface_options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW)) + return FALSE; + if (options & D2D1_BITMAP_OPTIONS_TARGET) + { + if (options & D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE && !(surface_options & D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE)) + return FALSE; + return TRUE; + } + + if (options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW) + { + if (!(surface_options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW)) + return FALSE; + + if (options & D2D1_BITMAP_OPTIONS_CPU_READ && !(surface_options & D2D1_BITMAP_OPTIONS_CPU_READ)) + return FALSE; + } + + return TRUE; +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromDxgiSurface(ID2D1DeviceContext6 *iface, IDXGISurface *surface, const D2D1_BITMAP_PROPERTIES1 *desc, ID2D1Bitmap1 **bitmap) { struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); D2D1_BITMAP_PROPERTIES1 bitmap_desc; + unsigned int surface_options; struct d2d_bitmap *object; HRESULT hr; TRACE("iface %p, surface %p, desc %p, bitmap %p.\n", iface, surface, desc, bitmap); - if (!desc) + surface_options = d2d_get_bitmap_options_for_surface(surface); + + if (desc) + { + if (!d2d_bitmap_check_options_with_surface(desc->bitmapOptions, surface_options)) + { + WARN("Incompatible bitmap options %#x, surface options %#x.\n", + desc->bitmapOptions, surface_options); + return E_INVALIDARG; + } + } + else { DXGI_SURFACE_DESC surface_desc; if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc))) { - WARN("Failed to get surface desc, hr %#x.\n", hr); + WARN("Failed to get surface desc, hr %#lx.\n", hr); return hr; } memset(&bitmap_desc, 0, sizeof(bitmap_desc)); bitmap_desc.pixelFormat.format = surface_desc.Format; bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; - bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW; + bitmap_desc.bitmapOptions = surface_options; desc = &bitmap_desc; } @@ -1858,26 +2182,18 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromDxgiSurface( return hr; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateEffect(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateEffect(ID2D1DeviceContext6 *iface, REFCLSID effect_id, ID2D1Effect **effect) { - struct d2d_effect *object; - - FIXME("iface %p, effect_id %s, effect %p stub!\n", iface, debugstr_guid(effect_id), effect); - - if (!(object = heap_alloc_zero(sizeof(*object)))) - return E_OUTOFMEMORY; - - d2d_effect_init(object); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); - TRACE("Created effect %p.\n", object); - *effect = &object->ID2D1Effect_iface; + TRACE("iface %p, effect_id %s, effect %p.\n", iface, debugstr_guid(effect_id), effect); - return S_OK; + return d2d_effect_create(context, effect_id, effect); } static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateGradientStopCollection( - ID2D1DeviceContext *iface, const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, + ID2D1DeviceContext6 *iface, const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_COLOR_SPACE preinterpolation_space, D2D1_COLOR_SPACE postinterpolation_space, D2D1_BUFFER_PRECISION buffer_precision, D2D1_EXTEND_MODE extend_mode, D2D1_COLOR_INTERPOLATION_MODE color_interpolation_mode, ID2D1GradientStopCollection1 **gradient) @@ -1890,17 +2206,25 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateGra return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateImageBrush(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateImageBrush(ID2D1DeviceContext6 *iface, ID2D1Image *image, const D2D1_IMAGE_BRUSH_PROPERTIES *image_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1ImageBrush **brush) { - FIXME("iface %p, image %p, image_brush_desc %p, brush_desc %p, brush %p stub!\n", - iface, image, image_brush_desc, brush_desc, brush); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + struct d2d_brush *object; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, image %p, image_brush_desc %p, brush_desc %p, brush %p.\n", iface, image, image_brush_desc, + brush_desc, brush); + + if (SUCCEEDED(hr = d2d_image_brush_create(context->factory, image, image_brush_desc, + brush_desc, &object))) + *brush = (ID2D1ImageBrush *)&object->ID2D1Brush_iface; + + return hr; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateBitmapBrush(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateBitmapBrush(ID2D1DeviceContext6 *iface, ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES1 *bitmap_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush1 **brush) { @@ -1917,36 +2241,103 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateBit return hr; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateCommandList(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateCommandList(ID2D1DeviceContext6 *iface, ID2D1CommandList **command_list) { - FIXME("iface %p, command_list %p stub!\n", iface, command_list); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + struct d2d_command_list *object; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, command_list %p.\n", iface, command_list); + + if (SUCCEEDED(hr = d2d_command_list_create(context->factory, &object))) + *command_list = &object->ID2D1CommandList_iface; + + return hr; } -static BOOL STDMETHODCALLTYPE d2d_device_context_IsDxgiFormatSupported(ID2D1DeviceContext *iface, DXGI_FORMAT format) +static BOOL STDMETHODCALLTYPE d2d_device_context_IsDxgiFormatSupported(ID2D1DeviceContext6 *iface, DXGI_FORMAT format) { FIXME("iface %p, format %#x stub!\n", iface, format); return FALSE; } -static BOOL STDMETHODCALLTYPE d2d_device_context_IsBufferPrecisionSupported(ID2D1DeviceContext *iface, +static BOOL STDMETHODCALLTYPE d2d_device_context_IsBufferPrecisionSupported(ID2D1DeviceContext6 *iface, D2D1_BUFFER_PRECISION buffer_precision) { - FIXME("iface %p, buffer_precision %#x stub!\n", iface, buffer_precision); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + DXGI_FORMAT format; + UINT support = 0; + HRESULT hr; - return FALSE; -} + TRACE("iface %p, buffer_precision %u.\n", iface, buffer_precision); -static void STDMETHODCALLTYPE d2d_device_context_GetImageLocalBounds(ID2D1DeviceContext *iface, + switch (buffer_precision) + { + case D2D1_BUFFER_PRECISION_8BPC_UNORM: format = DXGI_FORMAT_R8G8B8A8_UNORM; break; + case D2D1_BUFFER_PRECISION_8BPC_UNORM_SRGB: format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; break; + case D2D1_BUFFER_PRECISION_16BPC_UNORM: format = DXGI_FORMAT_R16G16B16A16_UNORM; break; + case D2D1_BUFFER_PRECISION_16BPC_FLOAT: format = DXGI_FORMAT_R16G16B16A16_FLOAT; break; + case D2D1_BUFFER_PRECISION_32BPC_FLOAT: format = DXGI_FORMAT_R32G32B32A32_FLOAT; break; + default: + WARN("Unexpected precision %u.\n", buffer_precision); + return FALSE; + } + + if (FAILED(hr = ID3D11Device1_CheckFormatSupport(context->d3d_device, format, &support))) + { + WARN("Format support check failed, hr %#lx.\n", hr); + } + + return !!(support & D3D11_FORMAT_SUPPORT_BUFFER); +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_GetImageLocalBounds(ID2D1DeviceContext6 *iface, ID2D1Image *image, D2D1_RECT_F *local_bounds) { - FIXME("iface %p, image %p, local_bounds %p stub!\n", iface, image, local_bounds); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + D2D_SIZE_U pixel_size; + ID2D1Bitmap *bitmap; + D2D_SIZE_F size; + + TRACE("iface %p, image %p, local_bounds %p.\n", iface, image, local_bounds); + + if (SUCCEEDED(ID2D1Image_QueryInterface(image, &IID_ID2D1Bitmap, (void **)&bitmap))) + { + local_bounds->left = 0.0f; + local_bounds->top = 0.0f; + switch (context->drawing_state.unitMode) + { + case D2D1_UNIT_MODE_DIPS: + size = ID2D1Bitmap_GetSize(bitmap); + local_bounds->right = size.width; + local_bounds->bottom = size.height; + break; + + case D2D1_UNIT_MODE_PIXELS: + pixel_size = ID2D1Bitmap_GetPixelSize(bitmap); + local_bounds->right = pixel_size.width; + local_bounds->bottom = pixel_size.height; + break; + + default: + WARN("Unknown unit mode %#x.\n", context->drawing_state.unitMode); + break; + } + ID2D1Bitmap_Release(bitmap); + + return S_OK; + } + else + { + FIXME("Unable to get local bounds of image %p.\n", image); + + return E_NOTIMPL; + } } -static HRESULT STDMETHODCALLTYPE d2d_device_context_GetImageWorldBounds(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_GetImageWorldBounds(ID2D1DeviceContext6 *iface, ID2D1Image *image, D2D1_RECT_F *world_bounds) { FIXME("iface %p, image %p, world_bounds %p stub!\n", iface, image, world_bounds); @@ -1954,7 +2345,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_GetImageWorldBounds(ID2D1Dev return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_GetGlyphRunWorldBounds(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_GetGlyphRunWorldBounds(ID2D1DeviceContext6 *iface, D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, DWRITE_MEASURING_MODE measuring_mode, D2D1_RECT_F *bounds) { @@ -1964,37 +2355,40 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_GetGlyphRunWorldBounds(ID2D1 return E_NOTIMPL; } -static void STDMETHODCALLTYPE d2d_device_context_GetDevice(ID2D1DeviceContext *iface, ID2D1Device **device) +static void STDMETHODCALLTYPE d2d_device_context_GetDevice(ID2D1DeviceContext6 *iface, ID2D1Device **device) { struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); TRACE("iface %p, device %p.\n", iface, device); - *device = context->device; + *device = (ID2D1Device *)&context->device->ID2D1Device6_iface; ID2D1Device_AddRef(*device); } static void d2d_device_context_reset_target(struct d2d_device_context *context) { - if (!context->target) + if (!context->target.object) return; - ID2D1Bitmap1_Release(&context->target->ID2D1Bitmap1_iface); - context->target = NULL; + IUnknown_Release(context->target.object); + memset(&context->target, 0, sizeof(context->target)); /* Note that DPI settings are kept. */ memset(&context->desc.pixelFormat, 0, sizeof(context->desc.pixelFormat)); memset(&context->pixel_size, 0, sizeof(context->pixel_size)); - ID3D10BlendState_Release(context->bs); + if (context->bs) + ID3D11BlendState_Release(context->bs); context->bs = NULL; } -static void STDMETHODCALLTYPE d2d_device_context_SetTarget(ID2D1DeviceContext *iface, ID2D1Image *target) +static void STDMETHODCALLTYPE d2d_device_context_SetTarget(ID2D1DeviceContext6 *iface, ID2D1Image *target) { struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + struct d2d_command_list *command_list_impl; struct d2d_bitmap *bitmap_impl; - D3D10_BLEND_DESC blend_desc; + ID2D1CommandList *command_list; + D3D11_BLEND_DESC blend_desc; ID2D1Bitmap *bitmap; HRESULT hr; @@ -2006,184 +2400,146 @@ static void STDMETHODCALLTYPE d2d_device_context_SetTarget(ID2D1DeviceContext *i return; } - if (FAILED(ID2D1Image_QueryInterface(target, &IID_ID2D1Bitmap, (void **)&bitmap))) + if (SUCCEEDED(ID2D1Image_QueryInterface(target, &IID_ID2D1Bitmap, (void **)&bitmap))) { - FIXME("Only bitmap targets are supported.\n"); - return; - } + bitmap_impl = unsafe_impl_from_ID2D1Bitmap(bitmap); - bitmap_impl = unsafe_impl_from_ID2D1Bitmap(bitmap); + if (!(bitmap_impl->options & D2D1_BITMAP_OPTIONS_TARGET)) + { + ID2D1Bitmap_Release(bitmap); + d2d_device_context_set_error(context, D2DERR_INVALID_TARGET); + return; + } - if (!(bitmap_impl->options & D2D1_BITMAP_OPTIONS_TARGET)) - { - d2d_device_context_set_error(context, D2DERR_INVALID_TARGET); - return; - } + d2d_device_context_reset_target(context); - d2d_device_context_reset_target(context); + /* Set sizes and pixel format. */ + context->pixel_size = bitmap_impl->pixel_size; + context->desc.pixelFormat = bitmap_impl->format; + context->target.bitmap = bitmap_impl; + context->target.object = target; + context->target.type = D2D_TARGET_BITMAP; + + memset(&blend_desc, 0, sizeof(blend_desc)); + blend_desc.IndependentBlendEnable = FALSE; + blend_desc.RenderTarget[0].BlendEnable = TRUE; + blend_desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + blend_desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + blend_desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blend_desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blend_desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; + blend_desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blend_desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + if (FAILED(hr = ID3D11Device1_CreateBlendState(context->d3d_device, &blend_desc, &context->bs))) + WARN("Failed to create blend state, hr %#lx.\n", hr); + } + else if (SUCCEEDED(ID2D1Image_QueryInterface(target, &IID_ID2D1CommandList, (void **)&command_list))) + { + command_list_impl = unsafe_impl_from_ID2D1CommandList(command_list); - /* Set sizes and pixel format. */ - context->pixel_size = bitmap_impl->pixel_size; - context->desc.pixelFormat = bitmap_impl->format; - context->target = bitmap_impl; + d2d_device_context_reset_target(context); - memset(&blend_desc, 0, sizeof(blend_desc)); - blend_desc.BlendEnable[0] = TRUE; - blend_desc.SrcBlend = D3D10_BLEND_ONE; - blend_desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA; - blend_desc.BlendOp = D3D10_BLEND_OP_ADD; - if (context->desc.pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE) - { - blend_desc.SrcBlendAlpha = D3D10_BLEND_ZERO; - blend_desc.DestBlendAlpha = D3D10_BLEND_ONE; + context->target.command_list = command_list_impl; + context->target.object = target; + context->target.type = D2D_TARGET_COMMAND_LIST; } else { - blend_desc.SrcBlendAlpha = D3D10_BLEND_ONE; - blend_desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA; + WARN("Unsupported target type.\n"); } - blend_desc.BlendOpAlpha = D3D10_BLEND_OP_ADD; - blend_desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL; - if (FAILED(hr = ID3D10Device_CreateBlendState(context->d3d_device, &blend_desc, &context->bs))) - WARN("Failed to create blend state, hr %#x.\n", hr); } -static void STDMETHODCALLTYPE d2d_device_context_GetTarget(ID2D1DeviceContext *iface, ID2D1Image **target) +static void STDMETHODCALLTYPE d2d_device_context_GetTarget(ID2D1DeviceContext6 *iface, ID2D1Image **target) { struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); TRACE("iface %p, target %p.\n", iface, target); - *target = context->target ? (ID2D1Image *)&context->target->ID2D1Bitmap1_iface : NULL; + *target = context->target.object ? context->target.object : NULL; if (*target) ID2D1Image_AddRef(*target); } -static void STDMETHODCALLTYPE d2d_device_context_SetRenderingControls(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_SetRenderingControls(ID2D1DeviceContext6 *iface, const D2D1_RENDERING_CONTROLS *rendering_controls) { FIXME("iface %p, rendering_controls %p stub!\n", iface, rendering_controls); } -static void STDMETHODCALLTYPE d2d_device_context_GetRenderingControls(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_GetRenderingControls(ID2D1DeviceContext6 *iface, D2D1_RENDERING_CONTROLS *rendering_controls) { FIXME("iface %p, rendering_controls %p stub!\n", iface, rendering_controls); } -static void STDMETHODCALLTYPE d2d_device_context_SetPrimitiveBlend(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_SetPrimitiveBlend(ID2D1DeviceContext6 *iface, D2D1_PRIMITIVE_BLEND primitive_blend) { - FIXME("iface %p, primitive_blend %#x stub!\n", iface, primitive_blend); -} - -static D2D1_PRIMITIVE_BLEND STDMETHODCALLTYPE d2d_device_context_GetPrimitiveBlend(ID2D1DeviceContext *iface) -{ - FIXME("iface %p stub!\n", iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); - return D2D1_PRIMITIVE_BLEND_SOURCE_OVER; -} + TRACE("iface %p, primitive_blend %u.\n", iface, primitive_blend); -static void STDMETHODCALLTYPE d2d_device_context_SetUnitMode(ID2D1DeviceContext *iface, D2D1_UNIT_MODE unit_mode) -{ - FIXME("iface %p, unit_mode %#x stub!\n", iface, unit_mode); -} + if (primitive_blend > D2D1_PRIMITIVE_BLEND_MAX) + { + WARN("Unknown blend mode %u.\n", primitive_blend); + return; + } -static D2D1_UNIT_MODE STDMETHODCALLTYPE d2d_device_context_GetUnitMode(ID2D1DeviceContext *iface) -{ - FIXME("iface %p stub!\n", iface); + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_set_primitive_blend(context->target.command_list, primitive_blend); - return D2D1_UNIT_MODE_DIPS; + context->drawing_state.primitiveBlend = primitive_blend; } -static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_DrawGlyphRun(ID2D1DeviceContext *iface, - D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, - const DWRITE_GLYPH_RUN_DESCRIPTION *glyph_run_desc, ID2D1Brush *brush, DWRITE_MEASURING_MODE measuring_mode) +static D2D1_PRIMITIVE_BLEND STDMETHODCALLTYPE d2d_device_context_GetPrimitiveBlend(ID2D1DeviceContext6 *iface) { - DWRITE_TEXT_ANTIALIAS_MODE antialias_mode = DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE; struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); - IDWriteRenderingParams *rendering_params; - DWRITE_RENDERING_MODE rendering_mode; - HRESULT hr; - TRACE("iface %p, baseline_origin %s, glyph_run %p, glyph_run_desc %p, brush %p, measuring_mode %#x.\n", - iface, debug_d2d_point_2f(&baseline_origin), glyph_run, glyph_run_desc, brush, measuring_mode); + TRACE("iface %p.\n", iface); - if (FAILED(context->error.code)) - return; + return context->drawing_state.primitiveBlend; +} - rendering_params = context->text_rendering_params ? context->text_rendering_params - : context->default_text_rendering_params; +static void STDMETHODCALLTYPE d2d_device_context_SetUnitMode(ID2D1DeviceContext6 *iface, D2D1_UNIT_MODE unit_mode) +{ + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); - rendering_mode = IDWriteRenderingParams_GetRenderingMode(rendering_params); + TRACE("iface %p, unit_mode %#x.\n", iface, unit_mode); - switch (context->drawing_state.textAntialiasMode) + if (unit_mode != D2D1_UNIT_MODE_DIPS && unit_mode != D2D1_UNIT_MODE_PIXELS) { - case D2D1_TEXT_ANTIALIAS_MODE_ALIASED: - if (rendering_mode == DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL - || rendering_mode == DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC - || rendering_mode == DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL - || rendering_mode == DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC) - d2d_device_context_set_error(context, E_INVALIDARG); - break; - - case D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE: - if (rendering_mode == DWRITE_RENDERING_MODE_ALIASED - || rendering_mode == DWRITE_RENDERING_MODE_OUTLINE) - d2d_device_context_set_error(context, E_INVALIDARG); - break; - - case D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE: - if (rendering_mode == DWRITE_RENDERING_MODE_ALIASED) - d2d_device_context_set_error(context, E_INVALIDARG); - break; - - default: - break; + WARN("Unknown unit mode %#x.\n", unit_mode); + return; } - if (FAILED(context->error.code)) - return; + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_set_unit_mode(context->target.command_list, unit_mode); - rendering_mode = DWRITE_RENDERING_MODE_DEFAULT; - switch (context->drawing_state.textAntialiasMode) - { - case D2D1_TEXT_ANTIALIAS_MODE_DEFAULT: - if (IDWriteRenderingParams_GetClearTypeLevel(rendering_params) > 0.0f) - antialias_mode = DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE; - break; + context->drawing_state.unitMode = unit_mode; +} - case D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE: - antialias_mode = DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE; - break; +static D2D1_UNIT_MODE STDMETHODCALLTYPE d2d_device_context_GetUnitMode(ID2D1DeviceContext6 *iface) +{ + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); - case D2D1_TEXT_ANTIALIAS_MODE_ALIASED: - rendering_mode = DWRITE_RENDERING_MODE_ALIASED; - break; + TRACE("iface %p.\n", iface); - default: - break; - } + return context->drawing_state.unitMode; +} - if (rendering_mode == DWRITE_RENDERING_MODE_DEFAULT) - { - if (FAILED(hr = IDWriteFontFace_GetRecommendedRenderingMode(glyph_run->fontFace, glyph_run->fontEmSize, - max(context->desc.dpiX, context->desc.dpiY) / 96.0f, - measuring_mode, rendering_params, &rendering_mode))) - { - ERR("Failed to get recommended rendering mode, hr %#x.\n", hr); - rendering_mode = DWRITE_RENDERING_MODE_OUTLINE; - } - } +static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_DrawGlyphRun(ID2D1DeviceContext6 *iface, + D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, + const DWRITE_GLYPH_RUN_DESCRIPTION *glyph_run_desc, ID2D1Brush *brush, DWRITE_MEASURING_MODE measuring_mode) +{ + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); - if (rendering_mode == DWRITE_RENDERING_MODE_OUTLINE) - d2d_device_context_draw_glyph_run_outline(context, baseline_origin, glyph_run, brush); - else - d2d_device_context_draw_glyph_run_bitmap(context, baseline_origin, glyph_run, brush, - rendering_mode, measuring_mode, antialias_mode); + TRACE("iface %p, baseline_origin %s, glyph_run %p, glyph_run_desc %p, brush %p, measuring_mode %#x.\n", + iface, debug_d2d_point_2f(&baseline_origin), glyph_run, glyph_run_desc, brush, measuring_mode); + + d2d_device_context_draw_glyph_run(context, baseline_origin, glyph_run, glyph_run_desc, brush, measuring_mode); } -static void STDMETHODCALLTYPE d2d_device_context_DrawImage(ID2D1DeviceContext *iface, ID2D1Image *image, +static void STDMETHODCALLTYPE d2d_device_context_DrawImage(ID2D1DeviceContext6 *iface, ID2D1Image *image, const D2D1_POINT_2F *target_offset, const D2D1_RECT_F *image_rect, D2D1_INTERPOLATION_MODE interpolation_mode, D2D1_COMPOSITE_MODE composite_mode) { @@ -2194,13 +2550,19 @@ static void STDMETHODCALLTYPE d2d_device_context_DrawImage(ID2D1DeviceContext *i iface, image, debug_d2d_point_2f(target_offset), debug_d2d_rect_f(image_rect), interpolation_mode, composite_mode); + if (context->target.type == D2D_TARGET_COMMAND_LIST) + { + d2d_command_list_draw_image(context->target.command_list, image, target_offset, image_rect, + interpolation_mode, composite_mode); + return; + } + if (composite_mode != D2D1_COMPOSITE_MODE_SOURCE_OVER) FIXME("Unhandled composite mode %#x.\n", composite_mode); if (SUCCEEDED(ID2D1Image_QueryInterface(image, &IID_ID2D1Bitmap, (void **)&bitmap))) { - d2d_device_context_draw_bitmap(context, bitmap, NULL, 1.0f, d2d1_1_interp_mode_from_d2d1(interpolation_mode), - image_rect, target_offset, NULL); + d2d_device_context_draw_bitmap(context, bitmap, NULL, 1.0f, interpolation_mode, image_rect, target_offset, NULL); ID2D1Bitmap_Release(bitmap); return; @@ -2209,14 +2571,14 @@ static void STDMETHODCALLTYPE d2d_device_context_DrawImage(ID2D1DeviceContext *i FIXME("Unhandled image %p.\n", image); } -static void STDMETHODCALLTYPE d2d_device_context_DrawGdiMetafile(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_DrawGdiMetafile(ID2D1DeviceContext6 *iface, ID2D1GdiMetafile *metafile, const D2D1_POINT_2F *target_offset) { FIXME("iface %p, metafile %p, target_offset %s stub!\n", iface, metafile, debug_d2d_point_2f(target_offset)); } -static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_DrawBitmap(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_DrawBitmap(ID2D1DeviceContext6 *iface, ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity, D2D1_INTERPOLATION_MODE interpolation_mode, const D2D1_RECT_F *src_rect, const D2D1_MATRIX_4X4_F *perspective_transform) { @@ -2227,17 +2589,30 @@ static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_DrawBitmap(I iface, bitmap, debug_d2d_rect_f(dst_rect), opacity, interpolation_mode, debug_d2d_rect_f(src_rect), perspective_transform); - d2d_device_context_draw_bitmap(context, bitmap, dst_rect, opacity, interpolation_mode, src_rect, - NULL, perspective_transform); + if (context->target.type == D2D_TARGET_COMMAND_LIST) + { + d2d_command_list_draw_bitmap(context->target.command_list, bitmap, dst_rect, opacity, interpolation_mode, + src_rect, perspective_transform); + } + else + { + d2d_device_context_draw_bitmap(context, bitmap, dst_rect, opacity, interpolation_mode, src_rect, + NULL, perspective_transform); + } } -static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_PushLayer(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_PushLayer(ID2D1DeviceContext6 *iface, const D2D1_LAYER_PARAMETERS1 *layer_parameters, ID2D1Layer *layer) { + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + FIXME("iface %p, layer_parameters %p, layer %p stub!\n", iface, layer_parameters, layer); + + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_push_layer(context->target.command_list, context, layer_parameters, layer); } -static HRESULT STDMETHODCALLTYPE d2d_device_context_InvalidateEffectInputRectangle(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_InvalidateEffectInputRectangle(ID2D1DeviceContext6 *iface, ID2D1Effect *effect, UINT32 input, const D2D1_RECT_F *input_rect) { FIXME("iface %p, effect %p, input %u, input_rect %s stub!\n", @@ -2246,7 +2621,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_InvalidateEffectInputRectang return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_GetEffectInvalidRectangleCount(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_GetEffectInvalidRectangleCount(ID2D1DeviceContext6 *iface, ID2D1Effect *effect, UINT32 *rect_count) { FIXME("iface %p, effect %p, rect_count %p stub!\n", iface, effect, rect_count); @@ -2254,7 +2629,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_GetEffectInvalidRectangleCou return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_GetEffectInvalidRectangles(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_GetEffectInvalidRectangles(ID2D1DeviceContext6 *iface, ID2D1Effect *effect, D2D1_RECT_F *rectangles, UINT32 rect_count) { FIXME("iface %p, effect %p, rectangles %p, rect_count %u stub!\n", iface, effect, rectangles, rect_count); @@ -2262,7 +2637,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_GetEffectInvalidRectangles(I return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_device_context_GetEffectRequiredInputRectangles(ID2D1DeviceContext *iface, +static HRESULT STDMETHODCALLTYPE d2d_device_context_GetEffectRequiredInputRectangles(ID2D1DeviceContext6 *iface, ID2D1Effect *effect, const D2D1_RECT_F *image_rect, const D2D1_EFFECT_INPUT_DESCRIPTION *desc, D2D1_RECT_F *input_rect, UINT32 input_count) { @@ -2272,14 +2647,276 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_GetEffectRequiredInputRectan return E_NOTIMPL; } -static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_FillOpacityMask(ID2D1DeviceContext *iface, +static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_FillOpacityMask(ID2D1DeviceContext6 *iface, ID2D1Bitmap *mask, ID2D1Brush *brush, const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect) { + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + FIXME("iface %p, mask %p, brush %p, dst_rect %s, src_rect %s stub!\n", iface, mask, brush, debug_d2d_rect_f(dst_rect), debug_d2d_rect_f(src_rect)); + + if (FAILED(context->error.code)) + return; + + if (context->drawing_state.antialiasMode != D2D1_ANTIALIAS_MODE_ALIASED) + { + d2d_device_context_set_error(context, D2DERR_WRONG_STATE); + return; + } + + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_fill_opacity_mask(context->target.command_list, context, mask, brush, dst_rect, src_rect); +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateFilledGeometryRealization(ID2D1DeviceContext6 *iface, + ID2D1Geometry *geometry, float tolerance, ID2D1GeometryRealization **realization) +{ + FIXME("iface %p, geometry %p, tolerance %.8e, realization %p stub!\n", iface, geometry, tolerance, + realization); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateStrokedGeometryRealization( + ID2D1DeviceContext6 *iface, ID2D1Geometry *geometry, float tolerance, float stroke_width, + ID2D1StrokeStyle *stroke_style, ID2D1GeometryRealization **realization) +{ + FIXME("iface %p, geometry %p, tolerance %.8e, stroke_width %.8e, stroke_style %p, realization %p stub!\n", + iface, geometry, tolerance, stroke_width, stroke_style, realization); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d2d_device_context_DrawGeometryRealization(ID2D1DeviceContext6 *iface, + ID2D1GeometryRealization *realization, ID2D1Brush *brush) +{ + FIXME("iface %p, realization %p, brush %p stub!\n", iface, realization, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateInk(ID2D1DeviceContext6 *iface, + const D2D1_INK_POINT *start_point, ID2D1Ink **ink) +{ + FIXME("iface %p, start_point %p, ink %p stub!\n", iface, start_point, ink); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateInkStyle(ID2D1DeviceContext6 *iface, + const D2D1_INK_STYLE_PROPERTIES *ink_style_properties, ID2D1InkStyle **ink_style) +{ + FIXME("iface %p, ink_style_properties %p, ink_style %p stub!\n", iface, ink_style_properties, ink_style); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateGradientMesh(ID2D1DeviceContext6 *iface, + const D2D1_GRADIENT_MESH_PATCH *patches, UINT32 patches_count, + ID2D1GradientMesh **gradient_mesh) +{ + FIXME("iface %p, patches %p, patches_count %u, gradient_mesh %p stub!\n", iface, patches, + patches_count, gradient_mesh); + + return E_NOTIMPL; } -static const struct ID2D1DeviceContextVtbl d2d_device_context_vtbl = +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateImageSourceFromWic(ID2D1DeviceContext6 *iface, + IWICBitmapSource *wic_bitmap_source, D2D1_IMAGE_SOURCE_LOADING_OPTIONS loading_options, + D2D1_ALPHA_MODE alpha_mode, ID2D1ImageSourceFromWic **image_source) +{ + FIXME("iface %p, wic_bitmap_source %p, loading_options %#x, alpha_mode %u, image_source %p stub!\n", + iface, wic_bitmap_source, loading_options, alpha_mode, image_source); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateLookupTable3D(ID2D1DeviceContext6 *iface, + D2D1_BUFFER_PRECISION precision, const UINT32 *extents, const BYTE *data, + UINT32 data_count, const UINT32 *strides, ID2D1LookupTable3D **lookup_table) +{ + FIXME("iface %p, precision %u, extents %p, data %p, data_count %u, strides %p, lookup_table %p stub!\n", + iface, precision, extents, data, data_count, strides, lookup_table); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateImageSourceFromDxgi(ID2D1DeviceContext6 *iface, + IDXGISurface **surfaces, UINT32 surface_count, DXGI_COLOR_SPACE_TYPE color_space, + D2D1_IMAGE_SOURCE_FROM_DXGI_OPTIONS options, ID2D1ImageSource **image_source) +{ + FIXME("iface %p, surfaces %p, surface_count %u, color_space %u, options %#x, image_source %p stub!\n", + iface, surfaces, surface_count, color_space, options, image_source); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_GetGradientMeshWorldBounds(ID2D1DeviceContext6 *iface, + ID2D1GradientMesh *gradient_mesh, D2D1_RECT_F *bounds) +{ + FIXME("iface %p, gradient_mesh %p, bounds %p stub!\n", iface, gradient_mesh, bounds); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d2d_device_context_DrawInk(ID2D1DeviceContext6 *iface, ID2D1Ink *ink, + ID2D1Brush *brush, ID2D1InkStyle *ink_style) +{ + FIXME("iface %p, ink %p, brush %p, ink_style %p stub!\n", iface, ink, brush, ink_style); +} + +static void STDMETHODCALLTYPE d2d_device_context_DrawGradientMesh(ID2D1DeviceContext6 *iface, + ID2D1GradientMesh *gradient_mesh) +{ + FIXME("iface %p, gradient_mesh %p stub!\n", iface, gradient_mesh); +} + +static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext2_DrawGdiMetafile( + ID2D1DeviceContext6 *iface, ID2D1GdiMetafile *gdi_metafile, const D2D1_RECT_F *dst_rect, + const D2D1_RECT_F *src_rect) +{ + FIXME("iface %p, gdi_metafile %p, dst_rect %s, src_rect %s stub!\n", iface, gdi_metafile, + debug_d2d_rect_f(dst_rect), debug_d2d_rect_f(src_rect)); +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateTransformedImageSource(ID2D1DeviceContext6 *iface, + ID2D1ImageSource *source, const D2D1_TRANSFORMED_IMAGE_SOURCE_PROPERTIES *props, + ID2D1TransformedImageSource **transformed) +{ + FIXME("iface %p, source %p, props %p, transformed %p stub!\n", iface, source, props, transformed); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSpriteBatch(ID2D1DeviceContext6 *iface, + ID2D1SpriteBatch **sprite_batch) +{ + FIXME("iface %p, sprite_batch %p stub!\n", iface, sprite_batch); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d2d_device_context_DrawSpriteBatch(ID2D1DeviceContext6 *iface, + ID2D1SpriteBatch *sprite_batch, UINT32 start_index, UINT32 sprite_count, ID2D1Bitmap *bitmap, + D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, D2D1_SPRITE_OPTIONS sprite_options) +{ + FIXME("iface %p, sprite_batch %p, start_index %u, sprite_count %u, bitmap %p, interpolation_mode %u," + "sprite_options %u stub!\n", iface, sprite_batch, start_index, sprite_count, bitmap, + interpolation_mode, sprite_options); +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSvgGlyphStyle(ID2D1DeviceContext6 *iface, + ID2D1SvgGlyphStyle **svg_glyph_style) +{ + FIXME("iface %p, svg_glyph_style %p stub!\n", iface, svg_glyph_style); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext4_DrawText(ID2D1DeviceContext6 *iface, + const WCHAR *string, UINT32 string_length, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect, + ID2D1Brush *default_fill_brush, ID2D1SvgGlyphStyle *svg_glyph_style, UINT32 color_palette_index, + D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode) +{ + FIXME("iface %p, string %s, string_length %u, text_format %p, layout_rect %s, default_fill_brush %p," + "svg_glyph_style %p, color_palette_index %u, options %#x, measuring_mode %u stub!\n", + iface, debugstr_wn(string, string_length), string_length, text_format, debug_d2d_rect_f(layout_rect), + default_fill_brush, svg_glyph_style, color_palette_index, options, measuring_mode); +} + +static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext4_DrawTextLayout(ID2D1DeviceContext6 *iface, + D2D1_POINT_2F origin, IDWriteTextLayout *text_layout, ID2D1Brush *default_fill_brush, + ID2D1SvgGlyphStyle *svg_glyph_style, UINT32 color_palette_index, D2D1_DRAW_TEXT_OPTIONS options) +{ + FIXME("iface %p, origin %s, text_layout %p, default_fill_brush %p, svg_glyph_style %p, color_palette_index %u," + "options %#x stub!\n", iface, debug_d2d_point_2f(&origin), text_layout, default_fill_brush, + svg_glyph_style, color_palette_index, options); +} + +static void STDMETHODCALLTYPE d2d_device_context_DrawColorBitmapGlyphRun(ID2D1DeviceContext6 *iface, + DWRITE_GLYPH_IMAGE_FORMATS glyph_image_format, D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, + DWRITE_MEASURING_MODE measuring_mode, D2D1_COLOR_BITMAP_GLYPH_SNAP_OPTION bitmap_snap_option) +{ + FIXME("iface %p, glyph_image_format %#x, baseline_origin %s, glyph_run %p, measuring_mode %u, bitmap_snap_option %#x stub!\n", + iface, glyph_image_format, debug_d2d_point_2f(&baseline_origin), glyph_run, measuring_mode, bitmap_snap_option); +} + +static void STDMETHODCALLTYPE d2d_device_context_DrawSvgGlyphRun(ID2D1DeviceContext6 *iface, + D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *default_fill_brush, + ID2D1SvgGlyphStyle *svg_glyph_style, UINT32 color_palette_index, DWRITE_MEASURING_MODE measuring_mode) +{ + FIXME("iface %p, baseline_origin %s, glyph_run %p, default_fill_brush %p, svg_glyph_style %p," + "color_palette_index %u, measuring_mode %u stub!\n", iface, debug_d2d_point_2f(&baseline_origin), + glyph_run, default_fill_brush, svg_glyph_style, color_palette_index, measuring_mode); +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_GetColorBitmapGlyphImage(ID2D1DeviceContext6 *iface, + DWRITE_GLYPH_IMAGE_FORMATS glyph_image_format, D2D1_POINT_2F glyph_origin, IDWriteFontFace *font_face, + FLOAT font_em_size, UINT16 glyph_index, BOOL is_sideways, const D2D1_MATRIX_3X2_F *world_transform, + FLOAT dpi_x, FLOAT dpi_y, D2D1_MATRIX_3X2_F *glyph_transform, ID2D1Image **glyph_image) +{ + FIXME("iface %p, glyph_image_format %u, glyph_origin %s, font_face %p, font_em_size %f, glyph_index %u," + "is_sideways %d, world_transform %p, dpi_x %f, dpi_y %f, glyph_transform %p, glyph_image %p stub!\n", + iface, glyph_image_format, debug_d2d_point_2f(&glyph_origin), font_face, font_em_size, glyph_index, + is_sideways, world_transform, dpi_x, dpi_y, glyph_transform, glyph_image); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_GetSvgGlyphImage(ID2D1DeviceContext6 *iface, + D2D1_POINT_2F glyph_origin, IDWriteFontFace *font_face, FLOAT font_em_size, UINT16 glyph_index, + BOOL is_sideways, const D2D1_MATRIX_3X2_F *world_transform, ID2D1Brush *default_fill_brush, + ID2D1SvgGlyphStyle *svg_glyph_style, UINT32 color_palette_index, D2D1_MATRIX_3X2_F *glyph_transform, + ID2D1CommandList **glyph_image) +{ + FIXME("iface %p, glyph_origin %s, font_face %p, font_em_size %f, glyph_index %u, is_sideways %d," + "world_transform %p, default_fill_brush %p, svg_glyph_style %p, color_palette_index %u," + "glyph_transform %p, glyph_image %p stub!\n", iface, debug_d2d_point_2f(&glyph_origin), + font_face, font_em_size, glyph_index, is_sideways, world_transform, default_fill_brush, + svg_glyph_style, color_palette_index, glyph_transform, glyph_image); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSvgDocument(ID2D1DeviceContext6 *iface, + IStream *input_xml_stream, D2D1_SIZE_F viewport_size, ID2D1SvgDocument **svg_document) +{ + FIXME("iface %p, input_xml_stream %p, svg_document %p stub!\n", iface, input_xml_stream, + svg_document); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d2d_device_context_DrawSvgDocument(ID2D1DeviceContext6 *iface, + ID2D1SvgDocument *svg_document) +{ + FIXME("iface %p, svg_document %p stub!\n", iface, svg_document); +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContextFromDxgiColorSpace( + ID2D1DeviceContext6 *iface, DXGI_COLOR_SPACE_TYPE color_space, ID2D1ColorContext1 **color_context) +{ + FIXME("iface %p, color_space %u, color_context %p stub!\n", iface, color_space, color_context); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContextFromSimpleColorProfile( + ID2D1DeviceContext6 *iface, const D2D1_SIMPLE_COLOR_PROFILE *simple_profile, ID2D1ColorContext1 **color_context) +{ + FIXME("iface %p, simple_profile %p, color_context %p stub!\n", iface, simple_profile, color_context); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d2d_device_context_BlendImage(ID2D1DeviceContext6 *iface, ID2D1Image *image, + D2D1_BLEND_MODE blend_mode, const D2D1_POINT_2F *target_offset, const D2D1_RECT_F *image_rect, + D2D1_INTERPOLATION_MODE interpolation_mode) +{ + FIXME("iface %p, image %p, blend_mode %u, target_offset %s, image_rect %s, interpolation_mode %u stub!\n", + iface, image, blend_mode, debug_d2d_point_2f(target_offset), debug_d2d_rect_f(image_rect), + interpolation_mode); +} + +static const struct ID2D1DeviceContext6Vtbl d2d_device_context_vtbl = { d2d_device_context_QueryInterface, d2d_device_context_AddRef, @@ -2373,6 +3010,34 @@ static const struct ID2D1DeviceContextVtbl d2d_device_context_vtbl = d2d_device_context_GetEffectInvalidRectangles, d2d_device_context_GetEffectRequiredInputRectangles, d2d_device_context_ID2D1DeviceContext_FillOpacityMask, + d2d_device_context_CreateFilledGeometryRealization, + d2d_device_context_CreateStrokedGeometryRealization, + d2d_device_context_DrawGeometryRealization, + d2d_device_context_CreateInk, + d2d_device_context_CreateInkStyle, + d2d_device_context_CreateGradientMesh, + d2d_device_context_CreateImageSourceFromWic, + d2d_device_context_CreateLookupTable3D, + d2d_device_context_CreateImageSourceFromDxgi, + d2d_device_context_GetGradientMeshWorldBounds, + d2d_device_context_DrawInk, + d2d_device_context_DrawGradientMesh, + d2d_device_context_ID2D1DeviceContext2_DrawGdiMetafile, + d2d_device_context_CreateTransformedImageSource, + d2d_device_context_CreateSpriteBatch, + d2d_device_context_DrawSpriteBatch, + d2d_device_context_CreateSvgGlyphStyle, + d2d_device_context_ID2D1DeviceContext4_DrawText, + d2d_device_context_ID2D1DeviceContext4_DrawTextLayout, + d2d_device_context_DrawColorBitmapGlyphRun, + d2d_device_context_DrawSvgGlyphRun, + d2d_device_context_GetColorBitmapGlyphImage, + d2d_device_context_GetSvgGlyphImage, + d2d_device_context_CreateSvgDocument, + d2d_device_context_DrawSvgDocument, + d2d_device_context_CreateColorContextFromDxgiColorSpace, + d2d_device_context_CreateColorContextFromSimpleColorProfile, + d2d_device_context_BlendImage, }; static inline struct d2d_device_context *impl_from_IDWriteTextRenderer(IDWriteTextRenderer *iface) @@ -2401,20 +3066,20 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_QueryInterface(IDWriteTextRen static ULONG STDMETHODCALLTYPE d2d_text_renderer_AddRef(IDWriteTextRenderer *iface) { - struct d2d_device_context *render_target = impl_from_IDWriteTextRenderer(iface); + struct d2d_device_context *context = impl_from_IDWriteTextRenderer(iface); TRACE("iface %p.\n", iface); - return d2d_device_context_AddRef(&render_target->ID2D1DeviceContext_iface); + return d2d_device_context_AddRef(&context->ID2D1DeviceContext6_iface); } static ULONG STDMETHODCALLTYPE d2d_text_renderer_Release(IDWriteTextRenderer *iface) { - struct d2d_device_context *render_target = impl_from_IDWriteTextRenderer(iface); + struct d2d_device_context *context = impl_from_IDWriteTextRenderer(iface); TRACE("iface %p.\n", iface); - return d2d_device_context_Release(&render_target->ID2D1DeviceContext_iface); + return d2d_device_context_Release(&context->ID2D1DeviceContext6_iface); } static HRESULT STDMETHODCALLTYPE d2d_text_renderer_IsPixelSnappingDisabled(IDWriteTextRenderer *iface, @@ -2432,11 +3097,11 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_IsPixelSnappingDisabled(IDWri static HRESULT STDMETHODCALLTYPE d2d_text_renderer_GetCurrentTransform(IDWriteTextRenderer *iface, void *ctx, DWRITE_MATRIX *transform) { - struct d2d_device_context *render_target = impl_from_IDWriteTextRenderer(iface); + struct d2d_device_context *context = impl_from_IDWriteTextRenderer(iface); TRACE("iface %p, ctx %p, transform %p.\n", iface, ctx, transform); - d2d_device_context_GetTransform(&render_target->ID2D1DeviceContext_iface, (D2D1_MATRIX_3X2_F *)transform); + d2d_device_context_GetTransform(&context->ID2D1DeviceContext6_iface, (D2D1_MATRIX_3X2_F *)transform); return S_OK; } @@ -2454,7 +3119,7 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_GetPixelsPerDip(IDWriteTextRe static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawGlyphRun(IDWriteTextRenderer *iface, void *ctx, float baseline_origin_x, float baseline_origin_y, DWRITE_MEASURING_MODE measuring_mode, - const DWRITE_GLYPH_RUN *glyph_run, const DWRITE_GLYPH_RUN_DESCRIPTION *desc, IUnknown *effect) + const DWRITE_GLYPH_RUN *glyph_run, const DWRITE_GLYPH_RUN_DESCRIPTION *glyph_run_desc, IUnknown *effect) { struct d2d_device_context *render_target = impl_from_IDWriteTextRenderer(iface); D2D1_POINT_2F baseline_origin = {baseline_origin_x, baseline_origin_y}; @@ -2463,18 +3128,16 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawGlyphRun(IDWriteTextRende ID2D1Brush *brush; TRACE("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, " - "measuring_mode %#x, glyph_run %p, desc %p, effect %p.\n", + "measuring_mode %#x, glyph_run %p, glyph_run_desc %p, effect %p.\n", iface, ctx, baseline_origin_x, baseline_origin_y, - measuring_mode, glyph_run, desc, effect); + measuring_mode, glyph_run, glyph_run_desc, effect); - if (desc) - WARN("Ignoring glyph run description %p.\n", desc); if (context->options & ~(D2D1_DRAW_TEXT_OPTIONS_NO_SNAP | D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT)) FIXME("Ignoring options %#x.\n", context->options); brush = d2d_draw_get_text_brush(context, effect); - TRACE("%s\n", debugstr_wn(desc->string, desc->stringLength)); + TRACE("%s\n", debugstr_wn(glyph_run_desc->string, glyph_run_desc->stringLength)); if (context->options & D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT) { @@ -2497,17 +3160,17 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawGlyphRun(IDWriteTextRende if (FAILED(hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory2, (IUnknown **)&dwrite_factory))) { - ERR("Failed to create dwrite factory, hr %#x.\n", hr); + ERR("Failed to create dwrite factory, hr %#lx.\n", hr); ID2D1Brush_Release(brush); return hr; } hr = IDWriteFactory2_TranslateColorGlyphRun(dwrite_factory, baseline_origin_x, baseline_origin_y, - glyph_run, desc, measuring_mode, (DWRITE_MATRIX *)&render_target->drawing_state.transform, 0, &layers); + glyph_run, glyph_run_desc, measuring_mode, (DWRITE_MATRIX *)&render_target->drawing_state.transform, 0, &layers); IDWriteFactory2_Release(dwrite_factory); if (FAILED(hr)) { - ERR("Failed to create color glyph run enumerator, hr %#x.\n", hr); + ERR("Failed to create colour glyph run enumerator, hr %#lx.\n", hr); ID2D1Brush_Release(brush); return hr; } @@ -2521,7 +3184,7 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawGlyphRun(IDWriteTextRende if (FAILED(hr = IDWriteColorGlyphRunEnumerator_MoveNext(layers, &has_run))) { - ERR("Failed to switch color glyph layer, hr %#x.\n", hr); + ERR("Failed to switch colour glyph layer, hr %#lx.\n", hr); break; } @@ -2530,7 +3193,7 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawGlyphRun(IDWriteTextRende if (FAILED(hr = IDWriteColorGlyphRunEnumerator_GetCurrentRun(layers, &color_run))) { - ERR("Failed to get current color run, hr %#x.\n", hr); + ERR("Failed to get current colour run, hr %#lx.\n", hr); break; } @@ -2538,18 +3201,18 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawGlyphRun(IDWriteTextRende color_brush = brush; else { - if (FAILED(hr = d2d_device_context_CreateSolidColorBrush(&render_target->ID2D1DeviceContext_iface, + if (FAILED(hr = d2d_device_context_CreateSolidColorBrush(&render_target->ID2D1DeviceContext6_iface, &color_run->runColor, NULL, (ID2D1SolidColorBrush **)&color_brush))) { - ERR("Failed to create solid color brush, hr %#x.\n", hr); + ERR("Failed to create solid colour brush, hr %#lx.\n", hr); break; } } origin.x = color_run->baselineOriginX; origin.y = color_run->baselineOriginY; - d2d_device_context_DrawGlyphRun(&render_target->ID2D1DeviceContext_iface, - origin, &color_run->glyphRun, color_brush, measuring_mode); + d2d_device_context_draw_glyph_run(render_target, origin, &color_run->glyphRun, + color_run->glyphRunDescription, color_brush, measuring_mode); if (color_brush != brush) ID2D1Brush_Release(color_brush); @@ -2558,8 +3221,8 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawGlyphRun(IDWriteTextRende IDWriteColorGlyphRunEnumerator_Release(layers); } else - d2d_device_context_DrawGlyphRun(&render_target->ID2D1DeviceContext_iface, - baseline_origin, glyph_run, brush, measuring_mode); + d2d_device_context_draw_glyph_run(render_target, baseline_origin, glyph_run, glyph_run_desc, + brush, measuring_mode); ID2D1Brush_Release(brush); @@ -2591,7 +3254,7 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawUnderline(IDWriteTextRend end.x = start.x + underline->width; end.y = start.y; prev_antialias_mode = d2d_device_context_set_aa_mode_from_text_aa_mode(render_target); - d2d_device_context_DrawLine(&render_target->ID2D1DeviceContext_iface, start, end, brush, thickness, NULL); + d2d_device_context_DrawLine(&render_target->ID2D1DeviceContext6_iface, start, end, brush, thickness, NULL); render_target->drawing_state.antialiasMode = prev_antialias_mode; ID2D1Brush_Release(brush); @@ -2624,7 +3287,7 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawStrikethrough(IDWriteText end.x = start.x + strikethrough->width; end.y = start.y; prev_antialias_mode = d2d_device_context_set_aa_mode_from_text_aa_mode(render_target); - d2d_device_context_DrawLine(&render_target->ID2D1DeviceContext_iface, start, end, brush, thickness, NULL); + d2d_device_context_DrawLine(&render_target->ID2D1DeviceContext6_iface, start, end, brush, thickness, NULL); render_target->drawing_state.antialiasMode = prev_antialias_mode; ID2D1Brush_Release(brush); @@ -2704,18 +3367,27 @@ static ULONG STDMETHODCALLTYPE d2d_gdi_interop_render_target_Release(ID2D1GdiInt return IUnknown_Release(render_target->outer_unknown); } -static HRESULT d2d_device_context_get_surface(struct d2d_device_context *render_target, IDXGISurface1 **surface) +static HRESULT d2d_gdi_interop_get_surface(struct d2d_device_context *context, IDXGISurface1 **surface) { - ID3D10Resource *resource; + ID3D11Resource *resource; HRESULT hr; - ID3D10RenderTargetView_GetResource(render_target->target->rtv, &resource); - hr = ID3D10Resource_QueryInterface(resource, &IID_IDXGISurface1, (void **)surface); - ID3D10Resource_Release(resource); + if (context->target.type != D2D_TARGET_BITMAP) + { + FIXME("Unimplemented for target type %u.\n", context->target.type); + return E_NOTIMPL; + } + + if (!(context->target.bitmap->options & D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE)) + return D2DERR_TARGET_NOT_GDI_COMPATIBLE; + + ID3D11RenderTargetView_GetResource(context->target.bitmap->rtv, &resource); + hr = ID3D11Resource_QueryInterface(resource, &IID_IDXGISurface1, (void **)surface); + ID3D11Resource_Release(resource); if (FAILED(hr)) { *surface = NULL; - WARN("Failed to get DXGI surface, %#x.\n", hr); + WARN("Failed to get DXGI surface, %#lx.\n", hr); return hr; } @@ -2731,12 +3403,20 @@ static HRESULT STDMETHODCALLTYPE d2d_gdi_interop_render_target_GetDC(ID2D1GdiInt TRACE("iface %p, mode %d, dc %p.\n", iface, mode, dc); - if (FAILED(hr = d2d_device_context_get_surface(render_target, &surface))) + *dc = NULL; + + if (render_target->target.hdc) + return D2DERR_WRONG_STATE; + + if (FAILED(hr = d2d_gdi_interop_get_surface(render_target, &surface))) return hr; - hr = IDXGISurface1_GetDC(surface, mode != D2D1_DC_INITIALIZE_MODE_COPY, dc); + hr = IDXGISurface1_GetDC(surface, mode != D2D1_DC_INITIALIZE_MODE_COPY, &render_target->target.hdc); IDXGISurface1_Release(surface); + if (SUCCEEDED(hr)) + *dc = render_target->target.hdc; + return hr; } @@ -2750,9 +3430,13 @@ static HRESULT STDMETHODCALLTYPE d2d_gdi_interop_render_target_ReleaseDC(ID2D1Gd TRACE("iface %p, update rect %s.\n", iface, wine_dbgstr_rect(update)); - if (FAILED(hr = d2d_device_context_get_surface(render_target, &surface))) + if (!render_target->target.hdc) + return D2DERR_WRONG_STATE; + + if (FAILED(hr = d2d_gdi_interop_get_surface(render_target, &surface))) return hr; + render_target->target.hdc = NULL; if (update) update_rect = *update; hr = IDXGISurface1_ReleaseDC(surface, update ? &update_rect : NULL); @@ -2770,143 +3454,91 @@ static const struct ID2D1GdiInteropRenderTargetVtbl d2d_gdi_interop_render_targe d2d_gdi_interop_render_target_ReleaseDC, }; -static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, ID2D1Device *device, - IUnknown *outer_unknown, const struct d2d_device_context_ops *ops) +static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, + struct d2d_device *device, IUnknown *outer_unknown, const struct d2d_device_context_ops *ops) { - D3D10_SUBRESOURCE_DATA buffer_data; - D3D10_STATE_BLOCK_MASK state_mask; + D3D11_SUBRESOURCE_DATA buffer_data; struct d2d_device *device_impl; IDWriteFactory *dwrite_factory; - D3D10_RASTERIZER_DESC rs_desc; - D3D10_BUFFER_DESC buffer_desc; + D3D11_RASTERIZER_DESC rs_desc; + D3D11_BUFFER_DESC buffer_desc; + struct d2d_factory *factory; + ID3D10Blob *compiled; unsigned int i; HRESULT hr; - static const D3D10_INPUT_ELEMENT_DESC il_desc_outline[] = + static const D3D11_INPUT_ELEMENT_DESC il_desc_outline[] = { - {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, - {"PREV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0}, - {"NEXT", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0}, - }; - static const D3D10_INPUT_ELEMENT_DESC il_desc_curve_outline[] = - { - {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, - {"P", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0}, - {"P", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0}, - {"P", 2, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0}, - {"PREV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 32, D3D10_INPUT_PER_VERTEX_DATA, 0}, - {"NEXT", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 40, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"PREV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"NEXT", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; - static const D3D10_INPUT_ELEMENT_DESC il_desc_triangle[] = + static const D3D11_INPUT_ELEMENT_DESC il_desc_curve_outline[] = { - {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"P", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"P", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"P", 2, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"PREV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"NEXT", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 40, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; - static const D3D10_INPUT_ELEMENT_DESC il_desc_curve[] = + static const D3D11_INPUT_ELEMENT_DESC il_desc_triangle[] = { - {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; - static const DWORD vs_code_outline[] = + static const D3D11_INPUT_ELEMENT_DESC il_desc_curve[] = { -#if 0 - float3x2 transform_geometry; - float stroke_width; - float4 transform_rtx; - float4 transform_rty; - - struct output - { - float2 p : WORLD_POSITION; - float4 b : BEZIER; - nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM; - float4 position : SV_POSITION; - }; - - /* The lines PₚᵣₑᵥP₀ and P₀Pₙₑₓₜ, both offset by ±½w, intersect each other at: - * - * Pᵢ = P₀ ± w · ½q⃑ᵢ. - * - * Where: - * - * q⃑ᵢ = q̂ₚᵣₑᵥ⊥ + tan(½θ) · -q̂ₚᵣₑᵥ - * θ = ∠PₚᵣₑᵥP₀Pₙₑₓₜ - * q⃑ₚᵣₑᵥ = P₀ - Pₚᵣₑᵥ */ - void main(float2 position : POSITION, float2 prev : PREV, float2 next : NEXT, out struct output o) - { - float2 q_prev, q_next, v_p, q_i; - float2x2 geom; - float l; - - o.stroke_transform = float2x2(transform_rtx.xy, transform_rty.xy) * stroke_width * 0.5f; - - geom = float2x2(transform_geometry._11_21, transform_geometry._12_22); - q_prev = normalize(mul(geom, prev)); - q_next = normalize(mul(geom, next)); - - /* tan(½θ) = sin(θ) / (1 + cos(θ)) - * = (q̂ₚᵣₑᵥ⊥ · q̂ₙₑₓₜ) / (1 + (q̂ₚᵣₑᵥ · q̂ₙₑₓₜ)) */ - v_p = float2(-q_prev.y, q_prev.x); - l = -dot(v_p, q_next) / (1.0f + dot(q_prev, q_next)); - q_i = l * q_prev + v_p; - - o.b = float4(0.0, 0.0, 0.0, 0.0); - - o.p = mul(float3(position, 1.0f), transform_geometry) + stroke_width * 0.5f * q_i; - position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f)) - * float2(transform_rtx.w, transform_rty.w); - o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f); - } -#endif - 0x43425844, 0xfb16cd75, 0xf5ec3e80, 0xceacf250, 0x91d29d18, 0x00000001, 0x00000608, 0x00000003, - 0x0000002c, 0x00000098, 0x00000154, 0x4e475349, 0x00000064, 0x00000003, 0x00000008, 0x00000050, - 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x00000059, 0x00000000, 0x00000000, - 0x00000003, 0x00000001, 0x00000303, 0x0000005e, 0x00000000, 0x00000000, 0x00000003, 0x00000002, - 0x00000303, 0x49534f50, 0x4e4f4954, 0x45525000, 0x454e0056, 0xab005458, 0x4e47534f, 0x000000b4, - 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000c03, - 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x00000096, 0x00000000, - 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096, 0x00000001, 0x00000000, 0x00000003, - 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001, 0x00000003, 0x00000004, 0x0000000f, - 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052, 0x454b4f52, 0x4152545f, - 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f, 0x52444853, 0x000004ac, 0x00010040, - 0x0000012b, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, 0x0300005f, 0x00101032, 0x00000000, - 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x00101032, 0x00000002, 0x03000065, 0x00102032, - 0x00000000, 0x03000065, 0x001020f2, 0x00000001, 0x03000065, 0x00102032, 0x00000002, 0x03000065, - 0x00102032, 0x00000003, 0x04000067, 0x001020f2, 0x00000004, 0x00000001, 0x02000068, 0x00000003, - 0x0800000f, 0x00100012, 0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000002, - 0x0800000f, 0x00100022, 0x00000000, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000002, - 0x0700000f, 0x00100042, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000000, 0x05000044, - 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x07000038, 0x00100032, 0x00000000, 0x00100aa6, - 0x00000000, 0x00100046, 0x00000000, 0x0800000f, 0x00100012, 0x00000001, 0x00208046, 0x00000000, - 0x00000000, 0x00101046, 0x00000001, 0x0800000f, 0x00100022, 0x00000001, 0x00208046, 0x00000000, - 0x00000001, 0x00101046, 0x00000001, 0x0700000f, 0x00100042, 0x00000000, 0x00100046, 0x00000001, - 0x00100046, 0x00000001, 0x05000044, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x07000038, - 0x00100032, 0x00000001, 0x00100aa6, 0x00000000, 0x00100046, 0x00000001, 0x06000036, 0x001000c2, - 0x00000001, 0x80100556, 0x00000041, 0x00000001, 0x0700000f, 0x00100042, 0x00000000, 0x00100a26, - 0x00000001, 0x00100046, 0x00000000, 0x0700000f, 0x00100012, 0x00000000, 0x00100046, 0x00000001, - 0x00100046, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, - 0x3f800000, 0x0800000e, 0x00100012, 0x00000000, 0x8010002a, 0x00000041, 0x00000000, 0x0010000a, - 0x00000000, 0x09000032, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00100046, 0x00000001, - 0x00100f36, 0x00000001, 0x08000038, 0x00100042, 0x00000000, 0x0020803a, 0x00000000, 0x00000001, - 0x00004001, 0x3f000000, 0x05000036, 0x00100032, 0x00000001, 0x00101046, 0x00000000, 0x05000036, - 0x00100042, 0x00000001, 0x00004001, 0x3f800000, 0x08000010, 0x00100012, 0x00000002, 0x00100246, - 0x00000001, 0x00208246, 0x00000000, 0x00000000, 0x08000010, 0x00100022, 0x00000002, 0x00100246, - 0x00000001, 0x00208246, 0x00000000, 0x00000001, 0x09000032, 0x00100032, 0x00000000, 0x00100aa6, - 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000002, 0x05000036, 0x00102032, 0x00000000, - 0x00100046, 0x00000000, 0x08000036, 0x001020f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x06000036, 0x00100032, 0x00000001, 0x00208046, 0x00000000, 0x00000002, - 0x06000036, 0x001000c2, 0x00000001, 0x00208406, 0x00000000, 0x00000003, 0x08000038, 0x001000f2, - 0x00000001, 0x00100e46, 0x00000001, 0x00208ff6, 0x00000000, 0x00000001, 0x0a000038, 0x001000f2, - 0x00000001, 0x00100e46, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, - 0x05000036, 0x00102032, 0x00000002, 0x00100086, 0x00000001, 0x05000036, 0x00102032, 0x00000003, - 0x001005d6, 0x00000001, 0x05000036, 0x00100042, 0x00000000, 0x00004001, 0x3f800000, 0x08000010, - 0x00100082, 0x00000000, 0x00208246, 0x00000000, 0x00000002, 0x00100246, 0x00000000, 0x08000010, - 0x00100012, 0x00000000, 0x00208246, 0x00000000, 0x00000003, 0x00100246, 0x00000000, 0x08000038, - 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000003, 0x08000038, - 0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x0020803a, 0x00000000, 0x00000002, 0x0a000000, - 0x00102032, 0x00000004, 0x00100046, 0x00000000, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, - 0x00000000, 0x08000036, 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, - 0x3f800000, 0x0100003e, + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; + static const char vs_code_outline[] = + "float3x2 transform_geometry;\n" + "float stroke_width;\n" + "float4 transform_rtx;\n" + "float4 transform_rty;\n" + "\n" + "struct output\n" + "{\n" + " float2 p : WORLD_POSITION;\n" + " float4 b : BEZIER;\n" + " nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;\n" + " float4 position : SV_POSITION;\n" + "};\n" + "\n" + "/* The lines PₚᵣₑᵥP₀ and P₀Pₙₑₓₜ, both offset by ±½w, intersect each other at:\n" + " *\n" + " * Pᵢ = P₀ ± w · ½q⃑ᵢ.\n" + " *\n" + " * Where:\n" + " *\n" + " * q⃑ᵢ = q̂ₚᵣₑᵥ⊥ + tan(½θ) · -q̂ₚᵣₑᵥ\n" + " * θ = ∠PₚᵣₑᵥP₀Pₙₑₓₜ\n" + " * q⃑ₚᵣₑᵥ = P₀ - Pₚᵣₑᵥ */\n" + "void main(float2 position : POSITION, float2 prev : PREV, float2 next : NEXT, out struct output o)\n" + "{\n" + " float2 q_prev, q_next, v_p, q_i;\n" + " float2x2 geom;\n" + " float l;\n" + "\n" + " o.stroke_transform = float2x2(transform_rtx.xy, transform_rty.xy) * stroke_width * 0.5f;\n" + "\n" + " geom = float2x2(transform_geometry._11_21, transform_geometry._12_22);\n" + " q_prev = normalize(mul(geom, prev));\n" + " q_next = normalize(mul(geom, next));\n" + "\n" + " /* tan(½θ) = sin(θ) / (1 + cos(θ))\n" + " * = (q̂ₚᵣₑᵥ⊥ · q̂ₙₑₓₜ) / (1 + (q̂ₚᵣₑᵥ · q̂ₙₑₓₜ)) */\n" + " v_p = float2(-q_prev.y, q_prev.x);\n" + " l = -dot(v_p, q_next) / (1.0f + dot(q_prev, q_next));\n" + " q_i = l * q_prev + v_p;\n" + "\n" + " o.b = float4(0.0, 0.0, 0.0, 0.0);\n" + "\n" + " o.p = mul(float3(position, 1.0f), transform_geometry) + stroke_width * 0.5f * q_i;\n" + " position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f))\n" + " * float2(transform_rtx.w, transform_rty.w);\n" + " o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n" + "}\n"; /* ⎡p0.x p0.y 1⎤ * A = ⎢p1.x p1.y 1⎥ * ⎣p2.x p2.y 1⎦ @@ -2924,160 +3556,68 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, * A'T = B' * T = A'⁻¹B' */ - static const DWORD vs_code_bezier_outline[] = - { -#if 0 - float3x2 transform_geometry; - float stroke_width; - float4 transform_rtx; - float4 transform_rty; - - struct output - { - float2 p : WORLD_POSITION; - float4 b : BEZIER; - nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM; - float4 position : SV_POSITION; - }; - - void main(float2 position : POSITION, float2 p0 : P0, float2 p1 : P1, float2 p2 : P2, - float2 prev : PREV, float2 next : NEXT, out struct output o) - { - float2 q_prev, q_next, v_p, q_i, p; - float2x2 geom, rt; - float l; - - geom = float2x2(transform_geometry._11_21, transform_geometry._12_22); - rt = float2x2(transform_rtx.xy, transform_rty.xy); - o.stroke_transform = rt * stroke_width * 0.5f; - - p = mul(geom, position); - p0 = mul(geom, p0); - p1 = mul(geom, p1); - p2 = mul(geom, p2); - - p -= p0; - p1 -= p0; - p2 -= p0; - - q_prev = normalize(mul(geom, prev)); - q_next = normalize(mul(geom, next)); - - v_p = float2(-q_prev.y, q_prev.x); - l = -dot(v_p, q_next) / (1.0f + dot(q_prev, q_next)); - q_i = l * q_prev + v_p; - p += 0.5f * stroke_width * q_i; - - v_p = mul(rt, p2); - v_p = normalize(float2(-v_p.y, v_p.x)); - if (abs(dot(mul(rt, p1), v_p)) < 1.0f) - { - o.b.xzw = float3(0.0f, 0.0f, 0.0f); - o.b.y = dot(mul(rt, p), v_p); - } - else - { - o.b.zw = sign(dot(mul(rt, p1), v_p)) * v_p; - v_p = -float2(-p.y, p.x) / dot(float2(-p1.y, p1.x), p2); - o.b.x = dot(v_p, p1 - 0.5f * p2); - o.b.y = dot(v_p, p1); - } - - o.p = mul(float3(position, 1.0f), transform_geometry) + 0.5f * stroke_width * q_i; - position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f)) - * float2(transform_rtx.w, transform_rty.w); - o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f); - } -#endif - 0x43425844, 0x356a0c5f, 0x8e4ba153, 0xe52cf793, 0xa6b774ea, 0x00000001, 0x00000afc, 0x00000003, - 0x0000002c, 0x000000e4, 0x000001a0, 0x4e475349, 0x000000b0, 0x00000006, 0x00000008, 0x00000098, - 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x000000a1, 0x00000000, 0x00000000, - 0x00000003, 0x00000001, 0x00000303, 0x000000a1, 0x00000001, 0x00000000, 0x00000003, 0x00000002, - 0x00000303, 0x000000a1, 0x00000002, 0x00000000, 0x00000003, 0x00000003, 0x00000303, 0x000000a3, - 0x00000000, 0x00000000, 0x00000003, 0x00000004, 0x00000303, 0x000000a8, 0x00000000, 0x00000000, - 0x00000003, 0x00000005, 0x00000303, 0x49534f50, 0x4e4f4954, 0x50005000, 0x00564552, 0x5458454e, - 0xababab00, 0x4e47534f, 0x000000b4, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000, - 0x00000003, 0x00000000, 0x00000c03, 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001, - 0x0000000f, 0x00000096, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096, - 0x00000001, 0x00000000, 0x00000003, 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001, - 0x00000003, 0x00000004, 0x0000000f, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, - 0x54530052, 0x454b4f52, 0x4152545f, 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f, - 0x52444853, 0x00000954, 0x00010040, 0x00000255, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, - 0x0300005f, 0x00101032, 0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x00101032, - 0x00000002, 0x0300005f, 0x00101032, 0x00000003, 0x0300005f, 0x00101032, 0x00000004, 0x0300005f, - 0x00101032, 0x00000005, 0x03000065, 0x00102032, 0x00000000, 0x03000065, 0x001020f2, 0x00000001, - 0x03000065, 0x00102032, 0x00000002, 0x03000065, 0x00102032, 0x00000003, 0x04000067, 0x001020f2, - 0x00000004, 0x00000001, 0x02000068, 0x00000006, 0x0800000f, 0x00100012, 0x00000000, 0x00208046, - 0x00000000, 0x00000000, 0x00101046, 0x00000005, 0x0800000f, 0x00100022, 0x00000000, 0x00208046, - 0x00000000, 0x00000001, 0x00101046, 0x00000005, 0x0700000f, 0x00100042, 0x00000000, 0x00100046, - 0x00000000, 0x00100046, 0x00000000, 0x05000044, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, - 0x07000038, 0x00100032, 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x0800000f, - 0x00100012, 0x00000001, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000004, 0x0800000f, - 0x00100022, 0x00000001, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000004, 0x0700000f, - 0x00100042, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000001, 0x05000044, 0x00100042, - 0x00000000, 0x0010002a, 0x00000000, 0x07000038, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000, - 0x00100046, 0x00000001, 0x06000036, 0x001000c2, 0x00000001, 0x80100556, 0x00000041, 0x00000001, - 0x0700000f, 0x00100042, 0x00000000, 0x00100a26, 0x00000001, 0x00100046, 0x00000000, 0x0700000f, - 0x00100012, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000000, 0x07000000, 0x00100012, - 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0800000e, 0x00100012, 0x00000000, - 0x8010002a, 0x00000041, 0x00000000, 0x0010000a, 0x00000000, 0x09000032, 0x00100032, 0x00000000, - 0x00100006, 0x00000000, 0x00100046, 0x00000001, 0x00100f36, 0x00000001, 0x05000036, 0x00100032, - 0x00000001, 0x00101046, 0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000, - 0x08000010, 0x00100012, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000000, - 0x08000010, 0x00100022, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000001, - 0x08000038, 0x00100042, 0x00000000, 0x0020803a, 0x00000000, 0x00000001, 0x00004001, 0x3f000000, - 0x09000032, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046, - 0x00000002, 0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000001, 0x0800000f, 0x00100012, - 0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000000, 0x0800000f, 0x00100022, - 0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000000, 0x0800000f, 0x00100012, - 0x00000003, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000001, 0x0800000f, 0x00100022, - 0x00000003, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000001, 0x08000000, 0x00100032, - 0x00000002, 0x00100046, 0x00000002, 0x80100046, 0x00000041, 0x00000003, 0x09000032, 0x00100032, - 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000002, 0x0800000f, - 0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000002, 0x00100046, 0x00000000, 0x0800000f, - 0x00100022, 0x00000002, 0x00208046, 0x00000000, 0x00000003, 0x00100046, 0x00000000, 0x0800000f, - 0x00100012, 0x00000004, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000003, 0x0800000f, - 0x00100022, 0x00000004, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000003, 0x08000000, - 0x001000c2, 0x00000002, 0x80100406, 0x00000041, 0x00000003, 0x00100406, 0x00000004, 0x0800000f, - 0x00100082, 0x00000000, 0x00208046, 0x00000000, 0x00000003, 0x00100ae6, 0x00000002, 0x06000036, - 0x00100042, 0x00000003, 0x8010003a, 0x00000041, 0x00000000, 0x0800000f, 0x00100082, 0x00000003, - 0x00208046, 0x00000000, 0x00000002, 0x00100ae6, 0x00000002, 0x0700000f, 0x00100082, 0x00000000, - 0x00100ae6, 0x00000003, 0x00100ae6, 0x00000003, 0x05000044, 0x00100082, 0x00000000, 0x0010003a, - 0x00000000, 0x07000038, 0x001000c2, 0x00000003, 0x00100ff6, 0x00000000, 0x00100ea6, 0x00000003, - 0x0700000f, 0x00100022, 0x00000004, 0x00100046, 0x00000002, 0x00100ae6, 0x00000003, 0x06000036, - 0x00100042, 0x00000000, 0x8010001a, 0x00000041, 0x00000000, 0x0800000f, 0x00100012, 0x00000002, - 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000002, 0x0800000f, 0x00100022, 0x00000002, - 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000002, 0x08000000, 0x00100032, 0x00000005, - 0x80100046, 0x00000041, 0x00000003, 0x00100046, 0x00000002, 0x06000036, 0x00100042, 0x00000005, - 0x8010001a, 0x00000041, 0x00000005, 0x0700000f, 0x00100022, 0x00000000, 0x00100a26, 0x00000005, - 0x00100ae6, 0x00000002, 0x0d000032, 0x00100032, 0x00000002, 0x80100ae6, 0x00000041, 0x00000002, - 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00100046, 0x00000005, 0x0800000e, - 0x00100032, 0x00000000, 0x80100a26, 0x00000041, 0x00000000, 0x00100556, 0x00000000, 0x0700000f, - 0x00100012, 0x00000002, 0x00100046, 0x00000000, 0x00100046, 0x00000002, 0x0700000f, 0x00100022, - 0x00000002, 0x00100046, 0x00000000, 0x00100046, 0x00000005, 0x0800000f, 0x00100012, 0x00000000, - 0x00208046, 0x00000000, 0x00000002, 0x00100046, 0x00000005, 0x0800000f, 0x00100022, 0x00000000, - 0x00208046, 0x00000000, 0x00000003, 0x00100046, 0x00000005, 0x0700000f, 0x00100012, 0x00000000, - 0x00100046, 0x00000000, 0x00100ae6, 0x00000003, 0x07000031, 0x00100022, 0x00000000, 0x00004001, - 0x00000000, 0x0010000a, 0x00000000, 0x07000031, 0x00100042, 0x00000000, 0x0010000a, 0x00000000, - 0x00004001, 0x00000000, 0x08000031, 0x00100012, 0x00000000, 0x8010000a, 0x00000081, 0x00000000, - 0x00004001, 0x3f800000, 0x0800001e, 0x00100022, 0x00000000, 0x8010001a, 0x00000041, 0x00000000, - 0x0010002a, 0x00000000, 0x0500002b, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x07000038, - 0x001000c2, 0x00000002, 0x00100ea6, 0x00000003, 0x00100556, 0x00000000, 0x08000036, 0x001000d2, - 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x09000037, 0x001020f2, - 0x00000001, 0x00100006, 0x00000000, 0x00100e46, 0x00000004, 0x00100e46, 0x00000002, 0x06000036, - 0x00100032, 0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x06000036, 0x001000c2, 0x00000000, - 0x00208406, 0x00000000, 0x00000003, 0x08000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, - 0x00208ff6, 0x00000000, 0x00000001, 0x0a000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, - 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x05000036, 0x00102032, 0x00000002, - 0x00100086, 0x00000000, 0x05000036, 0x00102032, 0x00000003, 0x001005d6, 0x00000000, 0x05000036, - 0x00100042, 0x00000001, 0x00004001, 0x3f800000, 0x08000010, 0x00100012, 0x00000000, 0x00208246, - 0x00000000, 0x00000002, 0x00100246, 0x00000001, 0x08000010, 0x00100022, 0x00000000, 0x00208246, - 0x00000000, 0x00000003, 0x00100246, 0x00000001, 0x08000038, 0x00100022, 0x00000001, 0x0010001a, - 0x00000000, 0x0020803a, 0x00000000, 0x00000003, 0x08000038, 0x00100012, 0x00000001, 0x0010000a, - 0x00000000, 0x0020803a, 0x00000000, 0x00000002, 0x0a000000, 0x00102032, 0x00000004, 0x00100046, - 0x00000001, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000, 0x08000036, 0x001020c2, - 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e, - }; + static const char vs_code_bezier_outline[] = + "float3x2 transform_geometry;\n" + "float stroke_width;\n" + "float4 transform_rtx;\n" + "float4 transform_rty;\n" + "\n" + "struct output\n" + "{\n" + " float2 p : WORLD_POSITION;\n" + " float4 b : BEZIER;\n" + " nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;\n" + " float4 position : SV_POSITION;\n" + "};\n" + "\n" + "void main(float2 position : POSITION, float2 p0 : P0, float2 p1 : P1, float2 p2 : P2,\n" + " float2 prev : PREV, float2 next : NEXT, out struct output o)\n" + "{\n" + " float2 q_prev, q_next, v_p, q_i, p;\n" + " float2x2 geom, rt;\n" + " float l;\n" + "\n" + " geom = float2x2(transform_geometry._11_21, transform_geometry._12_22);\n" + " rt = float2x2(transform_rtx.xy, transform_rty.xy);\n" + " o.stroke_transform = rt * stroke_width * 0.5f;\n" + "\n" + " p = mul(geom, position);\n" + " p0 = mul(geom, p0);\n" + " p1 = mul(geom, p1);\n" + " p2 = mul(geom, p2);\n" + "\n" + " p -= p0;\n" + " p1 -= p0;\n" + " p2 -= p0;\n" + "\n" + " q_prev = normalize(mul(geom, prev));\n" + " q_next = normalize(mul(geom, next));\n" + "\n" + " v_p = float2(-q_prev.y, q_prev.x);\n" + " l = -dot(v_p, q_next) / (1.0f + dot(q_prev, q_next));\n" + " q_i = l * q_prev + v_p;\n" + " p += 0.5f * stroke_width * q_i;\n" + "\n" + " v_p = mul(rt, p2);\n" + " v_p = normalize(float2(-v_p.y, v_p.x));\n" + " if (abs(dot(mul(rt, p1), v_p)) < 1.0f)\n" + " {\n" + " o.b.xzw = float3(0.0f, 0.0f, 0.0f);\n" + " o.b.y = dot(mul(rt, p), v_p);\n" + " }\n" + " else\n" + " {\n" + " o.b.zw = sign(dot(mul(rt, p1), v_p)) * v_p;\n" + " v_p = -float2(-p.y, p.x) / dot(float2(-p1.y, p1.x), p2);\n" + " o.b.x = dot(v_p, p1 - 0.5f * p2);\n" + " o.b.y = dot(v_p, p1);\n" + " }\n" + "\n" + " o.p = mul(float3(position, 1.0f), transform_geometry) + 0.5f * stroke_width * q_i;\n" + " position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f))\n" + " * float2(transform_rtx.w, transform_rty.w);\n" + " o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n" + "}\n"; /* ⎡p0.x p0.y 1⎤ * A = ⎢p1.x p1.y 1⎥ * ⎣p2.x p2.y 1⎦ @@ -3095,726 +3635,326 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, * A'T = B' * T = A'⁻¹B' = (B'⁻¹A')⁻¹ */ - static const DWORD vs_code_arc_outline[] = - { -#if 0 - float3x2 transform_geometry; - float stroke_width; - float4 transform_rtx; - float4 transform_rty; - - struct output - { - float2 p : WORLD_POSITION; - float4 b : BEZIER; - nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM; - float4 position : SV_POSITION; - }; - - void main(float2 position : POSITION, float2 p0 : P0, float2 p1 : P1, float2 p2 : P2, - float2 prev : PREV, float2 next : NEXT, out struct output o) - { - float2 q_prev, q_next, v_p, q_i, p; - float2x2 geom, rt, p_inv; - float l; - float a; - float2 bc; - - geom = float2x2(transform_geometry._11_21, transform_geometry._12_22); - rt = float2x2(transform_rtx.xy, transform_rty.xy); - o.stroke_transform = rt * stroke_width * 0.5f; - - p = mul(geom, position); - p0 = mul(geom, p0); - p1 = mul(geom, p1); - p2 = mul(geom, p2); - - p -= p0; - p1 -= p0; - p2 -= p0; - - q_prev = normalize(mul(geom, prev)); - q_next = normalize(mul(geom, next)); - - v_p = float2(-q_prev.y, q_prev.x); - l = -dot(v_p, q_next) / (1.0f + dot(q_prev, q_next)); - q_i = l * q_prev + v_p; - p += 0.5f * stroke_width * q_i; - - p_inv = float2x2(p1.y, -p1.x, p2.y - p1.y, p1.x - p2.x) / (p1.x * p2.y - p2.x * p1.y); - o.b.xy = mul(p_inv, p) + float2(1.0f, 0.0f); - o.b.zw = 0.0f; - - o.p = mul(float3(position, 1.0f), transform_geometry) + 0.5f * stroke_width * q_i; - position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f)) - * float2(transform_rtx.w, transform_rty.w); - o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f); - } -#endif - 0x43425844, 0xde1911bf, 0xfff8c893, 0xb0bfc24d, 0x78c9bbc4, 0x00000001, 0x00000924, 0x00000003, - 0x0000002c, 0x000000e4, 0x000001a0, 0x4e475349, 0x000000b0, 0x00000006, 0x00000008, 0x00000098, - 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x000000a1, 0x00000000, 0x00000000, - 0x00000003, 0x00000001, 0x00000303, 0x000000a1, 0x00000001, 0x00000000, 0x00000003, 0x00000002, - 0x00000303, 0x000000a1, 0x00000002, 0x00000000, 0x00000003, 0x00000003, 0x00000303, 0x000000a3, - 0x00000000, 0x00000000, 0x00000003, 0x00000004, 0x00000303, 0x000000a8, 0x00000000, 0x00000000, - 0x00000003, 0x00000005, 0x00000303, 0x49534f50, 0x4e4f4954, 0x50005000, 0x00564552, 0x5458454e, - 0xababab00, 0x4e47534f, 0x000000b4, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000, - 0x00000003, 0x00000000, 0x00000c03, 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001, - 0x0000000f, 0x00000096, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096, - 0x00000001, 0x00000000, 0x00000003, 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001, - 0x00000003, 0x00000004, 0x0000000f, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, - 0x54530052, 0x454b4f52, 0x4152545f, 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f, - 0x52444853, 0x0000077c, 0x00010040, 0x000001df, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, - 0x0300005f, 0x00101032, 0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x00101032, - 0x00000002, 0x0300005f, 0x00101032, 0x00000003, 0x0300005f, 0x00101032, 0x00000004, 0x0300005f, - 0x00101032, 0x00000005, 0x03000065, 0x00102032, 0x00000000, 0x03000065, 0x001020f2, 0x00000001, - 0x03000065, 0x00102032, 0x00000002, 0x03000065, 0x00102032, 0x00000003, 0x04000067, 0x001020f2, - 0x00000004, 0x00000001, 0x02000068, 0x00000004, 0x0800000f, 0x00100012, 0x00000000, 0x00208046, - 0x00000000, 0x00000000, 0x00101046, 0x00000005, 0x0800000f, 0x00100022, 0x00000000, 0x00208046, - 0x00000000, 0x00000001, 0x00101046, 0x00000005, 0x0700000f, 0x00100042, 0x00000000, 0x00100046, - 0x00000000, 0x00100046, 0x00000000, 0x05000044, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, - 0x07000038, 0x00100032, 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x0800000f, - 0x00100012, 0x00000001, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000004, 0x0800000f, - 0x00100022, 0x00000001, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000004, 0x0700000f, - 0x00100042, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000001, 0x05000044, 0x00100042, - 0x00000000, 0x0010002a, 0x00000000, 0x07000038, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000, - 0x00100046, 0x00000001, 0x06000036, 0x001000c2, 0x00000001, 0x80100556, 0x00000041, 0x00000001, - 0x0700000f, 0x00100042, 0x00000000, 0x00100a26, 0x00000001, 0x00100046, 0x00000000, 0x0700000f, - 0x00100012, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000000, 0x07000000, 0x00100012, - 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0800000e, 0x00100012, 0x00000000, - 0x8010002a, 0x00000041, 0x00000000, 0x0010000a, 0x00000000, 0x09000032, 0x00100032, 0x00000000, - 0x00100006, 0x00000000, 0x00100046, 0x00000001, 0x00100f36, 0x00000001, 0x05000036, 0x00100032, - 0x00000001, 0x00101046, 0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000, - 0x08000010, 0x00100012, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000000, - 0x08000010, 0x00100022, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000001, - 0x08000038, 0x00100042, 0x00000000, 0x0020803a, 0x00000000, 0x00000001, 0x00004001, 0x3f000000, - 0x09000032, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046, - 0x00000002, 0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000001, 0x0800000f, 0x00100012, - 0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000000, 0x0800000f, 0x00100022, - 0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000000, 0x0800000f, 0x00100022, - 0x00000003, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000001, 0x0800000f, 0x00100012, - 0x00000003, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000001, 0x08000000, 0x00100032, - 0x00000002, 0x00100046, 0x00000002, 0x80100516, 0x00000041, 0x00000003, 0x09000032, 0x00100032, - 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000002, 0x0800000f, - 0x00100022, 0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000003, 0x0800000f, - 0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000003, 0x08000000, - 0x001000c2, 0x00000000, 0x80100406, 0x00000041, 0x00000003, 0x00100406, 0x00000002, 0x0800000f, - 0x00100022, 0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000002, 0x0800000f, - 0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000002, 0x08000000, - 0x00100032, 0x00000002, 0x80100046, 0x00000041, 0x00000003, 0x00100046, 0x00000002, 0x07000038, - 0x00100082, 0x00000001, 0x0010003a, 0x00000000, 0x0010000a, 0x00000002, 0x0a000032, 0x00100082, - 0x00000001, 0x0010001a, 0x00000002, 0x0010002a, 0x00000000, 0x8010003a, 0x00000041, 0x00000001, - 0x08000000, 0x00100042, 0x00000003, 0x0010002a, 0x00000000, 0x8010000a, 0x00000041, 0x00000002, - 0x08000000, 0x00100082, 0x00000003, 0x8010003a, 0x00000041, 0x00000000, 0x0010001a, 0x00000002, - 0x0a000038, 0x00100032, 0x00000003, 0x00100046, 0x00000002, 0x00004002, 0x3f800000, 0xbf800000, - 0x00000000, 0x00000000, 0x0700000e, 0x001000f2, 0x00000002, 0x00100e46, 0x00000003, 0x00100ff6, - 0x00000001, 0x0700000f, 0x00100012, 0x00000002, 0x00100046, 0x00000002, 0x00100046, 0x00000000, - 0x0700000f, 0x00100022, 0x00000002, 0x00100ae6, 0x00000002, 0x00100046, 0x00000000, 0x0a000000, - 0x00102032, 0x00000001, 0x00100046, 0x00000002, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, - 0x00000000, 0x08000036, 0x001020c2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x06000036, 0x00100032, 0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x06000036, - 0x001000c2, 0x00000000, 0x00208406, 0x00000000, 0x00000003, 0x08000038, 0x001000f2, 0x00000000, - 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000001, 0x0a000038, 0x001000f2, 0x00000000, - 0x00100e46, 0x00000000, 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x05000036, - 0x00102032, 0x00000002, 0x00100086, 0x00000000, 0x05000036, 0x00102032, 0x00000003, 0x001005d6, - 0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000, 0x08000010, 0x00100012, - 0x00000000, 0x00208246, 0x00000000, 0x00000002, 0x00100246, 0x00000001, 0x08000010, 0x00100022, - 0x00000000, 0x00208246, 0x00000000, 0x00000003, 0x00100246, 0x00000001, 0x08000038, 0x00100022, - 0x00000001, 0x0010001a, 0x00000000, 0x0020803a, 0x00000000, 0x00000003, 0x08000038, 0x00100012, - 0x00000001, 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000002, 0x0a000000, 0x00102032, - 0x00000004, 0x00100046, 0x00000001, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000, - 0x08000036, 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, - 0x0100003e, - }; - static const DWORD vs_code_triangle[] = - { -#if 0 - float3x2 transform_geometry; - float4 transform_rtx; - float4 transform_rty; - - struct output - { - float2 p : WORLD_POSITION; - float4 b : BEZIER; - nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM; - float4 position : SV_POSITION; - }; - - void main(float2 position : POSITION, out struct output o) - { - o.p = mul(float3(position, 1.0f), transform_geometry); - o.b = float4(1.0, 0.0, 1.0, 1.0); - o.stroke_transform = float2x2(1.0, 0.0, 0.0, 1.0); - position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f)) - * float2(transform_rtx.w, transform_rty.w); - o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f); - } -#endif - 0x43425844, 0xda43bf17, 0x06e6d155, 0xdbce2ae5, 0x8aed6fd8, 0x00000001, 0x0000034c, 0x00000003, - 0x0000002c, 0x00000060, 0x0000011c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, - 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x49534f50, 0x4e4f4954, 0xababab00, - 0x4e47534f, 0x000000b4, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000, 0x00000003, - 0x00000000, 0x00000c03, 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, - 0x00000096, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096, 0x00000001, - 0x00000000, 0x00000003, 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001, 0x00000003, - 0x00000004, 0x0000000f, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052, - 0x454b4f52, 0x4152545f, 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f, 0x52444853, - 0x00000228, 0x00010040, 0x0000008a, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, 0x0300005f, - 0x00101032, 0x00000000, 0x03000065, 0x00102032, 0x00000000, 0x03000065, 0x001020f2, 0x00000001, - 0x03000065, 0x00102032, 0x00000002, 0x03000065, 0x00102032, 0x00000003, 0x04000067, 0x001020f2, - 0x00000004, 0x00000001, 0x02000068, 0x00000002, 0x05000036, 0x00100032, 0x00000000, 0x00101046, - 0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x00004001, 0x3f800000, 0x08000010, 0x00100012, - 0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000010, 0x00100022, - 0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000001, 0x05000036, 0x00102032, - 0x00000000, 0x00100046, 0x00000001, 0x08000036, 0x001020f2, 0x00000001, 0x00004002, 0x3f800000, - 0x00000000, 0x3f800000, 0x3f800000, 0x08000036, 0x00102032, 0x00000002, 0x00004002, 0x3f800000, - 0x00000000, 0x00000000, 0x00000000, 0x08000036, 0x00102032, 0x00000003, 0x00004002, 0x00000000, - 0x3f800000, 0x00000000, 0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000, - 0x08000010, 0x00100012, 0x00000000, 0x00208246, 0x00000000, 0x00000002, 0x00100246, 0x00000001, - 0x08000010, 0x00100022, 0x00000000, 0x00208246, 0x00000000, 0x00000003, 0x00100246, 0x00000001, - 0x08000038, 0x00100022, 0x00000001, 0x0010001a, 0x00000000, 0x0020803a, 0x00000000, 0x00000003, - 0x08000038, 0x00100012, 0x00000001, 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000002, - 0x0a000000, 0x00102032, 0x00000004, 0x00100046, 0x00000001, 0x00004002, 0xbf800000, 0x3f800000, - 0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000, - 0x00000000, 0x3f800000, 0x0100003e, - }; - static const DWORD vs_code_curve[] = - { -#if 0 - float3x2 transform_geometry; - float4 transform_rtx; - float4 transform_rty; - - struct output - { - float2 p : WORLD_POSITION; - float4 b : BEZIER; - nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM; - float4 position : SV_POSITION; - }; - - void main(float2 position : POSITION, float3 texcoord : TEXCOORD0, out struct output o) - { - o.p = mul(float3(position, 1.0f), transform_geometry); - o.b = float4(texcoord, 1.0); - o.stroke_transform = float2x2(1.0, 0.0, 0.0, 1.0); - position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f)) - * float2(transform_rtx.w, transform_rty.w); - o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f); - } -#endif - 0x43425844, 0xedb7472a, 0x2c2ea147, 0x36710079, 0xffc2e907, 0x00000001, 0x00000380, 0x00000003, - 0x0000002c, 0x00000080, 0x0000013c, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, - 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x00000041, 0x00000000, 0x00000000, - 0x00000003, 0x00000001, 0x00000707, 0x49534f50, 0x4e4f4954, 0x58455400, 0x524f4f43, 0xabab0044, - 0x4e47534f, 0x000000b4, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000, 0x00000003, - 0x00000000, 0x00000c03, 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, - 0x00000096, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096, 0x00000001, - 0x00000000, 0x00000003, 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001, 0x00000003, - 0x00000004, 0x0000000f, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052, - 0x454b4f52, 0x4152545f, 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f, 0x52444853, - 0x0000023c, 0x00010040, 0x0000008f, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, 0x0300005f, - 0x00101032, 0x00000000, 0x0300005f, 0x00101072, 0x00000001, 0x03000065, 0x00102032, 0x00000000, - 0x03000065, 0x001020f2, 0x00000001, 0x03000065, 0x00102032, 0x00000002, 0x03000065, 0x00102032, - 0x00000003, 0x04000067, 0x001020f2, 0x00000004, 0x00000001, 0x02000068, 0x00000002, 0x05000036, - 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x00004001, - 0x3f800000, 0x08000010, 0x00100012, 0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000, - 0x00000000, 0x08000010, 0x00100022, 0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000, - 0x00000001, 0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000001, 0x05000036, 0x00102072, - 0x00000001, 0x00101246, 0x00000001, 0x05000036, 0x00102082, 0x00000001, 0x00004001, 0x3f800000, - 0x08000036, 0x00102032, 0x00000002, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, - 0x08000036, 0x00102032, 0x00000003, 0x00004002, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, - 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000, 0x08000010, 0x00100012, 0x00000000, - 0x00208246, 0x00000000, 0x00000002, 0x00100246, 0x00000001, 0x08000010, 0x00100022, 0x00000000, - 0x00208246, 0x00000000, 0x00000003, 0x00100246, 0x00000001, 0x08000038, 0x00100022, 0x00000001, - 0x0010001a, 0x00000000, 0x0020803a, 0x00000000, 0x00000003, 0x08000038, 0x00100012, 0x00000001, - 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000002, 0x0a000000, 0x00102032, 0x00000004, - 0x00100046, 0x00000001, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000, 0x08000036, - 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e, - }; - static const DWORD ps_code[] = - { -#if 0 -#define BRUSH_TYPE_SOLID 0 -#define BRUSH_TYPE_LINEAR 1 -#define BRUSH_TYPE_RADIAL 2 -#define BRUSH_TYPE_BITMAP 3 -#define BRUSH_TYPE_COUNT 4 - - bool outline; - bool is_arc; - struct brush - { - uint type; - float opacity; - float4 data[3]; - } colour_brush, opacity_brush; - - SamplerState s0, s1; - Texture2D t0, t1; - Buffer b0, b1; - - struct input - { - float2 p : WORLD_POSITION; - float4 b : BEZIER; - nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM; - }; - - float4 sample_gradient(Buffer gradient, uint stop_count, float position) - { - float4 c_low, c_high; - float p_low, p_high; - uint i; - - p_low = gradient.Load(0).x; - c_low = gradient.Load(1); - c_high = c_low; - - if (position < p_low) - return c_low; - - for (i = 1; i < stop_count; ++i) - { - p_high = gradient.Load(i * 2).x; - c_high = gradient.Load(i * 2 + 1); - - if (position >= p_low && position <= p_high) - return lerp(c_low, c_high, (position - p_low) / (p_high - p_low)); - - p_low = p_high; - c_low = c_high; - } - - return c_high; - } - - float4 brush_linear(struct brush brush, Buffer gradient, float2 position) - { - float2 start, end, v_p, v_q; - uint stop_count; - float p; - - start = brush.data[0].xy; - end = brush.data[0].zw; - stop_count = asuint(brush.data[1].x); - - v_p = position - start; - v_q = end - start; - p = dot(v_q, v_p) / dot(v_q, v_q); - - return sample_gradient(gradient, stop_count, p); - } - - float4 brush_radial(struct brush brush, Buffer gradient, float2 position) - { - float2 centre, offset, ra, rb, v_p, v_q, r; - float b, c, l, t; - uint stop_count; - - centre = brush.data[0].xy; - offset = brush.data[0].zw; - ra = brush.data[1].xy; - rb = brush.data[1].zw; - stop_count = asuint(brush.data[2].x); - - /* Project onto ra, rb. */ - r = float2(dot(ra, ra), dot(rb, rb)); - v_p = position - (centre + offset); - v_p = float2(dot(v_p, ra), dot(v_p, rb)) / r; - v_q = float2(dot(offset, ra), dot(offset, rb)) / r; - - /* ‖t·p̂ + q⃑‖ = 1 - * (t·p̂ + q⃑) · (t·p̂ + q⃑) = 1 - * t² + 2·(p̂·q⃑)·t + (q⃑·q⃑) = 1 - * - * b = p̂·q⃑ - * c = q⃑·q⃑ - 1 - * t = -b + √(b² - c) */ - l = length(v_p); - b = dot(v_p, v_q) / l; - c = dot(v_q, v_q) - 1.0; - t = -b + sqrt(b * b - c); - - return sample_gradient(gradient, stop_count, l / t); - } - - float4 brush_bitmap(struct brush brush, Texture2D t, SamplerState s, float2 position) - { - float3 transform[2]; - bool ignore_alpha; - float2 texcoord; - float4 colour; - - transform[0] = brush.data[0].xyz; - transform[1] = brush.data[1].xyz; - ignore_alpha = asuint(brush.data[1].w); - - texcoord.x = dot(position.xy, transform[0].xy) + transform[0].z; - texcoord.y = dot(position.xy, transform[1].xy) + transform[1].z; - colour = t.Sample(s, texcoord); - if (ignore_alpha) - colour.a = 1.0; - return colour; - } - - float4 sample_brush(struct brush brush, Texture2D t, SamplerState s, Buffer b, float2 position) - { - if (brush.type == BRUSH_TYPE_SOLID) - return brush.data[0] * brush.opacity; - if (brush.type == BRUSH_TYPE_LINEAR) - return brush_linear(brush, b, position) * brush.opacity; - if (brush.type == BRUSH_TYPE_RADIAL) - return brush_radial(brush, b, position) * brush.opacity; - if (brush.type == BRUSH_TYPE_BITMAP) - return brush_bitmap(brush, t, s, position) * brush.opacity; - return float4(0.0, 0.0, 0.0, brush.opacity); - } - - float4 main(struct input i) : SV_Target - { - float4 colour; - - colour = sample_brush(colour_brush, t0, s0, b0, i.p); - if (opacity_brush.type < BRUSH_TYPE_COUNT) - colour *= sample_brush(opacity_brush, t1, s1, b1, i.p).a; - - if (outline) - { - float2 du, dv, df; - float4 uv; - - /* Evaluate the implicit form of the curve (u² - v = 0 - * for Béziers, u² + v² - 1 = 0 for arcs) in texture - * space, using the screen-space partial derivatives - * to convert the calculated distance to object space. - * - * d(x, y) = |f(x, y)| / ‖∇f(x, y)‖ - * = |f(x, y)| / √((∂f/∂x)² + (∂f/∂y)²) - * - * For Béziers: - * f(x, y) = u(x, y)² - v(x, y) - * ∂f/∂x = 2u · ∂u/∂x - ∂v/∂x - * ∂f/∂y = 2u · ∂u/∂y - ∂v/∂y - * - * For arcs: - * f(x, y) = u(x, y)² + v(x, y)² - 1 - * ∂f/∂x = 2u · ∂u/∂x + 2v · ∂v/∂x - * ∂f/∂y = 2u · ∂u/∂y + 2v · ∂v/∂y */ - uv = i.b; - du = float2(ddx(uv.x), ddy(uv.x)); - dv = float2(ddx(uv.y), ddy(uv.y)); - - if (!is_arc) - { - df = 2.0f * uv.x * du - dv; - - clip(dot(df, uv.zw)); - clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x - uv.y)); - } - else - { - df = 2.0f * uv.x * du + 2.0f * uv.y * dv; - - clip(dot(df, uv.zw)); - clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x + uv.y * uv.y - 1.0f)); - } - } - else - { - /* Evaluate the implicit form of the curve in texture space. - * "i.b.z" determines which side of the curve is shaded. */ - if (!is_arc) - { - clip((i.b.x * i.b.x - i.b.y) * i.b.z); - } - else - { - clip((i.b.x * i.b.x + i.b.y * i.b.y - 1.0) * i.b.z); - } - } - - return colour; - } -#endif - 0x43425844, 0xa8fee730, 0x92fa2196, 0xaf9f3eff, 0x888d4048, 0x00000001, 0x00002000, 0x00000003, - 0x0000002c, 0x000000c4, 0x000000f8, 0x4e475349, 0x00000090, 0x00000004, 0x00000008, 0x00000068, - 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x00000077, 0x00000000, 0x00000000, - 0x00000003, 0x00000001, 0x00000f0f, 0x0000007e, 0x00000000, 0x00000000, 0x00000003, 0x00000002, - 0x00000303, 0x0000007e, 0x00000001, 0x00000000, 0x00000003, 0x00000003, 0x00000303, 0x4c524f57, - 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052, 0x454b4f52, 0x4152545f, 0x4f46534e, - 0xab004d52, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, - 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00001f00, - 0x00000040, 0x000007c0, 0x04000059, 0x00208e46, 0x00000000, 0x00000009, 0x0300005a, 0x00106000, - 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555, - 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04000858, 0x00107000, 0x00000002, 0x00005555, - 0x04000858, 0x00107000, 0x00000003, 0x00005555, 0x03001062, 0x00101032, 0x00000000, 0x03001062, - 0x001010f2, 0x00000001, 0x03000862, 0x00101032, 0x00000002, 0x03000862, 0x00101032, 0x00000003, - 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x0000000a, 0x09000038, 0x001000f2, 0x00000000, - 0x00208556, 0x00000000, 0x00000001, 0x00208e46, 0x00000000, 0x00000002, 0x0404001f, 0x0020800a, - 0x00000000, 0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001, - 0x00004001, 0x00000001, 0x0304001f, 0x0010000a, 0x00000001, 0x09000000, 0x00100062, 0x00000001, - 0x00101106, 0x00000000, 0x80208106, 0x00000041, 0x00000000, 0x00000002, 0x0a000000, 0x00100032, - 0x00000002, 0x80208046, 0x00000041, 0x00000000, 0x00000002, 0x00208ae6, 0x00000000, 0x00000002, - 0x0700000f, 0x00100022, 0x00000001, 0x00100046, 0x00000002, 0x00100596, 0x00000001, 0x0700000f, - 0x00100042, 0x00000001, 0x00100046, 0x00000002, 0x00100046, 0x00000002, 0x0700000e, 0x00100022, - 0x00000001, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002, - 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000002, 0x0a00002d, - 0x001000f2, 0x00000003, 0x00004002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00107e46, - 0x00000002, 0x0700001d, 0x00100042, 0x00000001, 0x0010001a, 0x00000001, 0x0010000a, 0x00000002, - 0x0304001f, 0x0010002a, 0x00000001, 0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000003, - 0x05000036, 0x001000f2, 0x00000005, 0x00100e46, 0x00000003, 0x05000036, 0x001000f2, 0x00000006, - 0x00100e46, 0x00000003, 0x05000036, 0x00100042, 0x00000001, 0x0010000a, 0x00000002, 0x05000036, - 0x00100082, 0x00000001, 0x00004001, 0x00000001, 0x05000036, 0x00100022, 0x00000002, 0x00004001, - 0x00000000, 0x01000030, 0x08000050, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x0020800a, - 0x00000000, 0x00000003, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0x00000000, 0x03040003, - 0x0010002a, 0x00000002, 0x07000029, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x00004001, - 0x00000001, 0x0700002d, 0x001000f2, 0x00000007, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002, - 0x0700001e, 0x00100042, 0x00000002, 0x0010002a, 0x00000002, 0x00004001, 0x00000001, 0x0700002d, - 0x001000f2, 0x00000008, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002, 0x0700001d, 0x00100042, - 0x00000002, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0700001d, 0x00100082, 0x00000002, - 0x0010000a, 0x00000007, 0x0010001a, 0x00000001, 0x07000001, 0x00100042, 0x00000002, 0x0010003a, - 0x00000002, 0x0010002a, 0x00000002, 0x0304001f, 0x0010002a, 0x00000002, 0x08000000, 0x00100082, - 0x00000002, 0x8010002a, 0x00000041, 0x00000001, 0x0010001a, 0x00000001, 0x08000000, 0x00100022, - 0x00000007, 0x8010002a, 0x00000041, 0x00000001, 0x0010000a, 0x00000007, 0x0700000e, 0x00100082, - 0x00000002, 0x0010003a, 0x00000002, 0x0010001a, 0x00000007, 0x08000000, 0x001000f2, 0x00000009, - 0x80100e46, 0x00000041, 0x00000005, 0x00100e46, 0x00000008, 0x09000032, 0x001000f2, 0x00000009, - 0x00100ff6, 0x00000002, 0x00100e46, 0x00000009, 0x00100e46, 0x00000005, 0x05000036, 0x001000f2, - 0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0xffffffff, - 0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000009, 0x01000002, 0x01000015, 0x05000036, - 0x001000f2, 0x00000005, 0x00100e46, 0x00000008, 0x05000036, 0x00100042, 0x00000001, 0x0010000a, - 0x00000007, 0x0700001e, 0x00100082, 0x00000001, 0x0010003a, 0x00000001, 0x00004001, 0x00000001, - 0x05000036, 0x001000f2, 0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002, - 0x0010002a, 0x00000002, 0x01000016, 0x09000037, 0x001000f2, 0x00000003, 0x00100556, 0x00000002, - 0x00100e46, 0x00000004, 0x00100e46, 0x00000006, 0x01000015, 0x08000038, 0x001000f2, 0x00000000, - 0x00100e46, 0x00000003, 0x00208556, 0x00000000, 0x00000001, 0x01000015, 0x0300001f, 0x0010000a, - 0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001, 0x00004001, - 0x00000002, 0x0304001f, 0x0010000a, 0x00000001, 0x0900000f, 0x00100012, 0x00000002, 0x00208046, - 0x00000000, 0x00000003, 0x00208046, 0x00000000, 0x00000003, 0x0900000f, 0x00100022, 0x00000002, - 0x00208ae6, 0x00000000, 0x00000003, 0x00208ae6, 0x00000000, 0x00000003, 0x09000000, 0x00100062, - 0x00000001, 0x00208ba6, 0x00000000, 0x00000002, 0x00208106, 0x00000000, 0x00000002, 0x08000000, - 0x00100062, 0x00000001, 0x80100656, 0x00000041, 0x00000001, 0x00101106, 0x00000000, 0x0800000f, - 0x00100012, 0x00000003, 0x00100596, 0x00000001, 0x00208046, 0x00000000, 0x00000003, 0x0800000f, - 0x00100022, 0x00000003, 0x00100596, 0x00000001, 0x00208ae6, 0x00000000, 0x00000003, 0x0700000e, - 0x00100062, 0x00000001, 0x00100106, 0x00000003, 0x00100106, 0x00000002, 0x0900000f, 0x00100012, - 0x00000003, 0x00208ae6, 0x00000000, 0x00000002, 0x00208046, 0x00000000, 0x00000003, 0x0900000f, - 0x00100022, 0x00000003, 0x00208ae6, 0x00000000, 0x00000002, 0x00208ae6, 0x00000000, 0x00000003, - 0x0700000e, 0x00100032, 0x00000002, 0x00100046, 0x00000003, 0x00100046, 0x00000002, 0x0700000f, - 0x00100082, 0x00000001, 0x00100596, 0x00000001, 0x00100596, 0x00000001, 0x0500004b, 0x00100082, - 0x00000001, 0x0010003a, 0x00000001, 0x0700000f, 0x00100022, 0x00000001, 0x00100596, 0x00000001, - 0x00100046, 0x00000002, 0x0700000e, 0x00100022, 0x00000001, 0x0010001a, 0x00000001, 0x0010003a, - 0x00000001, 0x0700000f, 0x00100042, 0x00000001, 0x00100046, 0x00000002, 0x00100046, 0x00000002, - 0x07000000, 0x00100042, 0x00000001, 0x0010002a, 0x00000001, 0x00004001, 0xbf800000, 0x0a000032, - 0x00100042, 0x00000001, 0x0010001a, 0x00000001, 0x0010001a, 0x00000001, 0x8010002a, 0x00000041, - 0x00000001, 0x0500004b, 0x00100042, 0x00000001, 0x0010002a, 0x00000001, 0x08000000, 0x00100022, - 0x00000001, 0x0010002a, 0x00000001, 0x8010001a, 0x00000041, 0x00000001, 0x0700000e, 0x00100022, - 0x00000001, 0x0010003a, 0x00000001, 0x0010001a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002, - 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000002, 0x0a00002d, - 0x001000f2, 0x00000003, 0x00004002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00107e46, - 0x00000002, 0x0700001d, 0x00100042, 0x00000001, 0x0010001a, 0x00000001, 0x0010000a, 0x00000002, - 0x0304001f, 0x0010002a, 0x00000001, 0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000003, - 0x05000036, 0x001000f2, 0x00000005, 0x00100e46, 0x00000003, 0x05000036, 0x001000f2, 0x00000006, - 0x00100e46, 0x00000003, 0x05000036, 0x00100042, 0x00000001, 0x0010000a, 0x00000002, 0x05000036, - 0x00100082, 0x00000001, 0x00004001, 0x00000001, 0x05000036, 0x00100022, 0x00000002, 0x00004001, - 0x00000000, 0x01000030, 0x08000050, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x0020800a, - 0x00000000, 0x00000004, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0x00000000, 0x03040003, - 0x0010002a, 0x00000002, 0x07000029, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x00004001, - 0x00000001, 0x0700002d, 0x001000f2, 0x00000007, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002, - 0x0700001e, 0x00100042, 0x00000002, 0x0010002a, 0x00000002, 0x00004001, 0x00000001, 0x0700002d, - 0x001000f2, 0x00000008, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002, 0x0700001d, 0x00100042, - 0x00000002, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0700001d, 0x00100082, 0x00000002, - 0x0010000a, 0x00000007, 0x0010001a, 0x00000001, 0x07000001, 0x00100042, 0x00000002, 0x0010003a, - 0x00000002, 0x0010002a, 0x00000002, 0x0304001f, 0x0010002a, 0x00000002, 0x08000000, 0x00100082, - 0x00000002, 0x8010002a, 0x00000041, 0x00000001, 0x0010001a, 0x00000001, 0x08000000, 0x00100022, - 0x00000007, 0x8010002a, 0x00000041, 0x00000001, 0x0010000a, 0x00000007, 0x0700000e, 0x00100082, - 0x00000002, 0x0010003a, 0x00000002, 0x0010001a, 0x00000007, 0x08000000, 0x001000f2, 0x00000009, - 0x80100e46, 0x00000041, 0x00000005, 0x00100e46, 0x00000008, 0x09000032, 0x001000f2, 0x00000009, - 0x00100ff6, 0x00000002, 0x00100e46, 0x00000009, 0x00100e46, 0x00000005, 0x05000036, 0x001000f2, - 0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0xffffffff, - 0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000009, 0x01000002, 0x01000015, 0x05000036, - 0x001000f2, 0x00000005, 0x00100e46, 0x00000008, 0x05000036, 0x00100042, 0x00000001, 0x0010000a, - 0x00000007, 0x0700001e, 0x00100082, 0x00000001, 0x0010003a, 0x00000001, 0x00004001, 0x00000001, - 0x05000036, 0x001000f2, 0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002, - 0x0010002a, 0x00000002, 0x01000016, 0x09000037, 0x001000f2, 0x00000003, 0x00100556, 0x00000002, - 0x00100e46, 0x00000004, 0x00100e46, 0x00000006, 0x01000015, 0x08000038, 0x001000f2, 0x00000000, - 0x00100e46, 0x00000003, 0x00208556, 0x00000000, 0x00000001, 0x01000015, 0x0300001f, 0x0010000a, - 0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001, 0x00004001, - 0x00000003, 0x0304001f, 0x0010000a, 0x00000001, 0x0800000f, 0x00100022, 0x00000001, 0x00101046, - 0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x08000000, 0x00100012, 0x00000002, 0x0010001a, - 0x00000001, 0x0020802a, 0x00000000, 0x00000002, 0x0800000f, 0x00100022, 0x00000001, 0x00101046, - 0x00000000, 0x00208046, 0x00000000, 0x00000003, 0x08000000, 0x00100022, 0x00000002, 0x0010001a, - 0x00000001, 0x0020802a, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002, 0x00100046, - 0x00000002, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000037, 0x00100082, 0x00000002, - 0x0020803a, 0x00000000, 0x00000003, 0x00004001, 0x3f800000, 0x0010003a, 0x00000002, 0x08000038, - 0x001000f2, 0x00000000, 0x00100e46, 0x00000002, 0x00208556, 0x00000000, 0x00000001, 0x01000015, - 0x05000036, 0x00100012, 0x00000002, 0x00004001, 0x00000000, 0x06000036, 0x00100082, 0x00000002, - 0x0020801a, 0x00000000, 0x00000001, 0x09000037, 0x001000f2, 0x00000000, 0x00100006, 0x00000001, - 0x00100e46, 0x00000000, 0x00100c06, 0x00000002, 0x01000015, 0x01000015, 0x01000015, 0x0800004f, - 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000005, 0x00004001, 0x00000004, 0x0304001f, - 0x0010000a, 0x00000001, 0x09000038, 0x00100012, 0x00000001, 0x0020801a, 0x00000000, 0x00000005, - 0x0020803a, 0x00000000, 0x00000006, 0x0404001f, 0x0020800a, 0x00000000, 0x00000005, 0x08000020, - 0x00100022, 0x00000001, 0x0020800a, 0x00000000, 0x00000005, 0x00004001, 0x00000001, 0x0304001f, - 0x0010001a, 0x00000001, 0x09000000, 0x001000c2, 0x00000001, 0x00101406, 0x00000000, 0x80208406, - 0x00000041, 0x00000000, 0x00000006, 0x0a000000, 0x00100032, 0x00000002, 0x80208046, 0x00000041, - 0x00000000, 0x00000006, 0x00208ae6, 0x00000000, 0x00000006, 0x0700000f, 0x00100042, 0x00000001, - 0x00100046, 0x00000002, 0x00100ae6, 0x00000001, 0x0700000f, 0x00100082, 0x00000001, 0x00100046, - 0x00000002, 0x00100046, 0x00000002, 0x0700000e, 0x00100042, 0x00000001, 0x0010002a, 0x00000001, - 0x0010003a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002, 0x00004002, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00107e46, 0x00000003, 0x0a00002d, 0x001000f2, 0x00000003, 0x00004002, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00107e46, 0x00000003, 0x0700001d, 0x00100082, - 0x00000001, 0x0010002a, 0x00000001, 0x0010000a, 0x00000002, 0x0304001f, 0x0010003a, 0x00000001, - 0x05000036, 0x00100082, 0x00000001, 0x0010003a, 0x00000003, 0x05000036, 0x00100062, 0x00000002, - 0x00100ff6, 0x00000003, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000002, 0x08000036, - 0x00100032, 0x00000003, 0x00004002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x01000030, - 0x08000050, 0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x0020800a, 0x00000000, 0x00000007, - 0x05000036, 0x00100022, 0x00000003, 0x00004001, 0x00000000, 0x03040003, 0x0010002a, 0x00000003, - 0x07000029, 0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, - 0x001000f2, 0x00000004, 0x00100aa6, 0x00000003, 0x00107e46, 0x00000003, 0x0700001e, 0x00100042, - 0x00000003, 0x0010002a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2, 0x00000005, - 0x00100aa6, 0x00000003, 0x00107e46, 0x00000003, 0x0700001d, 0x00100042, 0x00000003, 0x0010002a, - 0x00000001, 0x0010003a, 0x00000002, 0x0700001d, 0x00100022, 0x00000004, 0x0010000a, 0x00000004, - 0x0010002a, 0x00000001, 0x07000001, 0x00100042, 0x00000003, 0x0010002a, 0x00000003, 0x0010001a, - 0x00000004, 0x0304001f, 0x0010002a, 0x00000003, 0x08000000, 0x00100022, 0x00000004, 0x0010002a, - 0x00000001, 0x8010003a, 0x00000041, 0x00000002, 0x08000000, 0x00100042, 0x00000004, 0x8010003a, - 0x00000041, 0x00000002, 0x0010000a, 0x00000004, 0x0700000e, 0x00100022, 0x00000004, 0x0010001a, - 0x00000004, 0x0010002a, 0x00000004, 0x08000000, 0x00100042, 0x00000004, 0x8010001a, 0x00000041, - 0x00000002, 0x0010003a, 0x00000005, 0x09000032, 0x00100022, 0x00000004, 0x0010001a, 0x00000004, - 0x0010002a, 0x00000004, 0x0010001a, 0x00000002, 0x05000036, 0x00100042, 0x00000002, 0x0010003a, - 0x00000005, 0x05000036, 0x00100022, 0x00000003, 0x00004001, 0xffffffff, 0x05000036, 0x00100082, - 0x00000001, 0x0010001a, 0x00000004, 0x01000002, 0x01000015, 0x05000036, 0x00100022, 0x00000002, - 0x0010003a, 0x00000005, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000004, 0x0700001e, - 0x00100012, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x05000036, 0x00100042, - 0x00000002, 0x0010003a, 0x00000005, 0x05000036, 0x00100032, 0x00000003, 0x00100086, 0x00000003, - 0x01000016, 0x09000037, 0x00100042, 0x00000001, 0x0010001a, 0x00000003, 0x0010003a, 0x00000001, - 0x0010002a, 0x00000002, 0x01000012, 0x05000036, 0x00100042, 0x00000001, 0x0010003a, 0x00000003, - 0x01000015, 0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a, 0x00000000, - 0x00000005, 0x01000015, 0x0300001f, 0x0010001a, 0x00000001, 0x08000020, 0x00100022, 0x00000001, - 0x0020800a, 0x00000000, 0x00000005, 0x00004001, 0x00000002, 0x0304001f, 0x0010001a, 0x00000001, - 0x0900000f, 0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000007, 0x00208046, 0x00000000, - 0x00000007, 0x0900000f, 0x00100022, 0x00000002, 0x00208ae6, 0x00000000, 0x00000007, 0x00208ae6, - 0x00000000, 0x00000007, 0x09000000, 0x001000c2, 0x00000001, 0x00208ea6, 0x00000000, 0x00000006, - 0x00208406, 0x00000000, 0x00000006, 0x08000000, 0x001000c2, 0x00000001, 0x80100ea6, 0x00000041, - 0x00000001, 0x00101406, 0x00000000, 0x0800000f, 0x00100012, 0x00000003, 0x00100ae6, 0x00000001, - 0x00208046, 0x00000000, 0x00000007, 0x0800000f, 0x00100022, 0x00000003, 0x00100ae6, 0x00000001, - 0x00208ae6, 0x00000000, 0x00000007, 0x0700000e, 0x001000c2, 0x00000001, 0x00100406, 0x00000003, - 0x00100406, 0x00000002, 0x0900000f, 0x00100012, 0x00000003, 0x00208ae6, 0x00000000, 0x00000006, - 0x00208046, 0x00000000, 0x00000007, 0x0900000f, 0x00100022, 0x00000003, 0x00208ae6, 0x00000000, - 0x00000006, 0x00208ae6, 0x00000000, 0x00000007, 0x0700000e, 0x00100032, 0x00000002, 0x00100046, - 0x00000003, 0x00100046, 0x00000002, 0x0700000f, 0x00100042, 0x00000002, 0x00100ae6, 0x00000001, - 0x00100ae6, 0x00000001, 0x0500004b, 0x00100042, 0x00000002, 0x0010002a, 0x00000002, 0x0700000f, - 0x00100042, 0x00000001, 0x00100ae6, 0x00000001, 0x00100046, 0x00000002, 0x0700000e, 0x00100042, - 0x00000001, 0x0010002a, 0x00000001, 0x0010002a, 0x00000002, 0x0700000f, 0x00100082, 0x00000001, - 0x00100046, 0x00000002, 0x00100046, 0x00000002, 0x07000000, 0x00100082, 0x00000001, 0x0010003a, - 0x00000001, 0x00004001, 0xbf800000, 0x0a000032, 0x00100082, 0x00000001, 0x0010002a, 0x00000001, - 0x0010002a, 0x00000001, 0x8010003a, 0x00000041, 0x00000001, 0x0500004b, 0x00100082, 0x00000001, - 0x0010003a, 0x00000001, 0x08000000, 0x00100042, 0x00000001, 0x0010003a, 0x00000001, 0x8010002a, - 0x00000041, 0x00000001, 0x0700000e, 0x00100042, 0x00000001, 0x0010002a, 0x00000002, 0x0010002a, - 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002, 0x00004002, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00107e46, 0x00000003, 0x0a00002d, 0x001000f2, 0x00000003, 0x00004002, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00107e46, 0x00000003, 0x0700001d, 0x00100082, 0x00000001, - 0x0010002a, 0x00000001, 0x0010000a, 0x00000002, 0x0304001f, 0x0010003a, 0x00000001, 0x05000036, - 0x00100082, 0x00000001, 0x0010003a, 0x00000003, 0x05000036, 0x00100062, 0x00000002, 0x00100ff6, - 0x00000003, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000002, 0x08000036, 0x00100032, - 0x00000003, 0x00004002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x01000030, 0x08000050, - 0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x0020800a, 0x00000000, 0x00000008, 0x05000036, - 0x00100022, 0x00000003, 0x00004001, 0x00000000, 0x03040003, 0x0010002a, 0x00000003, 0x07000029, - 0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2, - 0x00000004, 0x00100aa6, 0x00000003, 0x00107e46, 0x00000003, 0x0700001e, 0x00100042, 0x00000003, - 0x0010002a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2, 0x00000005, 0x00100aa6, - 0x00000003, 0x00107e46, 0x00000003, 0x0700001d, 0x00100042, 0x00000003, 0x0010002a, 0x00000001, - 0x0010003a, 0x00000002, 0x0700001d, 0x00100022, 0x00000004, 0x0010000a, 0x00000004, 0x0010002a, - 0x00000001, 0x07000001, 0x00100042, 0x00000003, 0x0010002a, 0x00000003, 0x0010001a, 0x00000004, - 0x0304001f, 0x0010002a, 0x00000003, 0x08000000, 0x00100022, 0x00000004, 0x0010002a, 0x00000001, - 0x8010003a, 0x00000041, 0x00000002, 0x08000000, 0x00100042, 0x00000004, 0x8010003a, 0x00000041, - 0x00000002, 0x0010000a, 0x00000004, 0x0700000e, 0x00100022, 0x00000004, 0x0010001a, 0x00000004, - 0x0010002a, 0x00000004, 0x08000000, 0x00100042, 0x00000004, 0x8010001a, 0x00000041, 0x00000002, - 0x0010003a, 0x00000005, 0x09000032, 0x00100022, 0x00000004, 0x0010001a, 0x00000004, 0x0010002a, - 0x00000004, 0x0010001a, 0x00000002, 0x05000036, 0x00100042, 0x00000002, 0x0010003a, 0x00000005, - 0x05000036, 0x00100022, 0x00000003, 0x00004001, 0xffffffff, 0x05000036, 0x00100082, 0x00000001, - 0x0010001a, 0x00000004, 0x01000002, 0x01000015, 0x05000036, 0x00100022, 0x00000002, 0x0010003a, - 0x00000005, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000004, 0x0700001e, 0x00100012, - 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x05000036, 0x00100042, 0x00000002, - 0x0010003a, 0x00000005, 0x05000036, 0x00100032, 0x00000003, 0x00100086, 0x00000003, 0x01000016, - 0x09000037, 0x00100042, 0x00000001, 0x0010001a, 0x00000003, 0x0010003a, 0x00000001, 0x0010002a, - 0x00000002, 0x01000012, 0x05000036, 0x00100042, 0x00000001, 0x0010003a, 0x00000003, 0x01000015, - 0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a, 0x00000000, 0x00000005, - 0x01000015, 0x0300001f, 0x0010001a, 0x00000001, 0x08000020, 0x00100022, 0x00000001, 0x0020800a, - 0x00000000, 0x00000005, 0x00004001, 0x00000003, 0x0304001f, 0x0010001a, 0x00000001, 0x0800000f, - 0x00100042, 0x00000001, 0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000006, 0x08000000, - 0x00100012, 0x00000002, 0x0010002a, 0x00000001, 0x0020802a, 0x00000000, 0x00000006, 0x0800000f, - 0x00100042, 0x00000001, 0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000007, 0x08000000, - 0x00100022, 0x00000002, 0x0010002a, 0x00000001, 0x0020802a, 0x00000000, 0x00000007, 0x09000045, - 0x001000f2, 0x00000002, 0x00100046, 0x00000002, 0x00107e46, 0x00000001, 0x00106000, 0x00000001, - 0x0a000037, 0x00100042, 0x00000001, 0x0020803a, 0x00000000, 0x00000007, 0x00004001, 0x3f800000, - 0x0010003a, 0x00000002, 0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a, - 0x00000000, 0x00000005, 0x01000015, 0x0a000037, 0x00100012, 0x00000001, 0x0010001a, 0x00000001, - 0x0010000a, 0x00000001, 0x0020801a, 0x00000000, 0x00000005, 0x01000015, 0x01000015, 0x01000015, - 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, 0x00000001, 0x01000012, - 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x01000015, 0x0404001f, 0x0020800a, - 0x00000000, 0x00000000, 0x0500000b, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x0500000c, - 0x001000c2, 0x00000000, 0x00101406, 0x00000001, 0x08000027, 0x00100012, 0x00000001, 0x0020801a, - 0x00000000, 0x00000000, 0x00004001, 0x00000000, 0x0500003b, 0x00100022, 0x00000001, 0x0010000a, - 0x00000001, 0x07000000, 0x001000c2, 0x00000001, 0x00101406, 0x00000001, 0x00101406, 0x00000001, - 0x07000038, 0x001000f2, 0x00000002, 0x00100d86, 0x00000000, 0x00100fa6, 0x00000001, 0x0a000032, - 0x00100032, 0x00000000, 0x00100aa6, 0x00000001, 0x00100086, 0x00000000, 0x801005d6, 0x00000041, - 0x00000000, 0x0700000f, 0x00100042, 0x00000000, 0x00100046, 0x00000000, 0x00101ae6, 0x00000001, - 0x07000031, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, - 0x00100042, 0x00000000, 0x0010001a, 0x00000001, 0x0010002a, 0x00000000, 0x0304000d, 0x0010002a, - 0x00000000, 0x07000038, 0x00100062, 0x00000000, 0x00100556, 0x00000000, 0x00101106, 0x00000003, - 0x09000032, 0x00100032, 0x00000000, 0x00101046, 0x00000002, 0x00100006, 0x00000000, 0x00100596, - 0x00000000, 0x0700000f, 0x00100012, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000000, - 0x0500004b, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x07000038, 0x00100062, 0x00000000, - 0x00101106, 0x00000001, 0x00101106, 0x00000001, 0x0a000032, 0x00100082, 0x00000000, 0x0010100a, - 0x00000001, 0x0010100a, 0x00000001, 0x8010101a, 0x00000041, 0x00000001, 0x08000000, 0x00100012, - 0x00000000, 0x8010003a, 0x000000c1, 0x00000000, 0x0010000a, 0x00000000, 0x07000031, 0x00100012, - 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000, - 0x0010001a, 0x00000001, 0x0010000a, 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x07000000, - 0x00100092, 0x00000000, 0x00100ea6, 0x00000002, 0x00100406, 0x00000002, 0x0700000f, 0x00100022, - 0x00000001, 0x001000c6, 0x00000000, 0x00101ae6, 0x00000001, 0x07000031, 0x00100022, 0x00000001, - 0x0010001a, 0x00000001, 0x00004001, 0x00000000, 0x07000001, 0x00100022, 0x00000001, 0x0010000a, - 0x00000001, 0x0010001a, 0x00000001, 0x0304000d, 0x0010001a, 0x00000001, 0x07000038, 0x00100062, - 0x00000001, 0x00100ff6, 0x00000000, 0x00101106, 0x00000003, 0x09000032, 0x00100092, 0x00000000, - 0x00101406, 0x00000002, 0x00100006, 0x00000000, 0x00100956, 0x00000001, 0x0700000f, 0x00100012, - 0x00000000, 0x001000c6, 0x00000000, 0x001000c6, 0x00000000, 0x0500004b, 0x00100012, 0x00000000, - 0x0010000a, 0x00000000, 0x07000000, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, - 0x00000000, 0x07000000, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0xbf800000, - 0x08000000, 0x00100012, 0x00000000, 0x8010001a, 0x000000c1, 0x00000000, 0x0010000a, 0x00000000, - 0x07000031, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, - 0x00100012, 0x00000000, 0x0010000a, 0x00000001, 0x0010000a, 0x00000000, 0x0304000d, 0x0010000a, - 0x00000000, 0x01000012, 0x08000027, 0x00100012, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, - 0x00004001, 0x00000000, 0x0500003b, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x07000038, - 0x001000c2, 0x00000000, 0x00101406, 0x00000001, 0x00101406, 0x00000001, 0x0a000032, 0x00100012, - 0x00000001, 0x0010100a, 0x00000001, 0x0010100a, 0x00000001, 0x8010101a, 0x00000041, 0x00000001, - 0x07000038, 0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x0010102a, 0x00000001, 0x07000031, - 0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x00004001, 0x00000000, 0x07000001, 0x00100022, - 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000001, 0x0304000d, 0x0010001a, 0x00000000, - 0x07000000, 0x00100022, 0x00000000, 0x0010003a, 0x00000000, 0x0010002a, 0x00000000, 0x07000000, - 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0xbf800000, 0x07000038, 0x00100022, - 0x00000000, 0x0010001a, 0x00000000, 0x0010102a, 0x00000001, 0x07000031, 0x00100022, 0x00000000, - 0x0010001a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000, 0x0010000a, - 0x00000000, 0x0010001a, 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x01000015, 0x0100003e, - }; + static const char vs_code_arc_outline[] = + "float3x2 transform_geometry;\n" + "float stroke_width;\n" + "float4 transform_rtx;\n" + "float4 transform_rty;\n" + "\n" + "struct output\n" + "{\n" + " float2 p : WORLD_POSITION;\n" + " float4 b : BEZIER;\n" + " nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;\n" + " float4 position : SV_POSITION;\n" + "};\n" + "\n" + "void main(float2 position : POSITION, float2 p0 : P0, float2 p1 : P1, float2 p2 : P2,\n" + " float2 prev : PREV, float2 next : NEXT, out struct output o)\n" + "{\n" + " float2 q_prev, q_next, v_p, q_i, p;\n" + " float2x2 geom, rt, p_inv;\n" + " float l;\n" + " float a;\n" + " float2 bc;\n" + "\n" + " geom = float2x2(transform_geometry._11_21, transform_geometry._12_22);\n" + " rt = float2x2(transform_rtx.xy, transform_rty.xy);\n" + " o.stroke_transform = rt * stroke_width * 0.5f;\n" + "\n" + " p = mul(geom, position);\n" + " p0 = mul(geom, p0);\n" + " p1 = mul(geom, p1);\n" + " p2 = mul(geom, p2);\n" + "\n" + " p -= p0;\n" + " p1 -= p0;\n" + " p2 -= p0;\n" + "\n" + " q_prev = normalize(mul(geom, prev));\n" + " q_next = normalize(mul(geom, next));\n" + "\n" + " v_p = float2(-q_prev.y, q_prev.x);\n" + " l = -dot(v_p, q_next) / (1.0f + dot(q_prev, q_next));\n" + " q_i = l * q_prev + v_p;\n" + " p += 0.5f * stroke_width * q_i;\n" + "\n" + " p_inv = float2x2(p1.y, -p1.x, p2.y - p1.y, p1.x - p2.x) / (p1.x * p2.y - p2.x * p1.y);\n" + " o.b.xy = mul(p_inv, p) + float2(1.0f, 0.0f);\n" + " o.b.zw = 0.0f;\n" + "\n" + " o.p = mul(float3(position, 1.0f), transform_geometry) + 0.5f * stroke_width * q_i;\n" + " position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f))\n" + " * float2(transform_rtx.w, transform_rty.w);\n" + " o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n" + "}\n"; + static const char vs_code_triangle[] = + "float3x2 transform_geometry;\n" + "float4 transform_rtx;\n" + "float4 transform_rty;\n" + "\n" + "struct output\n" + "{\n" + " float2 p : WORLD_POSITION;\n" + " float4 b : BEZIER;\n" + " nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;\n" + " float4 position : SV_POSITION;\n" + "};\n" + "\n" + "void main(float2 position : POSITION, out struct output o)\n" + "{\n" + " o.p = mul(float3(position, 1.0f), transform_geometry);\n" + " o.b = float4(1.0, 0.0, 1.0, 1.0);\n" + " o.stroke_transform = float2x2(1.0, 0.0, 0.0, 1.0);\n" + " position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f))\n" + " * float2(transform_rtx.w, transform_rty.w);\n" + " o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n" + "}\n"; + static const char vs_code_curve[] = + "float3x2 transform_geometry;\n" + "float4 transform_rtx;\n" + "float4 transform_rty;\n" + "\n" + "struct output\n" + "{\n" + " float2 p : WORLD_POSITION;\n" + " float4 b : BEZIER;\n" + " nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;\n" + " float4 position : SV_POSITION;\n" + "};\n" + "\n" + "void main(float2 position : POSITION, float3 texcoord : TEXCOORD0, out struct output o)\n" + "{\n" + " o.p = mul(float3(position, 1.0f), transform_geometry);\n" + " o.b = float4(texcoord, 1.0);\n" + " o.stroke_transform = float2x2(1.0, 0.0, 0.0, 1.0);\n" + " position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f))\n" + " * float2(transform_rtx.w, transform_rty.w);\n" + " o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n" + "}\n"; + static const char ps_code[] = + "#define BRUSH_TYPE_SOLID 0\n" + "#define BRUSH_TYPE_LINEAR 1\n" + "#define BRUSH_TYPE_RADIAL 2\n" + "#define BRUSH_TYPE_BITMAP 3\n" + "#define BRUSH_TYPE_COUNT 4\n" + "\n" + "bool outline;\n" + "bool is_arc;\n" + "struct brush\n" + "{\n" + " uint type;\n" + " float opacity;\n" + " float4 data[3];\n" + "} colour_brush, opacity_brush;\n" + "\n" + "SamplerState s0, s1;\n" + "Texture2D t0, t1;\n" + "Buffer b0, b1;\n" + "\n" + "struct input\n" + "{\n" + " float2 p : WORLD_POSITION;\n" + " float4 b : BEZIER;\n" + " nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;\n" + "};\n" + "\n" + "float4 sample_gradient(Buffer gradient, uint stop_count, float position)\n" + "{\n" + " float4 c_low, c_high;\n" + " float p_low, p_high;\n" + " uint i;\n" + "\n" + " p_low = gradient.Load(0).x;\n" + " c_low = gradient.Load(1);\n" + " c_high = c_low;\n" + "\n" + " if (position < p_low)\n" + " return c_low;\n" + "\n" + " for (i = 1; i < stop_count; ++i)\n" + " {\n" + " p_high = gradient.Load(i * 2).x;\n" + " c_high = gradient.Load(i * 2 + 1);\n" + "\n" + " if (position >= p_low && position <= p_high)\n" + " return lerp(c_low, c_high, (position - p_low) / (p_high - p_low));\n" + "\n" + " p_low = p_high;\n" + " c_low = c_high;\n" + " }\n" + "\n" + " return c_high;\n" + "}\n" + "\n" + "float4 brush_linear(struct brush brush, Buffer gradient, float2 position)\n" + "{\n" + " float2 start, end, v_p, v_q;\n" + " uint stop_count;\n" + " float p;\n" + "\n" + " start = brush.data[0].xy;\n" + " end = brush.data[0].zw;\n" + " stop_count = asuint(brush.data[1].x);\n" + "\n" + " v_p = position - start;\n" + " v_q = end - start;\n" + " p = dot(v_q, v_p) / dot(v_q, v_q);\n" + "\n" + " return sample_gradient(gradient, stop_count, p);\n" + "}\n" + "\n" + "float4 brush_radial(struct brush brush, Buffer gradient, float2 position)\n" + "{\n" + " float2 centre, offset, ra, rb, v_p, v_q, r;\n" + " float b, c, l, t;\n" + " uint stop_count;\n" + "\n" + " centre = brush.data[0].xy;\n" + " offset = brush.data[0].zw;\n" + " ra = brush.data[1].xy;\n" + " rb = brush.data[1].zw;\n" + " stop_count = asuint(brush.data[2].x);\n" + "\n" + " /* Project onto ra, rb. */\n" + " r = float2(dot(ra, ra), dot(rb, rb));\n" + " v_p = position - (centre + offset);\n" + " v_p = float2(dot(v_p, ra), dot(v_p, rb)) / r;\n" + " v_q = float2(dot(offset, ra), dot(offset, rb)) / r;\n" + "\n" + " /* ‖t·p̂ + q⃑‖ = 1\n" + " * (t·p̂ + q⃑) · (t·p̂ + q⃑) = 1\n" + " * t² + 2·(p̂·q⃑)·t + (q⃑·q⃑) = 1\n" + " *\n" + " * b = p̂·q⃑\n" + " * c = q⃑·q⃑ - 1\n" + " * t = -b + √(b² - c) */\n" + " l = length(v_p);\n" + " b = dot(v_p, v_q) / l;\n" + " c = dot(v_q, v_q) - 1.0;\n" + " t = -b + sqrt(b * b - c);\n" + "\n" + " return sample_gradient(gradient, stop_count, l / t);\n" + "}\n" + "\n" + "float4 brush_bitmap(struct brush brush, Texture2D t, SamplerState s, float2 position)\n" + "{\n" + " float3 transform[2];\n" + " bool ignore_alpha;\n" + " float2 texcoord;\n" + " float4 colour;\n" + "\n" + " transform[0] = brush.data[0].xyz;\n" + " transform[1] = brush.data[1].xyz;\n" + " ignore_alpha = asuint(brush.data[1].w);\n" + "\n" + " texcoord.x = dot(position.xy, transform[0].xy) + transform[0].z;\n" + " texcoord.y = dot(position.xy, transform[1].xy) + transform[1].z;\n" + " colour = t.Sample(s, texcoord);\n" + " if (ignore_alpha)\n" + " colour.a = 1.0;\n" + " return colour;\n" + "}\n" + "\n" + "float4 sample_brush(struct brush brush, Texture2D t, SamplerState s, Buffer b, float2 position)\n" + "{\n" + " if (brush.type == BRUSH_TYPE_SOLID)\n" + " return brush.data[0] * brush.opacity;\n" + " if (brush.type == BRUSH_TYPE_LINEAR)\n" + " return brush_linear(brush, b, position) * brush.opacity;\n" + " if (brush.type == BRUSH_TYPE_RADIAL)\n" + " return brush_radial(brush, b, position) * brush.opacity;\n" + " if (brush.type == BRUSH_TYPE_BITMAP)\n" + " return brush_bitmap(brush, t, s, position) * brush.opacity;\n" + " return float4(0.0, 0.0, 0.0, brush.opacity);\n" + "}\n" + "\n" + "float4 main(struct input i) : SV_Target\n" + "{\n" + " float4 colour;\n" + "\n" + " colour = sample_brush(colour_brush, t0, s0, b0, i.p);\n" + " if (opacity_brush.type < BRUSH_TYPE_COUNT)\n" + " colour *= sample_brush(opacity_brush, t1, s1, b1, i.p).a;\n" + "\n" + " if (outline)\n" + " {\n" + " float2 du, dv, df;\n" + " float4 uv;\n" + "\n" + " /* Evaluate the implicit form of the curve (u² - v = 0\n" + " * for Béziers, u² + v² - 1 = 0 for arcs) in texture\n" + " * space, using the screen-space partial derivatives\n" + " * to convert the calculated distance to object space.\n" + " *\n" + " * d(x, y) = |f(x, y)| / ‖∇f(x, y)‖\n" + " * = |f(x, y)| / √((∂f/∂x)² + (∂f/∂y)²)\n" + " *\n" + " * For Béziers:\n" + " * f(x, y) = u(x, y)² - v(x, y)\n" + " * ∂f/∂x = 2u · ∂u/∂x - ∂v/∂x\n" + " * ∂f/∂y = 2u · ∂u/∂y - ∂v/∂y\n" + " *\n" + " * For arcs:\n" + " * f(x, y) = u(x, y)² + v(x, y)² - 1\n" + " * ∂f/∂x = 2u · ∂u/∂x + 2v · ∂v/∂x\n" + " * ∂f/∂y = 2u · ∂u/∂y + 2v · ∂v/∂y */\n" + " uv = i.b;\n" + " du = float2(ddx(uv.x), ddy(uv.x));\n" + " dv = float2(ddx(uv.y), ddy(uv.y));\n" + "\n" + " if (!is_arc)\n" + " {\n" + " df = 2.0f * uv.x * du - dv;\n" + "\n" + " clip(dot(df, uv.zw));\n" + " clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x - uv.y));\n" + " }\n" + " else\n" + " {\n" + " df = 2.0f * uv.x * du + 2.0f * uv.y * dv;\n" + "\n" + " clip(dot(df, uv.zw));\n" + " clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x + uv.y * uv.y - 1.0f));\n" + " }\n" + " }\n" + " else\n" + " {\n" + " /* Evaluate the implicit form of the curve in texture space.\n" + " * \"i.b.z\" determines which side of the curve is shaded. */\n" + " if (!is_arc)\n" + " {\n" + " clip((i.b.x * i.b.x - i.b.y) * i.b.z);\n" + " }\n" + " else\n" + " {\n" + " clip((i.b.x * i.b.x + i.b.y * i.b.y - 1.0) * i.b.z);\n" + " }\n" + " }\n" + "\n" + " return colour;\n" + "}\n"; static const struct shape_info { enum d2d_shape_type shape_type; - const D3D10_INPUT_ELEMENT_DESC *il_desc; + const D3D11_INPUT_ELEMENT_DESC *il_desc; unsigned int il_element_count; - const void *vs_code; + const char *name; + const char *vs_code; size_t vs_code_size; } shape_info[] = { {D2D_SHAPE_TYPE_OUTLINE, il_desc_outline, ARRAY_SIZE(il_desc_outline), - vs_code_outline, sizeof(vs_code_outline)}, + "outline", vs_code_outline, sizeof(vs_code_outline) - 1}, {D2D_SHAPE_TYPE_BEZIER_OUTLINE, il_desc_curve_outline, ARRAY_SIZE(il_desc_curve_outline), - vs_code_bezier_outline, sizeof(vs_code_bezier_outline)}, + "bezier_outline", vs_code_bezier_outline, sizeof(vs_code_bezier_outline) - 1}, {D2D_SHAPE_TYPE_ARC_OUTLINE, il_desc_curve_outline, ARRAY_SIZE(il_desc_curve_outline), - vs_code_arc_outline, sizeof(vs_code_arc_outline)}, + "arc_outline", vs_code_arc_outline, sizeof(vs_code_arc_outline) - 1}, {D2D_SHAPE_TYPE_TRIANGLE, il_desc_triangle, ARRAY_SIZE(il_desc_triangle), - vs_code_triangle, sizeof(vs_code_triangle)}, + "triangle", vs_code_triangle, sizeof(vs_code_triangle) - 1}, {D2D_SHAPE_TYPE_CURVE, il_desc_curve, ARRAY_SIZE(il_desc_curve), - vs_code_curve, sizeof(vs_code_curve)}, + "curve", vs_code_curve, sizeof(vs_code_curve) - 1}, }; static const struct { @@ -3828,37 +3968,37 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, { 1.0f, -1.0f}, }; static const UINT16 indices[] = {0, 1, 2, 2, 1, 3}; + static const D3D_FEATURE_LEVEL feature_levels = D3D_FEATURE_LEVEL_10_0; - render_target->ID2D1DeviceContext_iface.lpVtbl = &d2d_device_context_vtbl; + render_target->ID2D1DeviceContext6_iface.lpVtbl = &d2d_device_context_vtbl; render_target->ID2D1GdiInteropRenderTarget_iface.lpVtbl = &d2d_gdi_interop_render_target_vtbl; render_target->IDWriteTextRenderer_iface.lpVtbl = &d2d_text_renderer_vtbl; render_target->IUnknown_iface.lpVtbl = &d2d_device_context_inner_unknown_vtbl; render_target->refcount = 1; - ID2D1Device_GetFactory(device, &render_target->factory); + ID2D1Device1_GetFactory((ID2D1Device1 *)&device->ID2D1Device6_iface, &render_target->factory); render_target->device = device; - ID2D1Device_AddRef(render_target->device); + ID2D1Device6_AddRef(&render_target->device->ID2D1Device6_iface); + + factory = unsafe_impl_from_ID2D1Factory(render_target->factory); + if (factory->factory_type == D2D1_FACTORY_TYPE_MULTI_THREADED) + render_target->cs = &factory->cs; render_target->outer_unknown = outer_unknown ? outer_unknown : &render_target->IUnknown_iface; render_target->ops = ops; - device_impl = unsafe_impl_from_ID2D1Device(device); + device_impl = unsafe_impl_from_ID2D1Device((ID2D1Device1 *)device); if (FAILED(hr = IDXGIDevice_QueryInterface(device_impl->dxgi_device, - &IID_ID3D10Device, (void **)&render_target->d3d_device))) - { - WARN("Failed to get device interface, hr %#x.\n", hr); - ID2D1Factory_Release(render_target->factory); - return hr; - } - - if (FAILED(hr = D3D10StateBlockMaskEnableAll(&state_mask))) + &IID_ID3D11Device1, (void **)&render_target->d3d_device))) { - WARN("Failed to create stateblock mask, hr %#x.\n", hr); + WARN("Failed to query ID3D11Device1 interface, hr %#lx.\n", hr); goto err; } - if (FAILED(hr = D3D10CreateStateBlock(render_target->d3d_device, &state_mask, &render_target->stateblock))) + if (FAILED(hr = ID3D11Device1_CreateDeviceContextState(render_target->d3d_device, + 0, &feature_levels, 1, D3D11_SDK_VERSION, &IID_ID3D11Device1, NULL, + &render_target->d3d_state))) { - WARN("Failed to create stateblock, hr %#x.\n", hr); + WARN("Failed to create device context state, hr %#lx.\n", hr); goto err; } @@ -3866,58 +4006,80 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, { const struct shape_info *si = &shape_info[i]; - if (FAILED(hr = ID3D10Device_CreateInputLayout(render_target->d3d_device, si->il_desc, si->il_element_count, - si->vs_code, si->vs_code_size, &render_target->shape_resources[si->shape_type].il))) + if (FAILED(hr = D3DCompile(si->vs_code, si->vs_code_size, si->name, NULL, NULL, + "main", "vs_4_0", 0, 0, &compiled, NULL))) + { + WARN("Failed to compile shader for shape type %#x, hr %#lx.\n", si->shape_type, hr); + goto err; + } + + if (FAILED(hr = ID3D11Device1_CreateInputLayout(render_target->d3d_device, si->il_desc, si->il_element_count, + ID3D10Blob_GetBufferPointer(compiled), ID3D10Blob_GetBufferSize(compiled), + &render_target->shape_resources[si->shape_type].il))) { - WARN("Failed to create input layout for shape type %#x, hr %#x.\n", si->shape_type, hr); + WARN("Failed to create input layout for shape type %#x, hr %#lx.\n", si->shape_type, hr); + ID3D10Blob_Release(compiled); goto err; } - if (FAILED(hr = ID3D10Device_CreateVertexShader(render_target->d3d_device, si->vs_code, - si->vs_code_size, &render_target->shape_resources[si->shape_type].vs))) + if (FAILED(hr = ID3D11Device1_CreateVertexShader(render_target->d3d_device, + ID3D10Blob_GetBufferPointer(compiled), ID3D10Blob_GetBufferSize(compiled), + NULL, &render_target->shape_resources[si->shape_type].vs))) { - WARN("Failed to create vertex shader for shape type %#x, hr %#x.\n", si->shape_type, hr); + WARN("Failed to create vertex shader for shape type %#x, hr %#lx.\n", si->shape_type, hr); + ID3D10Blob_Release(compiled); goto err; } + ID3D10Blob_Release(compiled); } buffer_desc.ByteWidth = sizeof(struct d2d_vs_cb); - buffer_desc.Usage = D3D10_USAGE_DYNAMIC; - buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER; - buffer_desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + buffer_desc.Usage = D3D11_USAGE_DYNAMIC; + buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; buffer_desc.MiscFlags = 0; - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, NULL, + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, NULL, &render_target->vs_cb))) { - WARN("Failed to create constant buffer, hr %#x.\n", hr); + WARN("Failed to create constant buffer, hr %#lx.\n", hr); + goto err; + } + + if (FAILED(hr = D3DCompile(ps_code, sizeof(ps_code) - 1, "ps", NULL, NULL, "main", "ps_4_0", 0, 0, &compiled, NULL))) + { + WARN("Failed to compile the pixel shader, hr %#lx.\n", hr); goto err; } - if (FAILED(hr = ID3D10Device_CreatePixelShader(render_target->d3d_device, - ps_code, sizeof(ps_code), &render_target->ps))) + if (FAILED(hr = ID3D11Device1_CreatePixelShader(render_target->d3d_device, + ID3D10Blob_GetBufferPointer(compiled), ID3D10Blob_GetBufferSize(compiled), + NULL, &render_target->ps))) { - WARN("Failed to create pixel shader, hr %#x.\n", hr); + WARN("Failed to create pixel shader, hr %#lx.\n", hr); + ID3D10Blob_Release(compiled); goto err; } + ID3D10Blob_Release(compiled); + buffer_desc.ByteWidth = sizeof(struct d2d_ps_cb); - buffer_desc.Usage = D3D10_USAGE_DYNAMIC; - buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER; - buffer_desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + buffer_desc.Usage = D3D11_USAGE_DYNAMIC; + buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; buffer_desc.MiscFlags = 0; - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, NULL, + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, NULL, &render_target->ps_cb))) { - WARN("Failed to create constant buffer, hr %#x.\n", hr); + WARN("Failed to create constant buffer, hr %#lx.\n", hr); goto err; } buffer_desc.ByteWidth = sizeof(indices); - buffer_desc.Usage = D3D10_USAGE_DEFAULT; - buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER; + buffer_desc.Usage = D3D11_USAGE_DEFAULT; + buffer_desc.BindFlags = D3D11_BIND_INDEX_BUFFER; buffer_desc.CPUAccessFlags = 0; buffer_desc.MiscFlags = 0; @@ -3925,27 +4087,27 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, buffer_data.SysMemPitch = 0; buffer_data.SysMemSlicePitch = 0; - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &render_target->ib))) { - WARN("Failed to create clear index buffer, hr %#x.\n", hr); + WARN("Failed to create clear index buffer, hr %#lx.\n", hr); goto err; } buffer_desc.ByteWidth = sizeof(quad); - buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; + buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; buffer_data.pSysMem = quad; render_target->vb_stride = sizeof(*quad); - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, + if (FAILED(hr = ID3D11Device1_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &render_target->vb))) { - WARN("Failed to create clear vertex buffer, hr %#x.\n", hr); + WARN("Failed to create clear vertex buffer, hr %#lx.\n", hr); goto err; } - rs_desc.FillMode = D3D10_FILL_SOLID; - rs_desc.CullMode = D3D10_CULL_NONE; + rs_desc.FillMode = D3D11_FILL_SOLID; + rs_desc.CullMode = D3D11_CULL_NONE; rs_desc.FrontCounterClockwise = FALSE; rs_desc.DepthBias = 0; rs_desc.DepthBiasClamp = 0.0f; @@ -3954,16 +4116,16 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, rs_desc.ScissorEnable = TRUE; rs_desc.MultisampleEnable = FALSE; rs_desc.AntialiasedLineEnable = FALSE; - if (FAILED(hr = ID3D10Device_CreateRasterizerState(render_target->d3d_device, &rs_desc, &render_target->rs))) + if (FAILED(hr = ID3D11Device1_CreateRasterizerState(render_target->d3d_device, &rs_desc, &render_target->rs))) { - WARN("Failed to create clear rasterizer state, hr %#x.\n", hr); + WARN("Failed to create clear rasteriser state, hr %#lx.\n", hr); goto err; } if (FAILED(hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown **)&dwrite_factory))) { - ERR("Failed to create dwrite factory, hr %#x.\n", hr); + ERR("Failed to create dwrite factory, hr %#lx.\n", hr); goto err; } @@ -3971,7 +4133,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, IDWriteFactory_Release(dwrite_factory); if (FAILED(hr)) { - ERR("Failed to create default text rendering parameters, hr %#x.\n", hr); + ERR("Failed to create default text rendering parameters, hr %#lx.\n", hr); goto err; } @@ -3993,34 +4155,34 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, if (render_target->default_text_rendering_params) IDWriteRenderingParams_Release(render_target->default_text_rendering_params); if (render_target->rs) - ID3D10RasterizerState_Release(render_target->rs); + ID3D11RasterizerState_Release(render_target->rs); if (render_target->vb) - ID3D10Buffer_Release(render_target->vb); + ID3D11Buffer_Release(render_target->vb); if (render_target->ib) - ID3D10Buffer_Release(render_target->ib); + ID3D11Buffer_Release(render_target->ib); if (render_target->ps_cb) - ID3D10Buffer_Release(render_target->ps_cb); + ID3D11Buffer_Release(render_target->ps_cb); if (render_target->ps) - ID3D10PixelShader_Release(render_target->ps); + ID3D11PixelShader_Release(render_target->ps); if (render_target->vs_cb) - ID3D10Buffer_Release(render_target->vs_cb); + ID3D11Buffer_Release(render_target->vs_cb); for (i = 0; i < D2D_SHAPE_TYPE_COUNT; ++i) { if (render_target->shape_resources[i].vs) - ID3D10VertexShader_Release(render_target->shape_resources[i].vs); + ID3D11VertexShader_Release(render_target->shape_resources[i].vs); if (render_target->shape_resources[i].il) - ID3D10InputLayout_Release(render_target->shape_resources[i].il); + ID3D11InputLayout_Release(render_target->shape_resources[i].il); } - if (render_target->stateblock) - render_target->stateblock->lpVtbl->Release(render_target->stateblock); + if (render_target->d3d_state) + ID3DDeviceContextState_Release(render_target->d3d_state); if (render_target->d3d_device) - ID3D10Device_Release(render_target->d3d_device); - ID2D1Device_Release(render_target->device); + ID3D11Device1_Release(render_target->d3d_device); + ID2D1Device6_Release(&render_target->device->ID2D1Device6_iface); ID2D1Factory_Release(render_target->factory); return hr; } -HRESULT d2d_d3d_create_render_target(ID2D1Device *device, IDXGISurface *surface, IUnknown *outer_unknown, +HRESULT d2d_d3d_create_render_target(struct d2d_device *device, IDXGISurface *surface, IUnknown *outer_unknown, const struct d2d_device_context_ops *ops, const D2D1_RENDER_TARGET_PROPERTIES *desc, void **render_target) { D2D1_BITMAP_PROPERTIES1 bitmap_desc; @@ -4046,54 +4208,61 @@ HRESULT d2d_d3d_create_render_target(ID2D1Device *device, IDXGISurface *surface, else if (bitmap_desc.dpiX <= 0.0f || bitmap_desc.dpiY <= 0.0f) return E_INVALIDARG; - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; if (FAILED(hr = d2d_device_context_init(object, device, outer_unknown, ops))) { - WARN("Failed to initialize render target, hr %#x.\n", hr); - heap_free(object); + WARN("Failed to initialise render target, hr %#lx.\n", hr); + free(object); return hr; } - ID2D1DeviceContext_SetDpi(&object->ID2D1DeviceContext_iface, bitmap_desc.dpiX, bitmap_desc.dpiY); + ID2D1DeviceContext6_SetDpi(&object->ID2D1DeviceContext6_iface, bitmap_desc.dpiX, bitmap_desc.dpiY); if (surface) { bitmap_desc.pixelFormat = desc->pixelFormat; bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW; + if (desc->usage & D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE) + bitmap_desc.bitmapOptions |= D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE; bitmap_desc.colorContext = NULL; - if (FAILED(hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(&object->ID2D1DeviceContext_iface, + if (FAILED(hr = ID2D1DeviceContext6_CreateBitmapFromDxgiSurface(&object->ID2D1DeviceContext6_iface, surface, &bitmap_desc, &bitmap))) { - WARN("Failed to create target bitmap, hr %#x.\n", hr); + WARN("Failed to create target bitmap, hr %#lx.\n", hr); IUnknown_Release(&object->IUnknown_iface); - heap_free(object); return hr; } - ID2D1DeviceContext_SetTarget(&object->ID2D1DeviceContext_iface, (ID2D1Image *)bitmap); + ID2D1DeviceContext6_SetTarget(&object->ID2D1DeviceContext6_iface, (ID2D1Image *)bitmap); ID2D1Bitmap1_Release(bitmap); } else object->desc.pixelFormat = desc->pixelFormat; TRACE("Created render target %p.\n", object); - *render_target = outer_unknown ? &object->IUnknown_iface : (IUnknown *)&object->ID2D1DeviceContext_iface; + *render_target = outer_unknown ? &object->IUnknown_iface : (IUnknown *)&object->ID2D1DeviceContext6_iface; return S_OK; } -static HRESULT WINAPI d2d_device_QueryInterface(ID2D1Device *iface, REFIID iid, void **out) +static HRESULT WINAPI d2d_device_QueryInterface(ID2D1Device6 *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); - if (IsEqualGUID(iid, &IID_ID2D1Device) + if (IsEqualGUID(iid, &IID_ID2D1Device6) + || IsEqualGUID(iid, &IID_ID2D1Device5) + || IsEqualGUID(iid, &IID_ID2D1Device4) + || IsEqualGUID(iid, &IID_ID2D1Device3) + || IsEqualGUID(iid, &IID_ID2D1Device2) + || IsEqualGUID(iid, &IID_ID2D1Device1) + || IsEqualGUID(iid, &IID_ID2D1Device) || IsEqualGUID(iid, &IID_ID2D1Resource) || IsEqualGUID(iid, &IID_IUnknown)) { - ID2D1Device_AddRef(iface); + ID2D1Device6_AddRef(iface); *out = iface; return S_OK; } @@ -4104,34 +4273,45 @@ static HRESULT WINAPI d2d_device_QueryInterface(ID2D1Device *iface, REFIID iid, return E_NOINTERFACE; } -static ULONG WINAPI d2d_device_AddRef(ID2D1Device *iface) +static ULONG WINAPI d2d_device_AddRef(ID2D1Device6 *iface) { struct d2d_device *device = impl_from_ID2D1Device(iface); ULONG refcount = InterlockedIncrement(&device->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } -static ULONG WINAPI d2d_device_Release(ID2D1Device *iface) +void d2d_device_indexed_objects_clear(struct d2d_indexed_objects *objects) +{ + size_t i; + + for (i = 0; i < objects->count; ++i) + IUnknown_Release(objects->elements[i].object); + free(objects->elements); + objects->elements = NULL; +} + +static ULONG WINAPI d2d_device_Release(ID2D1Device6 *iface) { struct d2d_device *device = impl_from_ID2D1Device(iface); ULONG refcount = InterlockedDecrement(&device->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { IDXGIDevice_Release(device->dxgi_device); ID2D1Factory1_Release(device->factory); - heap_free(device); + d2d_device_indexed_objects_clear(&device->shaders); + free(device); } return refcount; } -static void WINAPI d2d_device_GetFactory(ID2D1Device *iface, ID2D1Factory **factory) +static void WINAPI d2d_device_GetFactory(ID2D1Device6 *iface, ID2D1Factory **factory) { struct d2d_device *device = impl_from_ID2D1Device(iface); @@ -4141,34 +4321,44 @@ static void WINAPI d2d_device_GetFactory(ID2D1Device *iface, ID2D1Factory **fact ID2D1Factory1_AddRef(device->factory); } -static HRESULT WINAPI d2d_device_CreateDeviceContext(ID2D1Device *iface, D2D1_DEVICE_CONTEXT_OPTIONS options, - ID2D1DeviceContext **context) +static HRESULT d2d_device_create_device_context(struct d2d_device *device, + D2D1_DEVICE_CONTEXT_OPTIONS options, REFIID iid, void **context) { struct d2d_device_context *object; HRESULT hr; - TRACE("iface %p, options %#x, context %p.\n", iface, options, context); - if (options) FIXME("Options are ignored %#x.\n", options); - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; - if (FAILED(hr = d2d_device_context_init(object, iface, NULL, NULL))) + if (FAILED(hr = d2d_device_context_init(object, device, NULL, NULL))) { - WARN("Failed to initialize device context, hr %#x.\n", hr); - heap_free(object); + WARN("Failed to initialise device context, hr %#lx.\n", hr); + free(object); return hr; } TRACE("Created device context %p.\n", object); - *context = &object->ID2D1DeviceContext_iface; - return S_OK; + hr = ID2D1DeviceContext6_QueryInterface(&object->ID2D1DeviceContext6_iface, iid, context); + ID2D1DeviceContext6_Release(&object->ID2D1DeviceContext6_iface); + + return hr; } -static HRESULT WINAPI d2d_device_CreatePrintControl(ID2D1Device *iface, IWICImagingFactory *wic_factory, +static HRESULT WINAPI d2d_device_CreateDeviceContext(ID2D1Device6 *iface, D2D1_DEVICE_CONTEXT_OPTIONS options, + ID2D1DeviceContext **context) +{ + struct d2d_device *device = impl_from_ID2D1Device(iface); + + TRACE("iface %p, options %#x, context %p.\n", iface, options, context); + + return d2d_device_create_device_context(device, options, &IID_ID2D1DeviceContext, (void **)context); +} + +static HRESULT WINAPI d2d_device_CreatePrintControl(ID2D1Device6 *iface, IWICImagingFactory *wic_factory, IPrintDocumentPackageTarget *document_target, const D2D1_PRINT_CONTROL_PROPERTIES *desc, ID2D1PrintControl **print_control) { @@ -4178,26 +4368,125 @@ static HRESULT WINAPI d2d_device_CreatePrintControl(ID2D1Device *iface, IWICImag return E_NOTIMPL; } -static void WINAPI d2d_device_SetMaximumTextureMemory(ID2D1Device *iface, UINT64 max_texture_memory) +static void WINAPI d2d_device_SetMaximumTextureMemory(ID2D1Device6 *iface, UINT64 max_texture_memory) { FIXME("iface %p, max_texture_memory %s stub!\n", iface, wine_dbgstr_longlong(max_texture_memory)); } -static UINT64 WINAPI d2d_device_GetMaximumTextureMemory(ID2D1Device *iface) +static UINT64 WINAPI d2d_device_GetMaximumTextureMemory(ID2D1Device6 *iface) { FIXME("iface %p stub!\n", iface); return 0; } -static HRESULT WINAPI d2d_device_ClearResources(ID2D1Device *iface, UINT msec_since_use) +static HRESULT WINAPI d2d_device_ClearResources(ID2D1Device6 *iface, UINT msec_since_use) { FIXME("iface %p, msec_since_use %u stub!\n", iface, msec_since_use); return E_NOTIMPL; } -static const struct ID2D1DeviceVtbl d2d_device_vtbl = +static D2D1_RENDERING_PRIORITY WINAPI d2d_device_GetRenderingPriority(ID2D1Device6 *iface) +{ + FIXME("iface %p stub!\n", iface); + + return D2D1_RENDERING_PRIORITY_NORMAL; +} + +static void WINAPI d2d_device_SetRenderingPriority(ID2D1Device6 *iface, D2D1_RENDERING_PRIORITY priority) +{ + FIXME("iface %p, priority %#x stub!\n", iface, priority); +} + +static HRESULT WINAPI d2d_device_CreateDeviceContext1(ID2D1Device6 *iface, D2D1_DEVICE_CONTEXT_OPTIONS options, + ID2D1DeviceContext1 **context) +{ + struct d2d_device *device = impl_from_ID2D1Device(iface); + + TRACE("iface %p, options %#x, context %p.\n", iface, options, context); + + return d2d_device_create_device_context(device, options, &IID_ID2D1DeviceContext1, (void **)context); +} + +static HRESULT STDMETHODCALLTYPE d2d_device_ID2D1Device2_CreateDeviceContext(ID2D1Device6 *iface, + D2D1_DEVICE_CONTEXT_OPTIONS options, ID2D1DeviceContext2 **context) +{ + struct d2d_device *device = impl_from_ID2D1Device(iface); + + TRACE("iface %p, options %#x, context %p.\n", iface, options, context); + + return d2d_device_create_device_context(device, options, &IID_ID2D1DeviceContext2, (void **)context); +} + +static void STDMETHODCALLTYPE d2d_device_FlushDeviceContexts(ID2D1Device6 *iface, + ID2D1Bitmap *bitmap) +{ + FIXME("iface %p, bitmap %p stub!\n", iface, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_device_GetDxgiDevice(ID2D1Device6 *iface, + IDXGIDevice **dxgi_device) +{ + FIXME("iface %p, dxgi_device %p stub!\n", iface, dxgi_device); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_device_ID2D1Device3_CreateDeviceContext(ID2D1Device6 *iface, + D2D1_DEVICE_CONTEXT_OPTIONS options, ID2D1DeviceContext3 **context) +{ + struct d2d_device *device = impl_from_ID2D1Device(iface); + + TRACE("iface %p, options %#x, context %p.\n", iface, options, context); + + return d2d_device_create_device_context(device, options, &IID_ID2D1DeviceContext3, (void **)context); +} + +static HRESULT STDMETHODCALLTYPE d2d_device_ID2D1Device4_CreateDeviceContext(ID2D1Device6 *iface, + D2D1_DEVICE_CONTEXT_OPTIONS options, ID2D1DeviceContext4 **context) +{ + struct d2d_device *device = impl_from_ID2D1Device(iface); + + TRACE("iface %p, options %#x, context %p.\n", iface, options, context); + + return d2d_device_create_device_context(device, options, &IID_ID2D1DeviceContext4, (void **)context); +} + +static void STDMETHODCALLTYPE d2d_device_SetMaximumColorGlyphCacheMemory(ID2D1Device6 *iface, + UINT64 size) +{ + FIXME("iface %p, size %s stub!\n", iface, wine_dbgstr_longlong(size)); +} + +static UINT64 STDMETHODCALLTYPE d2d_device_GetMaximumColorGlyphCacheMemory(ID2D1Device6 *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static HRESULT STDMETHODCALLTYPE d2d_device_ID2D1Device5_CreateDeviceContext(ID2D1Device6 *iface, + D2D1_DEVICE_CONTEXT_OPTIONS options, ID2D1DeviceContext5 **context) +{ + struct d2d_device *device = impl_from_ID2D1Device(iface); + + TRACE("iface %p, options %#x, context %p.\n", iface, options, context); + + return d2d_device_create_device_context(device, options, &IID_ID2D1DeviceContext5, (void **)context); +} + +static HRESULT STDMETHODCALLTYPE d2d_device_ID2D1Device6_CreateDeviceContext(ID2D1Device6 *iface, + D2D1_DEVICE_CONTEXT_OPTIONS options, ID2D1DeviceContext6 **context) +{ + struct d2d_device *device = impl_from_ID2D1Device(iface); + + TRACE("iface %p, options %#x, context %p.\n", iface, options, context); + + return d2d_device_create_device_context(device, options, &IID_ID2D1DeviceContext6, (void **)context); +} + +static const struct ID2D1Device6Vtbl d2d_device_vtbl = { d2d_device_QueryInterface, d2d_device_AddRef, @@ -4208,22 +4497,74 @@ static const struct ID2D1DeviceVtbl d2d_device_vtbl = d2d_device_SetMaximumTextureMemory, d2d_device_GetMaximumTextureMemory, d2d_device_ClearResources, + d2d_device_GetRenderingPriority, + d2d_device_SetRenderingPriority, + d2d_device_CreateDeviceContext1, + d2d_device_ID2D1Device2_CreateDeviceContext, + d2d_device_FlushDeviceContexts, + d2d_device_GetDxgiDevice, + d2d_device_ID2D1Device3_CreateDeviceContext, + d2d_device_ID2D1Device4_CreateDeviceContext, + d2d_device_SetMaximumColorGlyphCacheMemory, + d2d_device_GetMaximumColorGlyphCacheMemory, + d2d_device_ID2D1Device5_CreateDeviceContext, + d2d_device_ID2D1Device6_CreateDeviceContext, }; -static struct d2d_device *unsafe_impl_from_ID2D1Device(ID2D1Device *iface) +struct d2d_device *unsafe_impl_from_ID2D1Device(ID2D1Device1 *iface) { if (!iface) return NULL; - assert(iface->lpVtbl == &d2d_device_vtbl); - return CONTAINING_RECORD(iface, struct d2d_device, ID2D1Device_iface); + assert(iface->lpVtbl == (ID2D1Device1Vtbl *)&d2d_device_vtbl); + return CONTAINING_RECORD(iface, struct d2d_device, ID2D1Device6_iface); } -void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *iface, IDXGIDevice *dxgi_device) +void d2d_device_init(struct d2d_device *device, struct d2d_factory *factory, IDXGIDevice *dxgi_device) { - device->ID2D1Device_iface.lpVtbl = &d2d_device_vtbl; + device->ID2D1Device6_iface.lpVtbl = &d2d_device_vtbl; device->refcount = 1; - device->factory = iface; + device->factory = (ID2D1Factory1 *)&factory->ID2D1Factory7_iface; ID2D1Factory1_AddRef(device->factory); device->dxgi_device = dxgi_device; IDXGIDevice_AddRef(device->dxgi_device); } + +HRESULT d2d_device_add_indexed_object(struct d2d_indexed_objects *objects, + const GUID *id, IUnknown *object) +{ + if (!d2d_array_reserve((void **)&objects->elements, &objects->size, objects->count + 1, + sizeof(*objects->elements))) + { + WARN("Failed to resize elements array.\n"); + return E_OUTOFMEMORY; + } + + objects->elements[objects->count].id = *id; + objects->elements[objects->count].object = object; + IUnknown_AddRef(object); + objects->count++; + + return S_OK; +} + +BOOL d2d_device_get_indexed_object(struct d2d_indexed_objects *objects, const GUID *id, + IUnknown **object) +{ + size_t i; + + for (i = 0; i < objects->count; ++i) + { + if (IsEqualGUID(id, &objects->elements[i].id)) + { + if (object) + { + *object = objects->elements[i].object; + IUnknown_AddRef(*object); + } + return TRUE; + } + } + + if (object) *object = NULL; + return FALSE; +} diff --git a/wrappers/directx/wine/d2d1/effect.c b/wrappers/directx/wine/d2d1/effect.c index fb1e66a3d9..7ea6673e27 100644 --- a/wrappers/directx/wine/d2d1/effect.c +++ b/wrappers/directx/wine/d2d1/effect.c @@ -20,192 +20,2717 @@ WINE_DEFAULT_DEBUG_CHANNEL(d2d); -static inline struct d2d_effect *impl_from_ID2D1Effect(ID2D1Effect *iface) +static inline struct d2d_transform *impl_from_ID2D1OffsetTransform(ID2D1OffsetTransform *iface) { - return CONTAINING_RECORD(iface, struct d2d_effect, ID2D1Effect_iface); + return CONTAINING_RECORD(iface, struct d2d_transform, ID2D1TransformNode_iface); } -static HRESULT STDMETHODCALLTYPE d2d_effect_QueryInterface(ID2D1Effect *iface, REFIID iid, void **out) +static inline struct d2d_transform *impl_from_ID2D1BlendTransform(ID2D1BlendTransform *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_transform, ID2D1TransformNode_iface); +} + +static inline struct d2d_transform *impl_from_ID2D1BorderTransform(ID2D1BorderTransform *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_transform, ID2D1TransformNode_iface); +} + +static inline struct d2d_transform *impl_from_ID2D1BoundsAdjustmentTransform( + ID2D1BoundsAdjustmentTransform *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_transform, ID2D1TransformNode_iface); +} + +static inline struct d2d_vertex_buffer *impl_from_ID2D1VertexBuffer(ID2D1VertexBuffer *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_vertex_buffer, ID2D1VertexBuffer_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_vertex_buffer_QueryInterface(ID2D1VertexBuffer *iface, + REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); - if (IsEqualGUID(iid, &IID_ID2D1Effect) - || IsEqualGUID(iid, &IID_ID2D1Properties) + if (IsEqualGUID(iid, &IID_ID2D1VertexBuffer) || IsEqualGUID(iid, &IID_IUnknown)) { - ID2D1Effect_AddRef(iface); *out = iface; + ID2D1VertexBuffer_AddRef(iface); return S_OK; } - WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); - + WARN("Unsupported interface %s.\n", debugstr_guid(iid)); *out = NULL; return E_NOINTERFACE; } -static ULONG STDMETHODCALLTYPE d2d_effect_AddRef(ID2D1Effect *iface) +static ULONG STDMETHODCALLTYPE d2d_vertex_buffer_AddRef(ID2D1VertexBuffer *iface) { - struct d2d_effect *effect = impl_from_ID2D1Effect(iface); - ULONG refcount = InterlockedIncrement(&effect->refcount); + struct d2d_vertex_buffer *buffer = impl_from_ID2D1VertexBuffer(iface); + ULONG refcount = InterlockedIncrement(&buffer->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } -static ULONG STDMETHODCALLTYPE d2d_effect_Release(ID2D1Effect *iface) +static ULONG STDMETHODCALLTYPE d2d_vertex_buffer_Release(ID2D1VertexBuffer *iface) { - struct d2d_effect *effect = impl_from_ID2D1Effect(iface); - ULONG refcount = InterlockedDecrement(&effect->refcount); + struct d2d_vertex_buffer *buffer = impl_from_ID2D1VertexBuffer(iface); + ULONG refcount = InterlockedDecrement(&buffer->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) - heap_free(effect); + free(buffer); return refcount; } -static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyCount(ID2D1Effect *iface) +static HRESULT STDMETHODCALLTYPE d2d_vertex_buffer_Map(ID2D1VertexBuffer *iface, BYTE **data, UINT32 size) { - FIXME("iface %p stub!\n", iface); + FIXME("iface %p, data %p, size %u.\n", iface, data, size); - return 0; + return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_effect_GetPropertyName(ID2D1Effect *iface, UINT32 index, - WCHAR *name, UINT32 name_count) +static HRESULT STDMETHODCALLTYPE d2d_vertex_buffer_Unmap(ID2D1VertexBuffer *iface) { - FIXME("iface %p, index %u, name %p, name_count %u stub!\n", iface, index, name, name_count); + FIXME("iface %p.\n", iface); return E_NOTIMPL; } -static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyNameLength(ID2D1Effect *iface, UINT32 index) +static const ID2D1VertexBufferVtbl d2d_vertex_buffer_vtbl = +{ + d2d_vertex_buffer_QueryInterface, + d2d_vertex_buffer_AddRef, + d2d_vertex_buffer_Release, + d2d_vertex_buffer_Map, + d2d_vertex_buffer_Unmap, +}; + +static HRESULT d2d_vertex_buffer_create(ID2D1VertexBuffer **buffer) { - FIXME("iface %p, index %u stub!\n", iface, index); + struct d2d_vertex_buffer *object; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID2D1VertexBuffer_iface.lpVtbl = &d2d_vertex_buffer_vtbl; + object->refcount = 1; - return 0; + *buffer = &object->ID2D1VertexBuffer_iface; + + return S_OK; } -static D2D1_PROPERTY_TYPE STDMETHODCALLTYPE d2d_effect_GetType(ID2D1Effect *iface, UINT32 index) +static HRESULT STDMETHODCALLTYPE d2d_offset_transform_QueryInterface(ID2D1OffsetTransform *iface, + REFIID iid, void **out) { - FIXME("iface %p, index %u stub!\n", iface, index); + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); - return 0; + if (IsEqualGUID(iid, &IID_ID2D1OffsetTransform) + || IsEqualGUID(iid, &IID_ID2D1TransformNode) + || IsEqualGUID(iid, &IID_IUnknown)) + { + *out = iface; + ID2D1OffsetTransform_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; } -static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyIndex(ID2D1Effect *iface, const WCHAR *name) +static ULONG STDMETHODCALLTYPE d2d_offset_transform_AddRef(ID2D1OffsetTransform *iface) { - FIXME("iface %p, name %s stub!\n", iface, debugstr_w(name)); + struct d2d_transform *transform = impl_from_ID2D1OffsetTransform(iface); + ULONG refcount = InterlockedIncrement(&transform->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); - return 0; + return refcount; } -static HRESULT STDMETHODCALLTYPE d2d_effect_SetValueByName(ID2D1Effect *iface, const WCHAR *name, - D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 value_size) +static ULONG STDMETHODCALLTYPE d2d_offset_transform_Release(ID2D1OffsetTransform *iface) { - FIXME("iface %p, name %s, type %#x, value %p, value_size %u stub!\n", iface, debugstr_w(name), - type, value, value_size); + struct d2d_transform *transform = impl_from_ID2D1OffsetTransform(iface); + ULONG refcount = InterlockedDecrement(&transform->refcount); - return E_NOTIMPL; + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + free(transform); + + return refcount; } -static HRESULT STDMETHODCALLTYPE d2d_effect_SetValue(ID2D1Effect *iface, UINT32 index, D2D1_PROPERTY_TYPE type, - const BYTE *value, UINT32 value_size) +static UINT32 STDMETHODCALLTYPE d2d_offset_transform_GetInputCount(ID2D1OffsetTransform *iface) +{ + TRACE("iface %p.\n", iface); + + return 1; +} + +static void STDMETHODCALLTYPE d2d_offset_transform_SetOffset(ID2D1OffsetTransform *iface, + D2D1_POINT_2L offset) +{ + struct d2d_transform *transform = impl_from_ID2D1OffsetTransform(iface); + + TRACE("iface %p, offset %s.\n", iface, debug_d2d_point_2l(&offset)); + + transform->offset = offset; +} + +static D2D1_POINT_2L * STDMETHODCALLTYPE d2d_offset_transform_GetOffset(ID2D1OffsetTransform *iface, + D2D1_POINT_2L *offset) +{ + struct d2d_transform *transform = impl_from_ID2D1OffsetTransform(iface); + + TRACE("iface %p.\n", iface); + + *offset = transform->offset; + return offset; +} + +static const ID2D1OffsetTransformVtbl d2d_offset_transform_vtbl = +{ + d2d_offset_transform_QueryInterface, + d2d_offset_transform_AddRef, + d2d_offset_transform_Release, + d2d_offset_transform_GetInputCount, + d2d_offset_transform_SetOffset, + d2d_offset_transform_GetOffset, +}; + +static HRESULT d2d_offset_transform_create(D2D1_POINT_2L offset, ID2D1OffsetTransform **transform) { - FIXME("iface %p, index %u, type %#x, value %p, value_size %u stub!\n", iface, index, type, value, value_size); + struct d2d_transform *object; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID2D1TransformNode_iface.lpVtbl = (ID2D1TransformNodeVtbl *)&d2d_offset_transform_vtbl; + object->refcount = 1; + object->offset = offset; + + *transform = (ID2D1OffsetTransform *)&object->ID2D1TransformNode_iface; return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_effect_GetValueByName(ID2D1Effect *iface, const WCHAR *name, - D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size) +static HRESULT STDMETHODCALLTYPE d2d_blend_transform_QueryInterface(ID2D1BlendTransform *iface, + REFIID iid, void **out) { - FIXME("iface %p, name %s, type %#x, value %p, value_size %u stub!\n", iface, debugstr_w(name), type, - value, value_size); + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); - return E_NOTIMPL; + if (IsEqualGUID(iid, &IID_ID2D1BlendTransform) + || IsEqualGUID(iid, &IID_ID2D1ConcreteTransform) + || IsEqualGUID(iid, &IID_ID2D1TransformNode) + || IsEqualGUID(iid, &IID_IUnknown)) + { + *out = iface; + ID2D1BlendTransform_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; } -static HRESULT STDMETHODCALLTYPE d2d_effect_GetValue(ID2D1Effect *iface, UINT32 index, D2D1_PROPERTY_TYPE type, - BYTE *value, UINT32 value_size) +static ULONG STDMETHODCALLTYPE d2d_blend_transform_AddRef(ID2D1BlendTransform *iface) { - FIXME("iface %p, index %u, type %#x, value %p, value_size %u stub!\n", iface, index, type, - value, value_size); + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + ULONG refcount = InterlockedIncrement(&transform->refcount); - return E_NOTIMPL; + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; } -static UINT32 STDMETHODCALLTYPE d2d_effect_GetValueSize(ID2D1Effect *iface, UINT32 index) +static ULONG STDMETHODCALLTYPE d2d_blend_transform_Release(ID2D1BlendTransform *iface) +{ + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + ULONG refcount = InterlockedDecrement(&transform->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + free(transform); + + return refcount; +} + +static UINT32 STDMETHODCALLTYPE d2d_blend_transform_GetInputCount(ID2D1BlendTransform *iface) { - FIXME("iface %p, index %u stub!\n", iface, index); + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + + TRACE("iface %p.\n", iface); - return 0; + return transform->input_count; } -static HRESULT STDMETHODCALLTYPE d2d_effect_GetSubProperties(ID2D1Effect *iface, UINT32 index, ID2D1Properties **props) +static HRESULT STDMETHODCALLTYPE d2d_blend_transform_SetOutputBuffer(ID2D1BlendTransform *iface, + D2D1_BUFFER_PRECISION precision, D2D1_CHANNEL_DEPTH depth) { - FIXME("iface %p, index %u, props %p stub!\n", iface, index, props); + FIXME("iface %p, precision %u, depth %u stub.\n", iface, precision, depth); return E_NOTIMPL; } -static void STDMETHODCALLTYPE d2d_effect_SetInput(ID2D1Effect *iface, UINT32 index, ID2D1Image *input, BOOL invalidate) +static void STDMETHODCALLTYPE d2d_blend_transform_SetCached(ID2D1BlendTransform *iface, + BOOL is_cached) { - FIXME("iface %p, index %u, input %p, invalidate %d stub!\n", iface, index, input, invalidate); + FIXME("iface %p, is_cached %d stub.\n", iface, is_cached); } -static HRESULT STDMETHODCALLTYPE d2d_effect_SetInputCount(ID2D1Effect *iface, UINT32 count) +static void STDMETHODCALLTYPE d2d_blend_transform_SetDescription(ID2D1BlendTransform *iface, + const D2D1_BLEND_DESCRIPTION *description) +{ + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + + TRACE("iface %p, description %p.\n", iface, description); + + transform->blend_desc = *description; +} + +static void STDMETHODCALLTYPE d2d_blend_transform_GetDescription(ID2D1BlendTransform *iface, + D2D1_BLEND_DESCRIPTION *description) +{ + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + + TRACE("iface %p, description %p.\n", iface, description); + + *description = transform->blend_desc; +} + +static const ID2D1BlendTransformVtbl d2d_blend_transform_vtbl = +{ + d2d_blend_transform_QueryInterface, + d2d_blend_transform_AddRef, + d2d_blend_transform_Release, + d2d_blend_transform_GetInputCount, + d2d_blend_transform_SetOutputBuffer, + d2d_blend_transform_SetCached, + d2d_blend_transform_SetDescription, + d2d_blend_transform_GetDescription, +}; + +static HRESULT d2d_blend_transform_create(UINT32 input_count, const D2D1_BLEND_DESCRIPTION *blend_desc, + ID2D1BlendTransform **transform) +{ + struct d2d_transform *object; + + *transform = NULL; + + if (!input_count) + return E_INVALIDARG; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID2D1TransformNode_iface.lpVtbl = (ID2D1TransformNodeVtbl *)&d2d_blend_transform_vtbl; + object->refcount = 1; + object->input_count = input_count; + object->blend_desc = *blend_desc; + + *transform = (ID2D1BlendTransform *)&object->ID2D1TransformNode_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_border_transform_QueryInterface(ID2D1BorderTransform *iface, + REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1BorderTransform) + || IsEqualGUID(iid, &IID_ID2D1ConcreteTransform) + || IsEqualGUID(iid, &IID_ID2D1TransformNode) + || IsEqualGUID(iid, &IID_IUnknown)) + { + *out = iface; + ID2D1BorderTransform_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_border_transform_AddRef(ID2D1BorderTransform *iface) +{ + struct d2d_transform *transform = impl_from_ID2D1BorderTransform(iface); + ULONG refcount = InterlockedIncrement(&transform->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_border_transform_Release(ID2D1BorderTransform *iface) +{ + struct d2d_transform *transform = impl_from_ID2D1BorderTransform(iface); + ULONG refcount = InterlockedDecrement(&transform->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + free(transform); + + return refcount; +} + +static UINT32 STDMETHODCALLTYPE d2d_border_transform_GetInputCount(ID2D1BorderTransform *iface) +{ + TRACE("iface %p.\n", iface); + + return 1; +} + +static HRESULT STDMETHODCALLTYPE d2d_border_transform_SetOutputBuffer( + ID2D1BorderTransform *iface, D2D1_BUFFER_PRECISION precision, D2D1_CHANNEL_DEPTH depth) { - FIXME("iface %p, count %u stub!\n", iface, count); + FIXME("iface %p, precision %u, depth %u stub.\n", iface, precision, depth); return E_NOTIMPL; } -static void STDMETHODCALLTYPE d2d_effect_GetInput(ID2D1Effect *iface, UINT32 index, ID2D1Image **input) +static void STDMETHODCALLTYPE d2d_border_transform_SetCached( + ID2D1BorderTransform *iface, BOOL is_cached) { - FIXME("iface %p, index %u, input %p stub!\n", iface, index, input); + FIXME("iface %p, is_cached %d stub.\n", iface, is_cached); } -static UINT32 STDMETHODCALLTYPE d2d_effect_GetInputCount(ID2D1Effect *iface) +static void STDMETHODCALLTYPE d2d_border_transform_SetExtendModeX( + ID2D1BorderTransform *iface, D2D1_EXTEND_MODE mode) { - FIXME("iface %p stub!\n", iface); + struct d2d_transform *transform = impl_from_ID2D1BorderTransform(iface); - return 0; + TRACE("iface %p.\n", iface); + + switch (mode) + { + case D2D1_EXTEND_MODE_CLAMP: + case D2D1_EXTEND_MODE_WRAP: + case D2D1_EXTEND_MODE_MIRROR: + transform->border.mode_x = mode; + break; + default: + ; + } } -static void STDMETHODCALLTYPE d2d_effect_GetOutput(ID2D1Effect *iface, ID2D1Image **output) +static void STDMETHODCALLTYPE d2d_border_transform_SetExtendModeY( + ID2D1BorderTransform *iface, D2D1_EXTEND_MODE mode) { - FIXME("iface %p, output %p stub!\n", iface, output); + struct d2d_transform *transform = impl_from_ID2D1BorderTransform(iface); + + TRACE("iface %p.\n", iface); + + switch (mode) + { + case D2D1_EXTEND_MODE_CLAMP: + case D2D1_EXTEND_MODE_WRAP: + case D2D1_EXTEND_MODE_MIRROR: + transform->border.mode_y = mode; + break; + default: + ; + } } -static const ID2D1EffectVtbl d2d_effect_vtbl = +static D2D1_EXTEND_MODE STDMETHODCALLTYPE d2d_border_transform_GetExtendModeX( + ID2D1BorderTransform *iface) { - d2d_effect_QueryInterface, - d2d_effect_AddRef, - d2d_effect_Release, - d2d_effect_GetPropertyCount, - d2d_effect_GetPropertyName, - d2d_effect_GetPropertyNameLength, - d2d_effect_GetType, - d2d_effect_GetPropertyIndex, - d2d_effect_SetValueByName, - d2d_effect_SetValue, - d2d_effect_GetValueByName, - d2d_effect_GetValue, - d2d_effect_GetValueSize, - d2d_effect_GetSubProperties, - d2d_effect_SetInput, - d2d_effect_SetInputCount, - d2d_effect_GetInput, - d2d_effect_GetInputCount, - d2d_effect_GetOutput, + struct d2d_transform *transform = impl_from_ID2D1BorderTransform(iface); + + TRACE("iface %p.\n", iface); + + return transform->border.mode_x; +} + +static D2D1_EXTEND_MODE STDMETHODCALLTYPE d2d_border_transform_GetExtendModeY( + ID2D1BorderTransform *iface) +{ + struct d2d_transform *transform = impl_from_ID2D1BorderTransform(iface); + + TRACE("iface %p.\n", iface); + + return transform->border.mode_y; +} + +static const ID2D1BorderTransformVtbl d2d_border_transform_vtbl = +{ + d2d_border_transform_QueryInterface, + d2d_border_transform_AddRef, + d2d_border_transform_Release, + d2d_border_transform_GetInputCount, + d2d_border_transform_SetOutputBuffer, + d2d_border_transform_SetCached, + d2d_border_transform_SetExtendModeX, + d2d_border_transform_SetExtendModeY, + d2d_border_transform_GetExtendModeX, + d2d_border_transform_GetExtendModeY, }; -void d2d_effect_init(struct d2d_effect *effect) +static HRESULT d2d_border_transform_create(D2D1_EXTEND_MODE mode_x, D2D1_EXTEND_MODE mode_y, + ID2D1BorderTransform **transform) +{ + struct d2d_transform *object; + + *transform = NULL; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID2D1TransformNode_iface.lpVtbl = (ID2D1TransformNodeVtbl *)&d2d_border_transform_vtbl; + object->refcount = 1; + object->border.mode_x = mode_x; + object->border.mode_y = mode_y; + + *transform = (ID2D1BorderTransform *)&object->ID2D1TransformNode_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_bounds_adjustment_transform_QueryInterface( + ID2D1BoundsAdjustmentTransform *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1BoundsAdjustmentTransform) + || IsEqualGUID(iid, &IID_ID2D1TransformNode) + || IsEqualGUID(iid, &IID_IUnknown)) + { + *out = iface; + ID2D1BoundsAdjustmentTransform_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_bounds_adjustment_transform_AddRef( + ID2D1BoundsAdjustmentTransform *iface) +{ + struct d2d_transform *transform = impl_from_ID2D1BoundsAdjustmentTransform(iface); + ULONG refcount = InterlockedIncrement(&transform->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_bounds_adjustment_transform_Release( + ID2D1BoundsAdjustmentTransform *iface) +{ + struct d2d_transform *transform = impl_from_ID2D1BoundsAdjustmentTransform(iface); + ULONG refcount = InterlockedDecrement(&transform->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + free(transform); + + return refcount; +} + +static UINT32 STDMETHODCALLTYPE d2d_bounds_adjustment_transform_GetInputCount( + ID2D1BoundsAdjustmentTransform *iface) +{ + TRACE("iface %p.\n", iface); + + return 1; +} + +static void STDMETHODCALLTYPE d2d_bounds_adjustment_transform_SetOutputBounds( + ID2D1BoundsAdjustmentTransform *iface, const D2D1_RECT_L *bounds) +{ + struct d2d_transform *transform = impl_from_ID2D1BoundsAdjustmentTransform(iface); + + TRACE("iface %p.\n", iface); + + transform->bounds = *bounds; +} + +static void STDMETHODCALLTYPE d2d_bounds_adjustment_transform_GetOutputBounds( + ID2D1BoundsAdjustmentTransform *iface, D2D1_RECT_L *bounds) +{ + struct d2d_transform *transform = impl_from_ID2D1BoundsAdjustmentTransform(iface); + + TRACE("iface %p.\n", iface); + + *bounds = transform->bounds; +} + +static const ID2D1BoundsAdjustmentTransformVtbl d2d_bounds_adjustment_transform_vtbl = { - effect->ID2D1Effect_iface.lpVtbl = &d2d_effect_vtbl; - effect->refcount = 1; + d2d_bounds_adjustment_transform_QueryInterface, + d2d_bounds_adjustment_transform_AddRef, + d2d_bounds_adjustment_transform_Release, + d2d_bounds_adjustment_transform_GetInputCount, + d2d_bounds_adjustment_transform_SetOutputBounds, + d2d_bounds_adjustment_transform_GetOutputBounds, +}; + +static HRESULT d2d_bounds_adjustment_transform_create(const D2D1_RECT_L *rect, + ID2D1BoundsAdjustmentTransform **transform) +{ + struct d2d_transform *object; + + *transform = NULL; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID2D1TransformNode_iface.lpVtbl = (ID2D1TransformNodeVtbl *)&d2d_bounds_adjustment_transform_vtbl; + object->refcount = 1; + object->bounds = *rect; + + *transform = (ID2D1BoundsAdjustmentTransform *)&object->ID2D1TransformNode_iface; + + return S_OK; +} + +static struct d2d_transform_node * d2d_transform_graph_get_node(const struct d2d_transform_graph *graph, + ID2D1TransformNode *object) +{ + struct d2d_transform_node *node; + + LIST_FOR_EACH_ENTRY(node, &graph->nodes, struct d2d_transform_node, entry) + { + if (node->object == object) + return node; + } + + return NULL; +} + +static HRESULT d2d_transform_graph_add_node(struct d2d_transform_graph *graph, + ID2D1TransformNode *object) +{ + struct d2d_transform_node *node; + + if (!(node = calloc(1, sizeof(*node)))) + return E_OUTOFMEMORY; + node->input_count = ID2D1TransformNode_GetInputCount(object); + if (!(node->inputs = calloc(node->input_count, sizeof(*node->inputs)))) + { + free(node); + return E_OUTOFMEMORY; + } + + node->object = object; + ID2D1TransformNode_AddRef(node->object); + list_add_tail(&graph->nodes, &node->entry); + + return S_OK; +} + +static void d2d_transform_node_disconnect(struct d2d_transform_node *node) +{ + struct d2d_transform_node *output = node->output; + unsigned int i; + + if (!output) + return; + + for (i = 0; i < output->input_count; ++i) + { + if (output->inputs[i] == node) + { + output->inputs[i] = NULL; + break; + } + } +} + +static void d2d_transform_graph_delete_node(struct d2d_transform_graph *graph, + struct d2d_transform_node *node) +{ + unsigned int i; + + list_remove(&node->entry); + ID2D1TransformNode_Release(node->object); + + for (i = 0; i < graph->input_count; ++i) + { + if (graph->inputs[i].node == node) + memset(&graph->inputs[i].node, 0, sizeof(graph->inputs[i].node)); + } + + if (graph->output == node) + graph->output = NULL; + + if (node->render_info) + ID2D1DrawInfo_Release(&node->render_info->ID2D1DrawInfo_iface); + + d2d_transform_node_disconnect(node); + + free(node->inputs); + free(node); +} + +static void d2d_transform_graph_clear(struct d2d_transform_graph *graph) +{ + struct d2d_transform_node *node, *node_next; + + LIST_FOR_EACH_ENTRY_SAFE(node, node_next, &graph->nodes, struct d2d_transform_node, entry) + { + d2d_transform_graph_delete_node(graph, node); + } + graph->passthrough = false; +} + +static inline struct d2d_transform_graph *impl_from_ID2D1TransformGraph(ID2D1TransformGraph *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_transform_graph, ID2D1TransformGraph_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_transform_graph_QueryInterface(ID2D1TransformGraph *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1TransformGraph) + || IsEqualGUID(iid, &IID_IUnknown)) + { + ID2D1TransformGraph_AddRef(iface); + *out = iface; + return S_OK; + } + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_transform_graph_AddRef(ID2D1TransformGraph *iface) +{ + struct d2d_transform_graph *graph =impl_from_ID2D1TransformGraph(iface); + ULONG refcount = InterlockedIncrement(&graph->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_transform_graph_Release(ID2D1TransformGraph *iface) +{ + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + ULONG refcount = InterlockedDecrement(&graph->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + { + d2d_transform_graph_clear(graph); + free(graph->inputs); + free(graph); + } + + return refcount; +} + +static UINT32 STDMETHODCALLTYPE d2d_transform_graph_GetInputCount(ID2D1TransformGraph *iface) +{ + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + + TRACE("iface %p.\n", iface); + + return graph->input_count; +} + +static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetSingleTransformNode(ID2D1TransformGraph *iface, + ID2D1TransformNode *object) +{ + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *node; + unsigned int i, input_count; + HRESULT hr; + + TRACE("iface %p, object %p.\n", iface, object); + + d2d_transform_graph_clear(graph); + if (FAILED(hr = d2d_transform_graph_add_node(graph, object))) + return hr; + + node = d2d_transform_graph_get_node(graph, object); + graph->output = node; + + input_count = ID2D1TransformNode_GetInputCount(object); + if (graph->input_count != input_count) + return E_INVALIDARG; + + for (i = 0; i < graph->input_count; ++i) + { + graph->inputs[i].node = node; + graph->inputs[i].index = i; + } + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_transform_graph_AddNode(ID2D1TransformGraph *iface, + ID2D1TransformNode *object) +{ + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + + TRACE("iface %p, object %p.\n", iface, object); + + if (d2d_transform_graph_get_node(graph, object)) + return E_INVALIDARG; + + return d2d_transform_graph_add_node(graph, object); +} + +static HRESULT STDMETHODCALLTYPE d2d_transform_graph_RemoveNode(ID2D1TransformGraph *iface, + ID2D1TransformNode *object) +{ + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *node; + + TRACE("iface %p, object %p.\n", iface, object); + + if (!(node = d2d_transform_graph_get_node(graph, object))) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + d2d_transform_graph_delete_node(graph, node); + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetOutputNode(ID2D1TransformGraph *iface, + ID2D1TransformNode *object) +{ + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *node; + + TRACE("iface %p, object %p.\n", iface, object); + + if (!(node = d2d_transform_graph_get_node(graph, object))) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + graph->output = node; + graph->passthrough = false; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_transform_graph_ConnectNode(ID2D1TransformGraph *iface, + ID2D1TransformNode *from_node, ID2D1TransformNode *to_node, UINT32 index) +{ + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *from, *to; + + TRACE("iface %p, from_node %p, to_node %p, index %u.\n", iface, from_node, to_node, index); + + if (!(from = d2d_transform_graph_get_node(graph, from_node))) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + if (!(to = d2d_transform_graph_get_node(graph, to_node))) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + if (index >= to->input_count) + return E_INVALIDARG; + + d2d_transform_node_disconnect(from); + to->inputs[index] = from; + from->output = to; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_transform_graph_ConnectToEffectInput(ID2D1TransformGraph *iface, + UINT32 input_index, ID2D1TransformNode *object, UINT32 node_index) +{ + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *node; + unsigned int count; + + TRACE("iface %p, input_index %u, object %p, node_index %u.\n", iface, input_index, object, node_index); + + if (!(node = d2d_transform_graph_get_node(graph, object))) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + if (input_index >= graph->input_count) + return E_INVALIDARG; + + count = ID2D1TransformNode_GetInputCount(object); + if (node_index >= count) + return E_INVALIDARG; + + graph->inputs[input_index].node = node; + graph->inputs[input_index].index = node_index; + graph->passthrough = false; + + return S_OK; +} + +static void STDMETHODCALLTYPE d2d_transform_graph_Clear(ID2D1TransformGraph *iface) +{ + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + + TRACE("iface %p.\n", iface); + + d2d_transform_graph_clear(graph); +} + +static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetPassthroughGraph(ID2D1TransformGraph *iface, UINT32 index) +{ + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + + TRACE("iface %p, index %u.\n", iface, index); + + if (index >= graph->input_count) + return E_INVALIDARG; + + d2d_transform_graph_clear(graph); + + graph->passthrough = true; + graph->passthrough_input = index; + + return S_OK; +} + +static const ID2D1TransformGraphVtbl d2d_transform_graph_vtbl = +{ + d2d_transform_graph_QueryInterface, + d2d_transform_graph_AddRef, + d2d_transform_graph_Release, + d2d_transform_graph_GetInputCount, + d2d_transform_graph_SetSingleTransformNode, + d2d_transform_graph_AddNode, + d2d_transform_graph_RemoveNode, + d2d_transform_graph_SetOutputNode, + d2d_transform_graph_ConnectNode, + d2d_transform_graph_ConnectToEffectInput, + d2d_transform_graph_Clear, + d2d_transform_graph_SetPassthroughGraph, +}; + +static HRESULT d2d_transform_graph_create(UINT32 input_count, struct d2d_transform_graph **graph) +{ + struct d2d_transform_graph *object; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID2D1TransformGraph_iface.lpVtbl = &d2d_transform_graph_vtbl; + object->refcount = 1; + list_init(&object->nodes); + + if (!(object->inputs = calloc(input_count, sizeof(*object->inputs)))) + { + free(object); + return E_OUTOFMEMORY; + } + object->input_count = input_count; + + *graph = object; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_impl_QueryInterface(ID2D1EffectImpl *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1EffectImpl) + || IsEqualGUID(iid, &IID_IUnknown)) + { + ID2D1EffectImpl_AddRef(iface); + *out = iface; + return S_OK; + } + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_effect_impl_AddRef(ID2D1EffectImpl *iface) +{ + return 2; +} + +static ULONG STDMETHODCALLTYPE d2d_effect_impl_Release(ID2D1EffectImpl *iface) +{ + return 1; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_impl_Initialize(ID2D1EffectImpl *iface, + ID2D1EffectContext *context, ID2D1TransformGraph *graph) +{ + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_impl_PrepareForRender(ID2D1EffectImpl *iface, D2D1_CHANGE_TYPE type) +{ + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_impl_SetGraph(ID2D1EffectImpl *iface, ID2D1TransformGraph *graph) +{ + return S_OK; +} + +static const ID2D1EffectImplVtbl d2d_effect_impl_vtbl = +{ + d2d_effect_impl_QueryInterface, + d2d_effect_impl_AddRef, + d2d_effect_impl_Release, + d2d_effect_impl_Initialize, + d2d_effect_impl_PrepareForRender, + d2d_effect_impl_SetGraph, +}; + +static HRESULT STDMETHODCALLTYPE builtin_factory_stub(IUnknown **effect_impl) +{ + static ID2D1EffectImpl builtin_stub = { &d2d_effect_impl_vtbl }; + + *effect_impl = (IUnknown *)&builtin_stub; + + return S_OK; +} + +static const WCHAR _2d_affine_transform_description[] = +L" \ + \ + \ + \ + \ + \ + \ + \ + \ + "; + +static const WCHAR _3d_perspective_transform_description[] = +L" \ + \ + \ + \ + \ + \ + \ + \ + \ + "; + +static const WCHAR composite_description[] = +L" \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + "; + +static const WCHAR crop_description[] = +L" \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + "; + +static const WCHAR shadow_description[] = +L" \ + \ + \ + \ + \ + \ + \ + \ + \ + "; + +static const WCHAR grayscale_description[] = +L" \ + \ + \ + \ + \ + \ + \ + \ + \ + "; + +void d2d_effects_init_builtins(struct d2d_factory *factory) +{ + static const struct builtin_description + { + const CLSID *clsid; + const WCHAR *description; + } + builtin_effects[] = + { + { &CLSID_D2D12DAffineTransform, _2d_affine_transform_description }, + { &CLSID_D2D13DPerspectiveTransform, _3d_perspective_transform_description}, + { &CLSID_D2D1Composite, composite_description }, + { &CLSID_D2D1Crop, crop_description }, + { &CLSID_D2D1Shadow, shadow_description }, + { &CLSID_D2D1Grayscale, grayscale_description }, + }; + unsigned int i; + HRESULT hr; + + for (i = 0; i < ARRAY_SIZE(builtin_effects); ++i) + { + if (FAILED(hr = d2d_factory_register_builtin_effect(factory, builtin_effects[i].clsid, builtin_effects[i].description, + NULL, 0, builtin_factory_stub))) + { + WARN("Failed to register the effect %s, hr %#lx.\n", wine_dbgstr_guid(builtin_effects[i].clsid), hr); + } + } +} + +/* Same syntax is used for value and default values. */ +static HRESULT d2d_effect_parse_float_array(D2D1_PROPERTY_TYPE type, const WCHAR *value, + float *vec) +{ + unsigned int i, num_components; + WCHAR *end_ptr; + + /* Type values are sequential. */ + switch (type) + { + case D2D1_PROPERTY_TYPE_VECTOR2: + case D2D1_PROPERTY_TYPE_VECTOR3: + case D2D1_PROPERTY_TYPE_VECTOR4: + num_components = (type - D2D1_PROPERTY_TYPE_VECTOR2) + 2; + break; + case D2D1_PROPERTY_TYPE_MATRIX_3X2: + num_components = 6; + break; + case D2D1_PROPERTY_TYPE_MATRIX_4X3: + case D2D1_PROPERTY_TYPE_MATRIX_4X4: + case D2D1_PROPERTY_TYPE_MATRIX_5X4: + num_components = (type - D2D1_PROPERTY_TYPE_MATRIX_4X3) * 4 + 12; + break; + default: + return E_UNEXPECTED; + } + + if (*(value++) != '(') return E_INVALIDARG; + + for (i = 0; i < num_components; ++i) + { + vec[i] = wcstof(value, &end_ptr); + if (value == end_ptr) return E_INVALIDARG; + value = end_ptr; + + /* Trailing characters after last component are ignored. */ + if (i == num_components - 1) continue; + if (*(value++) != ',') return E_INVALIDARG; + } + + return S_OK; +} + +static HRESULT d2d_effect_properties_internal_add(struct d2d_effect_properties *props, + const WCHAR *name, UINT32 index, BOOL subprop, D2D1_PROPERTY_TYPE type, const WCHAR *value) +{ + static const UINT32 sizes[] = + { + [D2D1_PROPERTY_TYPE_UNKNOWN] = 0, + [D2D1_PROPERTY_TYPE_STRING] = 0, + [D2D1_PROPERTY_TYPE_BOOL] = sizeof(BOOL), + [D2D1_PROPERTY_TYPE_UINT32] = sizeof(UINT32), + [D2D1_PROPERTY_TYPE_INT32] = sizeof(INT32), + [D2D1_PROPERTY_TYPE_FLOAT] = sizeof(float), + [D2D1_PROPERTY_TYPE_VECTOR2] = sizeof(D2D_VECTOR_2F), + [D2D1_PROPERTY_TYPE_VECTOR3] = sizeof(D2D_VECTOR_3F), + [D2D1_PROPERTY_TYPE_VECTOR4] = sizeof(D2D_VECTOR_4F), + [D2D1_PROPERTY_TYPE_BLOB] = 0, + [D2D1_PROPERTY_TYPE_IUNKNOWN] = sizeof(IUnknown *), + [D2D1_PROPERTY_TYPE_ENUM] = sizeof(UINT32), + [D2D1_PROPERTY_TYPE_ARRAY] = sizeof(UINT32), + [D2D1_PROPERTY_TYPE_CLSID] = sizeof(CLSID), + [D2D1_PROPERTY_TYPE_MATRIX_3X2] = sizeof(D2D_MATRIX_3X2_F), + [D2D1_PROPERTY_TYPE_MATRIX_4X3] = sizeof(D2D_MATRIX_4X3_F), + [D2D1_PROPERTY_TYPE_MATRIX_4X4] = sizeof(D2D_MATRIX_4X4_F), + [D2D1_PROPERTY_TYPE_MATRIX_5X4] = sizeof(D2D_MATRIX_5X4_F), + [D2D1_PROPERTY_TYPE_COLOR_CONTEXT] = sizeof(ID2D1ColorContext *), + }; + struct d2d_effect_property *p; + HRESULT hr; + + assert(type >= D2D1_PROPERTY_TYPE_STRING && type <= D2D1_PROPERTY_TYPE_COLOR_CONTEXT); + + if (!d2d_array_reserve((void **)&props->properties, &props->size, props->count + 1, + sizeof(*props->properties))) + { + return E_OUTOFMEMORY; + } + + /* TODO: we could save some space for properties that have both getter and setter. */ + if (!d2d_array_reserve((void **)&props->data.ptr, &props->data.size, + props->data.count + sizes[type], sizeof(*props->data.ptr))) + { + return E_OUTOFMEMORY; + } + props->data.count += sizes[type]; + + p = &props->properties[props->count++]; + memset(p, 0, sizeof(*p)); + p->index = index; + if (p->index < 0x80000000) + { + props->custom_count++; + /* FIXME: this should probably be controlled by subproperty */ + p->readonly = FALSE; + } + else if (subprop) + p->readonly = TRUE; + else + p->readonly = index != D2D1_PROPERTY_CACHED && index != D2D1_PROPERTY_PRECISION; + p->name = wcsdup(name); + p->type = type; + if (p->type == D2D1_PROPERTY_TYPE_STRING) + { + p->data.ptr = wcsdup(value); + p->size = value ? (wcslen(value) + 1) * sizeof(WCHAR) : sizeof(WCHAR); + } + else if (p->type == D2D1_PROPERTY_TYPE_BLOB) + { + p->data.ptr = NULL; + p->size = 0; + } + else + { + void *src = NULL; + UINT32 _uint32; + float _vec[20]; + CLSID _clsid; + BOOL _bool; + + p->data.offset = props->offset; + p->size = sizes[type]; + props->offset += p->size; + + if (value) + { + switch (p->type) + { + case D2D1_PROPERTY_TYPE_UINT32: + case D2D1_PROPERTY_TYPE_INT32: + _uint32 = wcstoul(value, NULL, 0); + src = &_uint32; + break; + case D2D1_PROPERTY_TYPE_ENUM: + _uint32 = wcstoul(value, NULL, 10); + src = &_uint32; + break; + case D2D1_PROPERTY_TYPE_BOOL: + if (!wcscmp(value, L"true")) _bool = TRUE; + else if (!wcscmp(value, L"false")) _bool = FALSE; + else return E_INVALIDARG; + src = &_bool; + break; + case D2D1_PROPERTY_TYPE_CLSID: + CLSIDFromString(value, &_clsid); + src = &_clsid; + break; + case D2D1_PROPERTY_TYPE_VECTOR2: + case D2D1_PROPERTY_TYPE_VECTOR3: + case D2D1_PROPERTY_TYPE_VECTOR4: + case D2D1_PROPERTY_TYPE_MATRIX_3X2: + case D2D1_PROPERTY_TYPE_MATRIX_4X3: + case D2D1_PROPERTY_TYPE_MATRIX_4X4: + case D2D1_PROPERTY_TYPE_MATRIX_5X4: + if (FAILED(hr = d2d_effect_parse_float_array(p->type, value, _vec))) + { + WARN("Failed to parse float array %s for type %u.\n", + wine_dbgstr_w(value), p->type); + return hr; + } + src = _vec; + break; + case D2D1_PROPERTY_TYPE_IUNKNOWN: + case D2D1_PROPERTY_TYPE_COLOR_CONTEXT: + break; + default: + FIXME("Initial value for property type %u is not handled.\n", p->type); + } + + if (src && p->size) memcpy(props->data.ptr + p->data.offset, src, p->size); + } + else if (p->size) + memset(props->data.ptr + p->data.offset, 0, p->size); + } + + return S_OK; +} + +HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCHAR *name, + UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value) +{ + return d2d_effect_properties_internal_add(props, name, index, FALSE, type, value); +} + +HRESULT d2d_effect_subproperties_add(struct d2d_effect_properties *props, const WCHAR *name, + UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value) +{ + return d2d_effect_properties_internal_add(props, name, index, TRUE, type, value); +} + +static HRESULT d2d_effect_duplicate_properties(struct d2d_effect *effect, + struct d2d_effect_properties *dst, const struct d2d_effect_properties *src) +{ + HRESULT hr; + size_t i; + + *dst = *src; + dst->effect = effect; + + if (!(dst->data.ptr = malloc(dst->data.size))) + return E_OUTOFMEMORY; + memcpy(dst->data.ptr, src->data.ptr, dst->data.size); + + if (!(dst->properties = calloc(dst->size, sizeof(*dst->properties)))) + return E_OUTOFMEMORY; + + for (i = 0; i < dst->count; ++i) + { + struct d2d_effect_property *d = &dst->properties[i]; + const struct d2d_effect_property *s = &src->properties[i]; + + *d = *s; + d->name = wcsdup(s->name); + if (d->type == D2D1_PROPERTY_TYPE_STRING) + d->data.ptr = wcsdup((WCHAR *)s->data.ptr); + + if (s->subproperties) + { + if (!(d->subproperties = calloc(1, sizeof(*d->subproperties)))) + return E_OUTOFMEMORY; + if (FAILED(hr = d2d_effect_duplicate_properties(effect, d->subproperties, s->subproperties))) + return hr; + } + } + + return S_OK; +} + +static struct d2d_effect_property * d2d_effect_properties_get_property_by_index( + const struct d2d_effect_properties *properties, UINT32 index) +{ + unsigned int i; + + for (i = 0; i < properties->count; ++i) + { + if (properties->properties[i].index == index) + return &properties->properties[i]; + } + + return NULL; +} + +struct d2d_effect_property * d2d_effect_properties_get_property_by_name( + const struct d2d_effect_properties *properties, const WCHAR *name) +{ + unsigned int i; + + for (i = 0; i < properties->count; ++i) + { + if (!wcscmp(properties->properties[i].name, name)) + return &properties->properties[i]; + } + + return NULL; +} + +static UINT32 d2d_effect_properties_get_value_size(const struct d2d_effect_properties *properties, + UINT32 index) +{ + struct d2d_effect *effect = properties->effect; + struct d2d_effect_property *prop; + UINT32 size; + + if (!(prop = d2d_effect_properties_get_property_by_index(properties, index))) + return 0; + + if (prop->get_function) + { + if (FAILED(prop->get_function((IUnknown *)effect->impl, NULL, 0, &size))) return 0; + return size; + } + + return prop->size; +} + +static HRESULT d2d_effect_return_string(const WCHAR *str, WCHAR *buffer, UINT32 buffer_size) +{ + UINT32 size = str ? wcslen(str) : 0; + if (size >= buffer_size) return D2DERR_INSUFFICIENT_BUFFER; + if (str) memcpy(buffer, str, (size + 1) * sizeof(*buffer)); + else *buffer = 0; + return S_OK; +} + +static HRESULT d2d_effect_property_get_value(const struct d2d_effect_properties *properties, + const struct d2d_effect_property *prop, D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 size) +{ + struct d2d_effect *effect = properties->effect; + UINT32 actual_size; + + memset(value, 0, size); + + if (type != D2D1_PROPERTY_TYPE_UNKNOWN && prop->type != type) return E_INVALIDARG; + /* Do not check sizes for variable-length properties. */ + if (prop->type != D2D1_PROPERTY_TYPE_STRING + && prop->type != D2D1_PROPERTY_TYPE_BLOB + && prop->size != size) + { + return E_INVALIDARG; + } + + if (prop->get_function) + return prop->get_function((IUnknown *)effect->impl, value, size, &actual_size); + + switch (prop->type) + { + case D2D1_PROPERTY_TYPE_BLOB: + memset(value, 0, size); + break; + case D2D1_PROPERTY_TYPE_STRING: + return d2d_effect_return_string(prop->data.ptr, (WCHAR *)value, size / sizeof(WCHAR)); + default: + memcpy(value, properties->data.ptr + prop->data.offset, size); + break; + } + + return S_OK; +} + +HRESULT d2d_effect_property_get_uint32_value(const struct d2d_effect_properties *properties, + const struct d2d_effect_property *prop, UINT32 *value) +{ + return d2d_effect_property_get_value(properties, prop, D2D1_PROPERTY_TYPE_UINT32, + (BYTE *)value, sizeof(*value)); +} + +static HRESULT d2d_effect_property_set_value(struct d2d_effect_properties *properties, + struct d2d_effect_property *prop, D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 size) +{ + struct d2d_effect *effect = properties->effect; + if (prop->readonly || !effect) return E_INVALIDARG; + if (type != D2D1_PROPERTY_TYPE_UNKNOWN && prop->type != type) return E_INVALIDARG; + if (prop->get_function && !prop->set_function) return E_INVALIDARG; + if (prop->index < 0x80000000 && !prop->set_function) return E_INVALIDARG; + + if (prop->set_function) + return prop->set_function((IUnknown *)effect->impl, value, size); + + if (prop->size != size) return E_INVALIDARG; + + switch (prop->type) + { + case D2D1_PROPERTY_TYPE_BOOL: + case D2D1_PROPERTY_TYPE_UINT32: + case D2D1_PROPERTY_TYPE_ENUM: + memcpy(properties->data.ptr + prop->data.offset, value, size); + break; + default: + FIXME("Unhandled type %u.\n", prop->type); + } + + return S_OK; +} + +void d2d_effect_properties_cleanup(struct d2d_effect_properties *props) +{ + struct d2d_effect_property *p; + size_t i; + + for (i = 0; i < props->count; ++i) + { + p = &props->properties[i]; + free(p->name); + if (p->type == D2D1_PROPERTY_TYPE_STRING) + free(p->data.ptr); + if (p->subproperties) + { + d2d_effect_properties_cleanup(p->subproperties); + free(p->subproperties); + } + } + free(props->properties); + free(props->data.ptr); +} + +static inline struct d2d_effect_context *impl_from_ID2D1EffectContext(ID2D1EffectContext *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_effect_context, ID2D1EffectContext_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_QueryInterface(ID2D1EffectContext *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1EffectContext) + || IsEqualGUID(iid, &IID_IUnknown)) + { + ID2D1EffectContext_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_effect_context_AddRef(ID2D1EffectContext *iface) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + ULONG refcount = InterlockedIncrement(&effect_context->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_effect_context_Release(ID2D1EffectContext *iface) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + ULONG refcount = InterlockedDecrement(&effect_context->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + { + ID2D1DeviceContext6_Release(&effect_context->device_context->ID2D1DeviceContext6_iface); + free(effect_context); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d2d_effect_context_GetDpi(ID2D1EffectContext *iface, float *dpi_x, float *dpi_y) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + + TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y); + + ID2D1DeviceContext6_GetDpi(&effect_context->device_context->ID2D1DeviceContext6_iface, dpi_x, dpi_y); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateEffect(ID2D1EffectContext *iface, + REFCLSID clsid, ID2D1Effect **effect) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + + TRACE("iface %p, clsid %s, effect %p.\n", iface, debugstr_guid(clsid), effect); + + return ID2D1DeviceContext6_CreateEffect(&effect_context->device_context->ID2D1DeviceContext6_iface, + clsid, effect); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_GetMaximumSupportedFeatureLevel(ID2D1EffectContext *iface, + const D3D_FEATURE_LEVEL *levels, UINT32 level_count, D3D_FEATURE_LEVEL *max_level) +{ + FIXME("iface %p, levels %p, level_count %u, max_level %p stub!\n", iface, levels, level_count, max_level); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateTransformNodeFromEffect(ID2D1EffectContext *iface, + ID2D1Effect *effect, ID2D1TransformNode **node) +{ + FIXME("iface %p, effect %p, node %p stub!\n", iface, effect, node); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateBlendTransform(ID2D1EffectContext *iface, + UINT32 num_inputs, const D2D1_BLEND_DESCRIPTION *description, ID2D1BlendTransform **transform) +{ + TRACE("iface %p, num_inputs %u, description %p, transform %p,\n", iface, num_inputs, description, transform); + + return d2d_blend_transform_create(num_inputs, description, transform); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateBorderTransform(ID2D1EffectContext *iface, + D2D1_EXTEND_MODE mode_x, D2D1_EXTEND_MODE mode_y, ID2D1BorderTransform **transform) +{ + TRACE("iface %p, mode_x %#x, mode_y %#x, transform %p.\n", iface, mode_x, mode_y, transform); + + return d2d_border_transform_create(mode_x, mode_y, transform); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateOffsetTransform(ID2D1EffectContext *iface, + D2D1_POINT_2L offset, ID2D1OffsetTransform **transform) +{ + TRACE("iface %p, offset %s, transform %p.\n", iface, debug_d2d_point_2l(&offset), transform); + + return d2d_offset_transform_create(offset, transform); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateBoundsAdjustmentTransform(ID2D1EffectContext *iface, + const D2D1_RECT_L *output_rect, ID2D1BoundsAdjustmentTransform **transform) +{ + TRACE("iface %p, output_rect %s, transform %p.\n", iface, debug_d2d_rect_l(output_rect), transform); + + return d2d_bounds_adjustment_transform_create(output_rect, transform); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_LoadPixelShader(ID2D1EffectContext *iface, + REFGUID shader_id, const BYTE *buffer, UINT32 buffer_size) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + struct d2d_device *device = effect_context->device_context->device; + ID3D11PixelShader *shader; + HRESULT hr; + + TRACE("iface %p, shader_id %s, buffer %p, buffer_size %u.\n", + iface, debugstr_guid(shader_id), buffer, buffer_size); + + if (d2d_device_get_indexed_object(&device->shaders, shader_id, NULL)) + return S_OK; + + if (FAILED(hr = ID3D11Device1_CreatePixelShader(effect_context->device_context->d3d_device, + buffer, buffer_size, NULL, &shader))) + { + WARN("Failed to create a pixel shader, hr %#lx.\n", hr); + return hr; + } + + hr = d2d_device_add_indexed_object(&device->shaders, shader_id, (IUnknown *)shader); + ID3D11PixelShader_Release(shader); + + return hr; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_LoadVertexShader(ID2D1EffectContext *iface, + REFGUID shader_id, const BYTE *buffer, UINT32 buffer_size) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + struct d2d_device *device = effect_context->device_context->device; + ID3D11VertexShader *shader; + HRESULT hr; + + TRACE("iface %p, shader_id %s, buffer %p, buffer_size %u.\n", + iface, debugstr_guid(shader_id), buffer, buffer_size); + + if (d2d_device_get_indexed_object(&device->shaders, shader_id, NULL)) + return S_OK; + + if (FAILED(hr = ID3D11Device1_CreateVertexShader(effect_context->device_context->d3d_device, + buffer, buffer_size, NULL, &shader))) + { + WARN("Failed to create vertex shader, hr %#lx.\n", hr); + return hr; + } + + hr = d2d_device_add_indexed_object(&device->shaders, shader_id, (IUnknown *)shader); + ID3D11VertexShader_Release(shader); + + return hr; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_LoadComputeShader(ID2D1EffectContext *iface, + REFGUID shader_id, const BYTE *buffer, UINT32 buffer_size) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + struct d2d_device *device = effect_context->device_context->device; + ID3D11ComputeShader *shader; + HRESULT hr; + + TRACE("iface %p, shader_id %s, buffer %p, buffer_size %u.\n", + iface, debugstr_guid(shader_id), buffer, buffer_size); + + if (d2d_device_get_indexed_object(&device->shaders, shader_id, NULL)) + return S_OK; + + if (FAILED(hr = ID3D11Device1_CreateComputeShader(effect_context->device_context->d3d_device, + buffer, buffer_size, NULL, &shader))) + { + WARN("Failed to create a compute shader, hr %#lx.\n", hr); + return hr; + } + + hr = d2d_device_add_indexed_object(&device->shaders, shader_id, (IUnknown *)shader); + ID3D11ComputeShader_Release(shader); + + return hr; +} + +static BOOL STDMETHODCALLTYPE d2d_effect_context_IsShaderLoaded(ID2D1EffectContext *iface, REFGUID shader_id) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + struct d2d_device *device = effect_context->device_context->device; + + TRACE("iface %p, shader_id %s.\n", iface, debugstr_guid(shader_id)); + + return d2d_device_get_indexed_object(&device->shaders, shader_id, NULL); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateResourceTexture(ID2D1EffectContext *iface, + const GUID *id, const D2D1_RESOURCE_TEXTURE_PROPERTIES *texture_properties, + const BYTE *data, const UINT32 *strides, UINT32 data_size, ID2D1ResourceTexture **texture) +{ + FIXME("iface %p, id %s, texture_properties %p, data %p, strides %p, data_size %u, texture %p stub!\n", + iface, debugstr_guid(id), texture_properties, data, strides, data_size, texture); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_FindResourceTexture(ID2D1EffectContext *iface, + const GUID *id, ID2D1ResourceTexture **texture) +{ + FIXME("iface %p, id %s, texture %p stub!\n", iface, debugstr_guid(id), texture); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateVertexBuffer(ID2D1EffectContext *iface, + const D2D1_VERTEX_BUFFER_PROPERTIES *buffer_properties, const GUID *id, + const D2D1_CUSTOM_VERTEX_BUFFER_PROPERTIES *custom_buffer_properties, + ID2D1VertexBuffer **buffer) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + struct d2d_device_context *context = effect_context->device_context; + HRESULT hr; + + FIXME("iface %p, buffer_properties %p, id %s, custom_buffer_properties %p, buffer %p stub!\n", + iface, buffer_properties, debugstr_guid(id), custom_buffer_properties, buffer); + + if (id && d2d_device_get_indexed_object(&context->vertex_buffers, id, (IUnknown **)buffer)) + return S_OK; + + if (SUCCEEDED(hr = d2d_vertex_buffer_create(buffer))) + { + if (id) + hr = d2d_device_add_indexed_object(&context->vertex_buffers, id, (IUnknown *)*buffer); + } + + if (FAILED(hr)) + *buffer = NULL; + + return hr; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_FindVertexBuffer(ID2D1EffectContext *iface, + const GUID *id, ID2D1VertexBuffer **buffer) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + struct d2d_device_context *context = effect_context->device_context; + + TRACE("iface %p, id %s, buffer %p.\n", iface, debugstr_guid(id), buffer); + + if (!d2d_device_get_indexed_object(&context->vertex_buffers, id, (IUnknown **)buffer)) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateColorContext(ID2D1EffectContext *iface, + D2D1_COLOR_SPACE space, const BYTE *profile, UINT32 profile_size, ID2D1ColorContext **color_context) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + + TRACE("iface %p, space %#x, profile %p, profile_size %u, color_context %p.\n", + iface, space, profile, profile_size, color_context); + + return ID2D1DeviceContext6_CreateColorContext(&effect_context->device_context->ID2D1DeviceContext6_iface, + space, profile, profile_size, color_context); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateColorContextFromFilename(ID2D1EffectContext *iface, + const WCHAR *filename, ID2D1ColorContext **color_context) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + + TRACE("iface %p, filename %s, color_context %p.\n", iface, debugstr_w(filename), color_context); + + return ID2D1DeviceContext6_CreateColorContextFromFilename(&effect_context->device_context->ID2D1DeviceContext6_iface, + filename, color_context); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateColorContextFromWicColorContext(ID2D1EffectContext *iface, + IWICColorContext *wic_color_context, ID2D1ColorContext **color_context) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + + TRACE("iface %p, wic_color_context %p, color_context %p.\n", iface, wic_color_context, color_context); + + return ID2D1DeviceContext6_CreateColorContextFromWicColorContext(&effect_context->device_context->ID2D1DeviceContext6_iface, + wic_color_context, color_context); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_context_CheckFeatureSupport(ID2D1EffectContext *iface, + D2D1_FEATURE feature, void *data, UINT32 data_size) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + D3D11_FEATURE d3d11_feature; + + TRACE("iface %p, feature %#x, data %p, data_size %u.\n", iface, feature, data, data_size); + + /* Data structures are compatible. */ + switch (feature) + { + case D2D1_FEATURE_DOUBLES: d3d11_feature = D3D11_FEATURE_DOUBLES; break; + case D2D1_FEATURE_D3D10_X_HARDWARE_OPTIONS: d3d11_feature = D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS; break; + default: + WARN("Unexpected feature index %d.\n", feature); + return E_INVALIDARG; + } + + return ID3D11Device1_CheckFeatureSupport(effect_context->device_context->d3d_device, + d3d11_feature, data, data_size); +} + +static BOOL STDMETHODCALLTYPE d2d_effect_context_IsBufferPrecisionSupported(ID2D1EffectContext *iface, + D2D1_BUFFER_PRECISION precision) +{ + struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface); + + TRACE("iface %p, precision %u.\n", iface, precision); + + return ID2D1DeviceContext6_IsBufferPrecisionSupported(&effect_context->device_context->ID2D1DeviceContext6_iface, + precision); +} + +static const ID2D1EffectContextVtbl d2d_effect_context_vtbl = +{ + d2d_effect_context_QueryInterface, + d2d_effect_context_AddRef, + d2d_effect_context_Release, + d2d_effect_context_GetDpi, + d2d_effect_context_CreateEffect, + d2d_effect_context_GetMaximumSupportedFeatureLevel, + d2d_effect_context_CreateTransformNodeFromEffect, + d2d_effect_context_CreateBlendTransform, + d2d_effect_context_CreateBorderTransform, + d2d_effect_context_CreateOffsetTransform, + d2d_effect_context_CreateBoundsAdjustmentTransform, + d2d_effect_context_LoadPixelShader, + d2d_effect_context_LoadVertexShader, + d2d_effect_context_LoadComputeShader, + d2d_effect_context_IsShaderLoaded, + d2d_effect_context_CreateResourceTexture, + d2d_effect_context_FindResourceTexture, + d2d_effect_context_CreateVertexBuffer, + d2d_effect_context_FindVertexBuffer, + d2d_effect_context_CreateColorContext, + d2d_effect_context_CreateColorContextFromFilename, + d2d_effect_context_CreateColorContextFromWicColorContext, + d2d_effect_context_CheckFeatureSupport, + d2d_effect_context_IsBufferPrecisionSupported, +}; + +void d2d_effect_context_init(struct d2d_effect_context *effect_context, struct d2d_device_context *device_context) +{ + effect_context->ID2D1EffectContext_iface.lpVtbl = &d2d_effect_context_vtbl; + effect_context->refcount = 1; + effect_context->device_context = device_context; + ID2D1DeviceContext6_AddRef(&device_context->ID2D1DeviceContext6_iface); +} + +static inline struct d2d_effect *impl_from_ID2D1Effect(ID2D1Effect *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_effect, ID2D1Effect_iface); +} + +static void d2d_effect_cleanup(struct d2d_effect *effect) +{ + unsigned int i; + + for (i = 0; i < effect->input_count; ++i) + { + if (effect->inputs[i]) + ID2D1Image_Release(effect->inputs[i]); + } + free(effect->inputs); + ID2D1EffectContext_Release(&effect->effect_context->ID2D1EffectContext_iface); + if (effect->graph) + ID2D1TransformGraph_Release(&effect->graph->ID2D1TransformGraph_iface); + d2d_effect_properties_cleanup(&effect->properties); + if (effect->impl) + ID2D1EffectImpl_Release(effect->impl); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_QueryInterface(ID2D1Effect *iface, REFIID iid, void **out) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1Effect) + || IsEqualGUID(iid, &IID_ID2D1Properties) + || IsEqualGUID(iid, &IID_IUnknown)) + { + ID2D1Effect_AddRef(iface); + *out = iface; + return S_OK; + } + + if (IsEqualGUID(iid, &IID_ID2D1Image) + || IsEqualGUID(iid, &IID_ID2D1Resource)) + { + ID2D1Image_AddRef(&effect->ID2D1Image_iface); + *out = &effect->ID2D1Image_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_effect_AddRef(ID2D1Effect *iface) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + ULONG refcount = InterlockedIncrement(&effect->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_effect_Release(ID2D1Effect *iface) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + ULONG refcount = InterlockedDecrement(&effect->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + { + d2d_effect_cleanup(effect); + free(effect); + } + + return refcount; +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyCount(ID2D1Effect *iface) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1Properties_GetPropertyCount(&effect->properties.ID2D1Properties_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_GetPropertyName(ID2D1Effect *iface, UINT32 index, + WCHAR *name, UINT32 name_count) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, index %u, name %p, name_count %u.\n", iface, index, name, name_count); + + return ID2D1Properties_GetPropertyName(&effect->properties.ID2D1Properties_iface, + index, name, name_count); +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyNameLength(ID2D1Effect *iface, UINT32 index) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, index %u.\n", iface, index); + + return ID2D1Properties_GetPropertyNameLength(&effect->properties.ID2D1Properties_iface, index); +} + +static D2D1_PROPERTY_TYPE STDMETHODCALLTYPE d2d_effect_GetType(ID2D1Effect *iface, UINT32 index) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, index %#x.\n", iface, index); + + return ID2D1Properties_GetType(&effect->properties.ID2D1Properties_iface, index); +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyIndex(ID2D1Effect *iface, const WCHAR *name) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, name %s.\n", iface, debugstr_w(name)); + + return ID2D1Properties_GetPropertyIndex(&effect->properties.ID2D1Properties_iface, name); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_SetValueByName(ID2D1Effect *iface, const WCHAR *name, + D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 value_size) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, name %s, type %u, value %p, value_size %u.\n", iface, debugstr_w(name), + type, value, value_size); + + return ID2D1Properties_SetValueByName(&effect->properties.ID2D1Properties_iface, name, + type, value, value_size); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_SetValue(ID2D1Effect *iface, UINT32 index, D2D1_PROPERTY_TYPE type, + const BYTE *value, UINT32 value_size) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, index %#x, type %u, value %p, value_size %u.\n", iface, index, type, value, value_size); + + return ID2D1Properties_SetValue(&effect->properties.ID2D1Properties_iface, index, type, + value, value_size); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_GetValueByName(ID2D1Effect *iface, const WCHAR *name, + D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, name %s, type %#x, value %p, value_size %u.\n", iface, debugstr_w(name), type, + value, value_size); + + return ID2D1Properties_GetValueByName(&effect->properties.ID2D1Properties_iface, name, type, + value, value_size); +} + +static HRESULT d2d_effect_get_value(struct d2d_effect *effect, UINT32 index, D2D1_PROPERTY_TYPE type, + BYTE *value, UINT32 value_size) +{ + return ID2D1Properties_GetValue(&effect->properties.ID2D1Properties_iface, index, type, value, value_size); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_GetValue(ID2D1Effect *iface, UINT32 index, D2D1_PROPERTY_TYPE type, + BYTE *value, UINT32 value_size) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, index %#x, type %u, value %p, value_size %u.\n", iface, index, type, value, value_size); + + return d2d_effect_get_value(effect, index, type, value, value_size); +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_GetValueSize(ID2D1Effect *iface, UINT32 index) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, index %#x.\n", iface, index); + + return ID2D1Properties_GetValueSize(&effect->properties.ID2D1Properties_iface, index); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_GetSubProperties(ID2D1Effect *iface, UINT32 index, + ID2D1Properties **props) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, index %u, props %p.\n", iface, index, props); + + return ID2D1Properties_GetSubProperties(&effect->properties.ID2D1Properties_iface, index, props); +} + +static void STDMETHODCALLTYPE d2d_effect_SetInput(ID2D1Effect *iface, UINT32 index, ID2D1Image *input, BOOL invalidate) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, index %u, input %p, invalidate %#x.\n", iface, index, input, invalidate); + + if (index >= effect->input_count) + return; + + ID2D1Image_AddRef(input); + if (effect->inputs[index]) + ID2D1Image_Release(effect->inputs[index]); + effect->inputs[index] = input; +} + +static HRESULT d2d_effect_set_input_count(struct d2d_effect *effect, UINT32 count) +{ + bool initialized = effect->inputs != NULL; + HRESULT hr = S_OK; + unsigned int i; + + if (count == effect->input_count) + return S_OK; + + if (count < effect->input_count) + { + for (i = count; i < effect->input_count; ++i) + { + if (effect->inputs[i]) + ID2D1Image_Release(effect->inputs[i]); + } + } + else + { + if (!d2d_array_reserve((void **)&effect->inputs, &effect->inputs_size, + count, sizeof(*effect->inputs))) + { + ERR("Failed to resize inputs array.\n"); + return E_OUTOFMEMORY; + } + + memset(&effect->inputs[effect->input_count], 0, sizeof(*effect->inputs) * (count - effect->input_count)); + } + effect->input_count = count; + + if (initialized) + { + ID2D1TransformGraph_Release(&effect->graph->ID2D1TransformGraph_iface); + effect->graph = NULL; + + if (SUCCEEDED(hr = d2d_transform_graph_create(count, &effect->graph))) + { + if (FAILED(hr = ID2D1EffectImpl_SetGraph(effect->impl, &effect->graph->ID2D1TransformGraph_iface))) + WARN("Failed to set a new transform graph, hr %#lx.\n", hr); + } + } + + return hr; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_SetInputCount(ID2D1Effect *iface, UINT32 count) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + unsigned int min_inputs, max_inputs; + + TRACE("iface %p, count %u.\n", iface, count); + + d2d_effect_get_value(effect, D2D1_PROPERTY_MIN_INPUTS, D2D1_PROPERTY_TYPE_UINT32, + (BYTE *)&min_inputs, sizeof(min_inputs)); + d2d_effect_get_value(effect, D2D1_PROPERTY_MAX_INPUTS, D2D1_PROPERTY_TYPE_UINT32, + (BYTE *)&max_inputs, sizeof(max_inputs)); + + if (count < min_inputs || count > max_inputs) + return E_INVALIDARG; + + return d2d_effect_set_input_count(effect, count); +} + +static void STDMETHODCALLTYPE d2d_effect_GetInput(ID2D1Effect *iface, UINT32 index, ID2D1Image **input) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, index %u, input %p.\n", iface, index, input); + + if (index < effect->input_count && effect->inputs[index]) + ID2D1Image_AddRef(*input = effect->inputs[index]); + else + *input = NULL; +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_GetInputCount(ID2D1Effect *iface) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p.\n", iface); + + return effect->input_count; +} + +static void STDMETHODCALLTYPE d2d_effect_GetOutput(ID2D1Effect *iface, ID2D1Image **output) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, output %p.\n", iface, output); + + ID2D1Image_AddRef(*output = &effect->ID2D1Image_iface); +} + +static const ID2D1EffectVtbl d2d_effect_vtbl = +{ + d2d_effect_QueryInterface, + d2d_effect_AddRef, + d2d_effect_Release, + d2d_effect_GetPropertyCount, + d2d_effect_GetPropertyName, + d2d_effect_GetPropertyNameLength, + d2d_effect_GetType, + d2d_effect_GetPropertyIndex, + d2d_effect_SetValueByName, + d2d_effect_SetValue, + d2d_effect_GetValueByName, + d2d_effect_GetValue, + d2d_effect_GetValueSize, + d2d_effect_GetSubProperties, + d2d_effect_SetInput, + d2d_effect_SetInputCount, + d2d_effect_GetInput, + d2d_effect_GetInputCount, + d2d_effect_GetOutput, +}; + +static inline struct d2d_effect *impl_from_ID2D1Image(ID2D1Image *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_effect, ID2D1Image_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_image_QueryInterface(ID2D1Image *iface, REFIID iid, void **out) +{ + struct d2d_effect *effect = impl_from_ID2D1Image(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + return d2d_effect_QueryInterface(&effect->ID2D1Effect_iface, iid, out); +} + +static ULONG STDMETHODCALLTYPE d2d_effect_image_AddRef(ID2D1Image *iface) +{ + struct d2d_effect *effect = impl_from_ID2D1Image(iface); + + TRACE("iface %p.\n", iface); + + return d2d_effect_AddRef(&effect->ID2D1Effect_iface); +} + +static ULONG STDMETHODCALLTYPE d2d_effect_image_Release(ID2D1Image *iface) +{ + struct d2d_effect *effect = impl_from_ID2D1Image(iface); + + TRACE("iface %p.\n", iface); + + return d2d_effect_Release(&effect->ID2D1Effect_iface); +} + +static void STDMETHODCALLTYPE d2d_effect_image_GetFactory(ID2D1Image *iface, ID2D1Factory **factory) +{ + struct d2d_effect *effect = impl_from_ID2D1Image(iface); + + TRACE("iface %p, factory %p.\n", iface, factory); + + ID2D1Factory_AddRef(*factory = effect->effect_context->device_context->factory); +} + +static const ID2D1ImageVtbl d2d_effect_image_vtbl = +{ + d2d_effect_image_QueryInterface, + d2d_effect_image_AddRef, + d2d_effect_image_Release, + d2d_effect_image_GetFactory, +}; + +static inline struct d2d_effect_properties *impl_from_ID2D1Properties(ID2D1Properties *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_effect_properties, ID2D1Properties_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_QueryInterface(ID2D1Properties *iface, + REFIID riid, void **obj) +{ + if (IsEqualGUID(riid, &IID_ID2D1Properties) || + IsEqualGUID(riid, &IID_IUnknown)) + { + *obj = iface; + ID2D1Properties_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_effect_properties_AddRef(ID2D1Properties *iface) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + + if (properties->effect) + return ID2D1Effect_AddRef(&properties->effect->ID2D1Effect_iface); + + return InterlockedIncrement(&properties->refcount); +} + +static ULONG STDMETHODCALLTYPE d2d_effect_properties_Release(ID2D1Properties *iface) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + ULONG refcount; + + if (properties->effect) + return ID2D1Effect_Release(&properties->effect->ID2D1Effect_iface); + + refcount = InterlockedDecrement(&properties->refcount); + + if (!refcount) + { + d2d_effect_properties_cleanup(properties); + free(properties); + } + + return refcount; +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_properties_GetPropertyCount(ID2D1Properties *iface) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + + TRACE("iface %p.\n", iface); + + return properties->custom_count; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_GetPropertyName(ID2D1Properties *iface, + UINT32 index, WCHAR *name, UINT32 name_count) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, index %u, name %p, name_count %u.\n", iface, index, name, name_count); + + if (!(prop = d2d_effect_properties_get_property_by_index(properties, index))) + return D2DERR_INVALID_PROPERTY; + + return d2d_effect_return_string(prop->name, name, name_count); +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_properties_GetPropertyNameLength(ID2D1Properties *iface, + UINT32 index) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, index %u.\n", iface, index); + + if (!(prop = d2d_effect_properties_get_property_by_index(properties, index))) + return D2DERR_INVALID_PROPERTY; + + return wcslen(prop->name); +} + +static D2D1_PROPERTY_TYPE STDMETHODCALLTYPE d2d_effect_properties_GetType(ID2D1Properties *iface, + UINT32 index) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, index %#x.\n", iface, index); + + if (!(prop = d2d_effect_properties_get_property_by_index(properties, index))) + return D2D1_PROPERTY_TYPE_UNKNOWN; + + return prop->type; +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_properties_GetPropertyIndex(ID2D1Properties *iface, + const WCHAR *name) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, name %s.\n", iface, debugstr_w(name)); + + if (!(prop = d2d_effect_properties_get_property_by_name(properties, name))) + return D2D1_INVALID_PROPERTY_INDEX; + + return prop->index; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_SetValueByName(ID2D1Properties *iface, + const WCHAR *name, D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 value_size) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, name %s, type %u, value %p, value_size %u.\n", iface, debugstr_w(name), + type, value, value_size); + + if (!(prop = d2d_effect_properties_get_property_by_name(properties, name))) + return D2DERR_INVALID_PROPERTY; + + return d2d_effect_property_set_value(properties, prop, type, value, value_size); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_SetValue(ID2D1Properties *iface, + UINT32 index, D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 value_size) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, index %#x, type %u, value %p, value_size %u.\n", iface, index, type, value, value_size); + + if (!(prop = d2d_effect_properties_get_property_by_index(properties, index))) + return D2DERR_INVALID_PROPERTY; + + return d2d_effect_property_set_value(properties, prop, type, value, value_size); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_GetValueByName(ID2D1Properties *iface, + const WCHAR *name, D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, name %s, type %#x, value %p, value_size %u.\n", iface, debugstr_w(name), type, + value, value_size); + + if (!(prop = d2d_effect_properties_get_property_by_name(properties, name))) + return D2DERR_INVALID_PROPERTY; + + return d2d_effect_property_get_value(properties, prop, type, value, value_size); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_GetValue(ID2D1Properties *iface, + UINT32 index, D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, index %#x, type %u, value %p, value_size %u.\n", iface, index, type, value, value_size); + + if (!(prop = d2d_effect_properties_get_property_by_index(properties, index))) + return D2DERR_INVALID_PROPERTY; + + return d2d_effect_property_get_value(properties, prop, type, value, value_size); +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_properties_GetValueSize(ID2D1Properties *iface, + UINT32 index) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + + TRACE("iface %p, index %#x.\n", iface, index); + + return d2d_effect_properties_get_value_size(properties, index); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_GetSubProperties(ID2D1Properties *iface, + UINT32 index, ID2D1Properties **props) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, index %u, props %p.\n", iface, index, props); + + if (!(prop = d2d_effect_properties_get_property_by_index(properties, index))) + return D2DERR_INVALID_PROPERTY; + + if (!prop->subproperties) return D2DERR_NO_SUBPROPERTIES; + + *props = &prop->subproperties->ID2D1Properties_iface; + ID2D1Properties_AddRef(*props); + return S_OK; +} + +static const ID2D1PropertiesVtbl d2d_effect_properties_vtbl = +{ + d2d_effect_properties_QueryInterface, + d2d_effect_properties_AddRef, + d2d_effect_properties_Release, + d2d_effect_properties_GetPropertyCount, + d2d_effect_properties_GetPropertyName, + d2d_effect_properties_GetPropertyNameLength, + d2d_effect_properties_GetType, + d2d_effect_properties_GetPropertyIndex, + d2d_effect_properties_SetValueByName, + d2d_effect_properties_SetValue, + d2d_effect_properties_GetValueByName, + d2d_effect_properties_GetValue, + d2d_effect_properties_GetValueSize, + d2d_effect_properties_GetSubProperties, +}; + +void d2d_effect_init_properties(struct d2d_effect *effect, + struct d2d_effect_properties *properties) +{ + properties->ID2D1Properties_iface.lpVtbl = &d2d_effect_properties_vtbl; + properties->effect = effect; + properties->refcount = 1; +} + +static struct d2d_render_info *impl_from_ID2D1DrawInfo(ID2D1DrawInfo *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_render_info, ID2D1DrawInfo_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_QueryInterface(ID2D1DrawInfo *iface, REFIID iid, + void **obj) +{ + TRACE("iface %p, iid %s, obj %p.\n", iface, debugstr_guid(iid), obj); + + if (IsEqualGUID(iid, &IID_ID2D1DrawInfo) + || IsEqualGUID(iid, &IID_ID2D1RenderInfo) + || IsEqualGUID(iid, &IID_IUnknown)) + { + *obj = iface; + ID2D1DrawInfo_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(iid)); + + *obj = NULL; + + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_draw_info_AddRef(ID2D1DrawInfo *iface) +{ + struct d2d_render_info *render_info = impl_from_ID2D1DrawInfo(iface); + ULONG refcount = InterlockedIncrement(&render_info->refcount); + + TRACE("iface %p refcount %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_draw_info_Release(ID2D1DrawInfo *iface) +{ + struct d2d_render_info *render_info = impl_from_ID2D1DrawInfo(iface); + ULONG refcount = InterlockedDecrement(&render_info->refcount); + + TRACE("iface %p refcount %lu.\n", iface, refcount); + + if (!refcount) + free(render_info); + + return refcount; +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetInputDescription(ID2D1DrawInfo *iface, + UINT32 index, D2D1_INPUT_DESCRIPTION description) +{ + FIXME("iface %p, index %u stub.\n", iface, index); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetOutputBuffer(ID2D1DrawInfo *iface, + D2D1_BUFFER_PRECISION precision, D2D1_CHANNEL_DEPTH depth) +{ + FIXME("iface %p, precision %u, depth %u stub.\n", iface, precision, depth); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d2d_draw_info_SetCached(ID2D1DrawInfo *iface, BOOL is_cached) +{ + FIXME("iface %p, is_cached %d stub.\n", iface, is_cached); +} + +static void STDMETHODCALLTYPE d2d_draw_info_SetInstructionCountHint(ID2D1DrawInfo *iface, + UINT32 count) +{ + FIXME("iface %p, count %u stub.\n", iface, count); +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetPixelShaderConstantBuffer(ID2D1DrawInfo *iface, + const BYTE *buffer, UINT32 size) +{ + FIXME("iface %p, buffer %p, size %u stub.\n", iface, buffer, size); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetResourceTexture(ID2D1DrawInfo *iface, + UINT32 index, ID2D1ResourceTexture *texture) +{ + FIXME("iface %p, index %u, texture %p stub.\n", iface, index, texture); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetVertexShaderConstantBuffer(ID2D1DrawInfo *iface, + const BYTE *buffer, UINT32 size) +{ + FIXME("iface %p, buffer %p, size %u stub.\n", iface, buffer, size); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetPixelShader(ID2D1DrawInfo *iface, + REFGUID id, D2D1_PIXEL_OPTIONS options) +{ + struct d2d_render_info *render_info = impl_from_ID2D1DrawInfo(iface); + + TRACE("iface %p, id %s, options %u.\n", iface, debugstr_guid(id), options); + + render_info->mask |= D2D_RENDER_INFO_PIXEL_SHADER; + render_info->pixel_shader = *id; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetVertexProcessing(ID2D1DrawInfo *iface, + ID2D1VertexBuffer *buffer, D2D1_VERTEX_OPTIONS options, + const D2D1_BLEND_DESCRIPTION *description, const D2D1_VERTEX_RANGE *range, + const GUID *shader) +{ + FIXME("iface %p, buffer %p, options %#x, description %p, range %p, shader %s stub.\n", + iface, buffer, options, description, range, debugstr_guid(shader)); + + return E_NOTIMPL; +} + +static const ID2D1DrawInfoVtbl d2d_draw_info_vtbl = +{ + d2d_draw_info_QueryInterface, + d2d_draw_info_AddRef, + d2d_draw_info_Release, + d2d_draw_info_SetInputDescription, + d2d_draw_info_SetOutputBuffer, + d2d_draw_info_SetCached, + d2d_draw_info_SetInstructionCountHint, + d2d_draw_info_SetPixelShaderConstantBuffer, + d2d_draw_info_SetResourceTexture, + d2d_draw_info_SetVertexShaderConstantBuffer, + d2d_draw_info_SetPixelShader, + d2d_draw_info_SetVertexProcessing, +}; + +static HRESULT d2d_effect_render_info_create(struct d2d_render_info **obj) +{ + struct d2d_render_info *object; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID2D1DrawInfo_iface.lpVtbl = &d2d_draw_info_vtbl; + object->refcount = 1; + + *obj = object; + + return S_OK; +} + +static bool d2d_transform_node_needs_render_info(const struct d2d_transform_node *node) +{ + static const GUID *iids[] = + { + &IID_ID2D1SourceTransform, + &IID_ID2D1ComputeTransform, + &IID_ID2D1DrawTransform, + }; + unsigned int i; + IUnknown *obj; + + for (i = 0; i < ARRAY_SIZE(iids); ++i) + { + if (SUCCEEDED(ID2D1TransformNode_QueryInterface(node->object, iids[i], (void **)&obj))) + { + IUnknown_Release(obj); + return true; + } + } + + return false; +} + +static HRESULT d2d_effect_transform_graph_initialize_nodes(struct d2d_transform_graph *graph) +{ + ID2D1DrawTransform *draw_transform; + struct d2d_transform_node *node; + HRESULT hr; + + LIST_FOR_EACH_ENTRY(node, &graph->nodes, struct d2d_transform_node, entry) + { + if (d2d_transform_node_needs_render_info(node)) + { + if (FAILED(hr = d2d_effect_render_info_create(&node->render_info))) + return hr; + } + + if (SUCCEEDED(ID2D1TransformNode_QueryInterface(node->object, &IID_ID2D1DrawTransform, + (void **)&draw_transform))) + { + hr = ID2D1DrawTransform_SetDrawInfo(draw_transform, &node->render_info->ID2D1DrawInfo_iface); + ID2D1DrawTransform_Release(draw_transform); + if (FAILED(hr)) + { + WARN("Failed to set draw info, hr %#lx.\n", hr); + return hr; + } + } + else + { + FIXME("Unsupported node %p.\n", node); + return E_NOTIMPL; + } + } + + return S_OK; +} + +HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effect_id, + ID2D1Effect **effect) +{ + struct d2d_effect_context *effect_context; + const struct d2d_effect_registration *reg; + struct d2d_effect *object; + UINT32 input_count; + WCHAR clsidW[39]; + HRESULT hr; + + if (!(reg = d2d_factory_get_registered_effect(context->factory, effect_id))) + { + WARN("Effect id %s not found.\n", wine_dbgstr_guid(effect_id)); + return D2DERR_EFFECT_IS_NOT_REGISTERED; + } + + if (!(effect_context = calloc(1, sizeof(*effect_context)))) + return E_OUTOFMEMORY; + d2d_effect_context_init(effect_context, context); + + if (!(object = calloc(1, sizeof(*object)))) + { + ID2D1EffectContext_Release(&effect_context->ID2D1EffectContext_iface); + return E_OUTOFMEMORY; + } + + object->ID2D1Effect_iface.lpVtbl = &d2d_effect_vtbl; + object->ID2D1Image_iface.lpVtbl = &d2d_effect_image_vtbl; + object->refcount = 1; + object->effect_context = effect_context; + + /* Create properties */ + d2d_effect_duplicate_properties(object, &object->properties, reg->properties); + + StringFromGUID2(effect_id, clsidW, ARRAY_SIZE(clsidW)); + d2d_effect_properties_add(&object->properties, L"CLSID", D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_CLSID, clsidW); + d2d_effect_properties_add(&object->properties, L"Cached", D2D1_PROPERTY_CACHED, D2D1_PROPERTY_TYPE_BOOL, L"false"); + d2d_effect_properties_add(&object->properties, L"Precision", D2D1_PROPERTY_PRECISION, D2D1_PROPERTY_TYPE_ENUM, L"0"); + + /* Sync instance input count with default input count from the description. */ + d2d_effect_get_value(object, D2D1_PROPERTY_INPUTS, D2D1_PROPERTY_TYPE_ARRAY, (BYTE *)&input_count, sizeof(input_count)); + d2d_effect_set_input_count(object, input_count); + + if (FAILED(hr = d2d_transform_graph_create(input_count, &object->graph))) + { + ID2D1EffectContext_Release(&effect_context->ID2D1EffectContext_iface); + return hr; + } + + if (FAILED(hr = reg->factory((IUnknown **)&object->impl))) + { + WARN("Failed to create implementation object, hr %#lx.\n", hr); + ID2D1Effect_Release(&object->ID2D1Effect_iface); + return hr; + } + + if (FAILED(hr = ID2D1EffectImpl_Initialize(object->impl, &effect_context->ID2D1EffectContext_iface, + &object->graph->ID2D1TransformGraph_iface))) + { + WARN("Failed to initialize effect, hr %#lx.\n", hr); + ID2D1Effect_Release(&object->ID2D1Effect_iface); + return hr; + } + + if (FAILED(hr = d2d_effect_transform_graph_initialize_nodes(object->graph))) + { + WARN("Failed to initialize graph nodes, hr %#lx.\n", hr); + ID2D1Effect_Release(&object->ID2D1Effect_iface); + return hr; + } + + *effect = &object->ID2D1Effect_iface; + + TRACE("Created effect %p.\n", *effect); + + return S_OK; } diff --git a/wrappers/directx/wine/d2d1/factory.c b/wrappers/directx/wine/d2d1/factory.c index 5f081a1c12..954d90efc0 100644 --- a/wrappers/directx/wine/d2d1/factory.c +++ b/wrappers/directx/wine/d2d1/factory.c @@ -19,6 +19,9 @@ #define D2D1_INIT_GUID #include "d2d1_private.h" +#include "xmllite.h" +#include "wine/list.h" + WINE_DECLARE_DEBUG_CHANNEL(winediag); WINE_DEFAULT_DEBUG_CHANNEL(d2d); @@ -27,28 +30,53 @@ struct d2d_settings d2d_settings = ~0u, /* No ID2D1Factory version limit by default. */ }; -struct d2d_factory +static void d2d_effect_registration_cleanup(struct d2d_effect_registration *reg) { - ID2D1Factory2 ID2D1Factory2_iface; - ID2D1Multithread ID2D1Multithread_iface; - LONG refcount; + ID2D1Properties_Release(®->properties->ID2D1Properties_iface); + free(reg); +} - ID3D10Device1 *device; +static inline struct d2d_factory *impl_from_ID2D1Factory7(ID2D1Factory7 *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_factory, ID2D1Factory7_iface); +} - float dpi_x; - float dpi_y; +static inline struct d2d_factory *impl_from_ID2D1Multithread(ID2D1Multithread *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_factory, ID2D1Multithread_iface); +} - CRITICAL_SECTION cs; -}; +static BOOL WINAPI d2d_factory_builtins_initonce(INIT_ONCE *once, void *param, void **context) +{ + d2d_effects_init_builtins(param); -static inline struct d2d_factory *impl_from_ID2D1Factory2(ID2D1Factory2 *iface) + return TRUE; +} + +static void d2d_factory_init_builtin_effects(struct d2d_factory *factory) { - return CONTAINING_RECORD(iface, struct d2d_factory, ID2D1Factory2_iface); + InitOnceExecuteOnce(&factory->init_builtins, d2d_factory_builtins_initonce, factory, NULL); } -static inline struct d2d_factory *impl_from_ID2D1Multithread(ID2D1Multithread *iface) +void d2d_factory_register_effect(struct d2d_factory *factory, struct d2d_effect_registration *effect) { - return CONTAINING_RECORD(iface, struct d2d_factory, ID2D1Multithread_iface); + list_add_tail(&factory->effects, &effect->entry); +} + +struct d2d_effect_registration * d2d_factory_get_registered_effect(ID2D1Factory *iface, + const GUID *id) +{ + struct d2d_factory *factory = unsafe_impl_from_ID2D1Factory(iface); + struct d2d_effect_registration *reg; + + d2d_factory_init_builtin_effects(factory); + + LIST_FOR_EACH_ENTRY(reg, &factory->effects, struct d2d_effect_registration, entry) + { + if (IsEqualGUID(id, ®->id)) return reg; + } + + return NULL; } static HRESULT d2d_factory_reload_sysmetrics(struct d2d_factory *factory) @@ -69,24 +97,29 @@ static HRESULT d2d_factory_reload_sysmetrics(struct d2d_factory *factory) return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_QueryInterface(ID2D1Factory2 *iface, REFIID iid, void **out) +static HRESULT STDMETHODCALLTYPE d2d_factory_QueryInterface(ID2D1Factory7 *iface, REFIID iid, void **out) { - struct d2d_factory *factory = impl_from_ID2D1Factory2(iface); + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); - if ((IsEqualGUID(iid, &IID_ID2D1Factory2) && d2d_settings.max_version_factory >= 2) + if ((IsEqualGUID(iid, &IID_ID2D1Factory7) && d2d_settings.max_version_factory >= 7) + || (IsEqualGUID(iid, &IID_ID2D1Factory6) && d2d_settings.max_version_factory >= 6) + || (IsEqualGUID(iid, &IID_ID2D1Factory5) && d2d_settings.max_version_factory >= 5) + || (IsEqualGUID(iid, &IID_ID2D1Factory4) && d2d_settings.max_version_factory >= 4) + || (IsEqualGUID(iid, &IID_ID2D1Factory3) && d2d_settings.max_version_factory >= 3) + || (IsEqualGUID(iid, &IID_ID2D1Factory2) && d2d_settings.max_version_factory >= 2) || (IsEqualGUID(iid, &IID_ID2D1Factory1) && d2d_settings.max_version_factory >= 1) || IsEqualGUID(iid, &IID_ID2D1Factory) || IsEqualGUID(iid, &IID_IUnknown)) { - ID2D1Factory2_AddRef(iface); + ID2D1Factory7_AddRef(iface); *out = iface; return S_OK; } else if (IsEqualGUID(iid, &IID_ID2D1Multithread)) { - ID2D1Factory2_AddRef(iface); + ID2D1Factory7_AddRef(iface); *out = &factory->ID2D1Multithread_iface; return S_OK; } @@ -97,46 +130,51 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_QueryInterface(ID2D1Factory2 *iface return E_NOINTERFACE; } -static ULONG STDMETHODCALLTYPE d2d_factory_AddRef(ID2D1Factory2 *iface) +static ULONG STDMETHODCALLTYPE d2d_factory_AddRef(ID2D1Factory7 *iface) { - struct d2d_factory *factory = impl_from_ID2D1Factory2(iface); + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); ULONG refcount = InterlockedIncrement(&factory->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } -static ULONG STDMETHODCALLTYPE d2d_factory_Release(ID2D1Factory2 *iface) +static ULONG STDMETHODCALLTYPE d2d_factory_Release(ID2D1Factory7 *iface) { - struct d2d_factory *factory = impl_from_ID2D1Factory2(iface); + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); ULONG refcount = InterlockedDecrement(&factory->refcount); + struct d2d_effect_registration *reg, *reg2; - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { if (factory->device) ID3D10Device1_Release(factory->device); + LIST_FOR_EACH_ENTRY_SAFE(reg, reg2, &factory->effects, struct d2d_effect_registration, entry) + { + d2d_effect_registration_cleanup(reg); + } DeleteCriticalSection(&factory->cs); - heap_free(factory); + free(factory); } return refcount; } -static HRESULT STDMETHODCALLTYPE d2d_factory_ReloadSystemMetrics(ID2D1Factory2 *iface) +static HRESULT STDMETHODCALLTYPE d2d_factory_ReloadSystemMetrics(ID2D1Factory7 *iface) { - struct d2d_factory *factory = impl_from_ID2D1Factory2(iface); + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); TRACE("iface %p.\n", iface); return d2d_factory_reload_sysmetrics(factory); } -static void STDMETHODCALLTYPE d2d_factory_GetDesktopDpi(ID2D1Factory2 *iface, float *dpi_x, float *dpi_y) +static void STDMETHODCALLTYPE d2d_factory_GetDesktopDpi(ID2D1Factory7 *iface, float *dpi_x, float *dpi_y) { - struct d2d_factory *factory = impl_from_ID2D1Factory2(iface); + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y); @@ -144,7 +182,7 @@ static void STDMETHODCALLTYPE d2d_factory_GetDesktopDpi(ID2D1Factory2 *iface, fl *dpi_y = factory->dpi_y; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRectangleGeometry(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRectangleGeometry(ID2D1Factory7 *iface, const D2D1_RECT_F *rect, ID2D1RectangleGeometry **geometry) { struct d2d_geometry *object; @@ -152,13 +190,13 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRectangleGeometry(ID2D1Factor TRACE("iface %p, rect %s, geometry %p.\n", iface, debug_d2d_rect_f(rect), geometry); - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; if (FAILED(hr = d2d_rectangle_geometry_init(object, (ID2D1Factory *)iface, rect))) { - WARN("Failed to initialize rectangle geometry, hr %#x.\n", hr); - heap_free(object); + WARN("Failed to initialise rectangle geometry, hr %#lx.\n", hr); + free(object); return hr; } @@ -168,7 +206,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRectangleGeometry(ID2D1Factor return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRoundedRectangleGeometry(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRoundedRectangleGeometry(ID2D1Factory7 *iface, const D2D1_ROUNDED_RECT *rounded_rect, ID2D1RoundedRectangleGeometry **geometry) { struct d2d_geometry *object; @@ -176,13 +214,13 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRoundedRectangleGeometry(ID2D TRACE("iface %p, rounded_rect %s, geometry %p.\n", iface, debug_d2d_rounded_rect(rounded_rect), geometry); - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; if (FAILED(hr = d2d_rounded_rectangle_geometry_init(object, (ID2D1Factory *)iface, rounded_rect))) { - WARN("Failed to initialize rounded rectangle geometry, hr %#x.\n", hr); - heap_free(object); + WARN("Failed to initialise rounded rectangle geometry, hr %#lx.\n", hr); + free(object); return hr; } @@ -192,7 +230,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRoundedRectangleGeometry(ID2D return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateEllipseGeometry(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateEllipseGeometry(ID2D1Factory7 *iface, const D2D1_ELLIPSE *ellipse, ID2D1EllipseGeometry **geometry) { struct d2d_geometry *object; @@ -200,13 +238,13 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateEllipseGeometry(ID2D1Factory2 TRACE("iface %p, ellipse %s, geometry %p.\n", iface, debug_d2d_ellipse(ellipse), geometry); - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; if (FAILED(hr = d2d_ellipse_geometry_init(object, (ID2D1Factory *)iface, ellipse))) { - WARN("Failed to initialize ellipse geometry, hr %#x.\n", hr); - heap_free(object); + WARN("Failed to initialise ellipse geometry, hr %#lx.\n", hr); + free(object); return hr; } @@ -216,7 +254,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateEllipseGeometry(ID2D1Factory2 return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateGeometryGroup(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateGeometryGroup(ID2D1Factory7 *iface, D2D1_FILL_MODE fill_mode, ID2D1Geometry **geometries, UINT32 geometry_count, ID2D1GeometryGroup **group) { struct d2d_geometry *object; @@ -225,13 +263,13 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateGeometryGroup(ID2D1Factory2 * TRACE("iface %p, fill_mode %#x, geometries %p, geometry_count %u, group %p.\n", iface, fill_mode, geometries, geometry_count, group); - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; if (FAILED(hr = d2d_geometry_group_init(object, (ID2D1Factory *)iface, fill_mode, geometries, geometry_count))) { - WARN("Failed to initialize geometry group, hr %#x.\n", hr); - heap_free(object); + WARN("Failed to initialise geometry group, hr %#lx.\n", hr); + free(object); return hr; } @@ -241,7 +279,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateGeometryGroup(ID2D1Factory2 * return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateTransformedGeometry(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateTransformedGeometry(ID2D1Factory7 *iface, ID2D1Geometry *src_geometry, const D2D1_MATRIX_3X2_F *transform, ID2D1TransformedGeometry **transformed_geometry) { @@ -250,7 +288,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateTransformedGeometry(ID2D1Fact TRACE("iface %p, src_geometry %p, transform %p, transformed_geometry %p.\n", iface, src_geometry, transform, transformed_geometry); - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; d2d_transformed_geometry_init(object, (ID2D1Factory *)iface, src_geometry, transform); @@ -261,13 +299,14 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateTransformedGeometry(ID2D1Fact return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreatePathGeometry(ID2D1Factory2 *iface, ID2D1PathGeometry **geometry) +static HRESULT STDMETHODCALLTYPE d2d_factory_CreatePathGeometry(ID2D1Factory7 *iface, + ID2D1PathGeometry **geometry) { struct d2d_geometry *object; TRACE("iface %p, geometry %p.\n", iface, geometry); - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; d2d_path_geometry_init(object, (ID2D1Factory *)iface); @@ -278,33 +317,43 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreatePathGeometry(ID2D1Factory2 *i return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateStrokeStyle(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateStrokeStyle(ID2D1Factory7 *iface, const D2D1_STROKE_STYLE_PROPERTIES *desc, const float *dashes, UINT32 dash_count, ID2D1StrokeStyle **stroke_style) { struct d2d_stroke_style *object; + D2D1_STROKE_STYLE_PROPERTIES1 desc1; HRESULT hr; TRACE("iface %p, desc %p, dashes %p, dash_count %u, stroke_style %p.\n", iface, desc, dashes, dash_count, stroke_style); - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; - if (FAILED(hr = d2d_stroke_style_init(object, (ID2D1Factory *)iface, desc, dashes, dash_count))) + desc1.startCap = desc->startCap; + desc1.endCap = desc->endCap; + desc1.dashCap = desc->dashCap; + desc1.lineJoin = desc->lineJoin; + desc1.miterLimit = desc->miterLimit; + desc1.dashStyle = desc->dashStyle; + desc1.dashOffset = desc->dashOffset; + desc1.transformType = D2D1_STROKE_TRANSFORM_TYPE_NORMAL; + + if (FAILED(hr = d2d_stroke_style_init(object, (ID2D1Factory *)iface, &desc1, dashes, dash_count))) { - WARN("Failed to initialize stroke style, hr %#x.\n", hr); - heap_free(object); + WARN("Failed to initialise stroke style, hr %#lx.\n", hr); + free(object); return hr; } TRACE("Created stroke style %p.\n", object); - *stroke_style = &object->ID2D1StrokeStyle_iface; + *stroke_style = (ID2D1StrokeStyle *)&object->ID2D1StrokeStyle1_iface; return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock(ID2D1Factory7 *iface, const D2D1_DRAWING_STATE_DESCRIPTION *desc, IDWriteRenderingParams *text_rendering_params, ID2D1DrawingStateBlock **state_block) { @@ -314,7 +363,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock(ID2D1Factor TRACE("iface %p, desc %p, text_rendering_params %p, state_block %p.\n", iface, desc, text_rendering_params, state_block); - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; if (desc) @@ -338,35 +387,35 @@ static HRESULT d2d_factory_get_device(struct d2d_factory *factory, ID3D10Device1 if (!factory->device && FAILED(hr = D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &factory->device))) - WARN("Failed to create device, hr %#x.\n", hr); + WARN("Failed to create device, hr %#lx.\n", hr); *device = factory->device; return hr; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateWicBitmapRenderTarget(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateWicBitmapRenderTarget(ID2D1Factory7 *iface, IWICBitmap *target, const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target) { - struct d2d_factory *factory = impl_from_ID2D1Factory2(iface); + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); struct d2d_wic_render_target *object; ID3D10Device1 *device; HRESULT hr; TRACE("iface %p, target %p, desc %p, render_target %p.\n", iface, target, desc, render_target); - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; if (FAILED(hr = d2d_factory_get_device(factory, &device))) { - heap_free(object); + free(object); return hr; } if (FAILED(hr = d2d_wic_render_target_init(object, (ID2D1Factory1 *)iface, device, target, desc))) { - WARN("Failed to initialize render target, hr %#x.\n", hr); - heap_free(object); + WARN("Failed to initialise render target, hr %#lx.\n", hr); + free(object); return hr; } @@ -376,11 +425,11 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateWicBitmapRenderTarget(ID2D1Fa return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory7 *iface, const D2D1_RENDER_TARGET_PROPERTIES *desc, const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_rt_desc, ID2D1HwndRenderTarget **render_target) { - struct d2d_factory *factory = impl_from_ID2D1Factory2(iface); + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); struct d2d_hwnd_render_target *object; ID3D10Device1 *device; HRESULT hr; @@ -390,13 +439,13 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory if (FAILED(hr = d2d_factory_get_device(factory, &device))) return hr; - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; if (FAILED(hr = d2d_hwnd_render_target_init(object, (ID2D1Factory1 *)iface, device, desc, hwnd_rt_desc))) { - WARN("Failed to initialize render target, hr %#x.\n", hr); - heap_free(object); + WARN("Failed to initialise render target, hr %#lx.\n", hr); + free(object); return hr; } @@ -406,7 +455,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1Factory7 *iface, IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target) { IDXGIDevice *dxgi_device; @@ -417,7 +466,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1 if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_IDXGIDevice, (void **)&dxgi_device))) { - WARN("Failed to get DXGI device, hr %#x.\n", hr); + WARN("Failed to get DXGI device, hr %#lx.\n", hr); return hr; } @@ -425,19 +474,20 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1 IDXGIDevice_Release(dxgi_device); if (FAILED(hr)) { - WARN("Failed to create D2D device, hr %#x.\n", hr); + WARN("Failed to create D2D device, hr %#lx.\n", hr); return hr; } - hr = d2d_d3d_create_render_target(device, surface, NULL, NULL, desc, (void **)render_target); + hr = d2d_d3d_create_render_target(unsafe_impl_from_ID2D1Device((ID2D1Device1 *)device), surface, + NULL, NULL, desc, (void **)render_target); ID2D1Device_Release(device); return hr; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory7 *iface, const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1DCRenderTarget **render_target) { - struct d2d_factory *factory = impl_from_ID2D1Factory2(iface); + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); struct d2d_dc_render_target *object; ID3D10Device1 *device; HRESULT hr; @@ -447,13 +497,13 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory2 if (FAILED(hr = d2d_factory_get_device(factory, &device))) return hr; - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; if (FAILED(hr = d2d_dc_render_target_init(object, (ID2D1Factory1 *)iface, device, desc))) { - WARN("Failed to initialize render target, hr %#x.\n", hr); - heap_free(object); + WARN("Failed to initialise render target, hr %#lx.\n", hr); + free(object); return hr; } @@ -463,42 +513,81 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory2 return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDevice(ID2D1Factory2 *iface, - IDXGIDevice *dxgi_device, ID2D1Device **device) +static HRESULT d2d_factory_create_device(struct d2d_factory *factory, IDXGIDevice *dxgi_device, + REFIID iid, void **device) { struct d2d_device *object; + HRESULT hr; - TRACE("iface %p, dxgi_device %p, device %p.\n", iface, dxgi_device, device); - - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; - d2d_device_init(object, (ID2D1Factory1 *)iface, dxgi_device); + d2d_device_init(object, factory, dxgi_device); TRACE("Create device %p.\n", object); - *device = &object->ID2D1Device_iface; - return S_OK; + hr = ID2D1Device6_QueryInterface(&object->ID2D1Device6_iface, iid, device); + ID2D1Device6_Release(&object->ID2D1Device6_iface); + + return hr; +} + +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDevice(ID2D1Factory7 *iface, + IDXGIDevice *dxgi_device, ID2D1Device **device) +{ + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); + + TRACE("iface %p, dxgi_device %p, device %p.\n", iface, dxgi_device, device); + + return d2d_factory_create_device(factory, dxgi_device, &IID_ID2D1Device, (void **)device); } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateStrokeStyle1(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateStrokeStyle1(ID2D1Factory7 *iface, const D2D1_STROKE_STYLE_PROPERTIES1 *desc, const float *dashes, UINT32 dash_count, ID2D1StrokeStyle1 **stroke_style) { - FIXME("iface %p, desc %p, dashes %p, dash_count %u, stroke_style %p stub!\n", + struct d2d_stroke_style *object; + HRESULT hr; + + TRACE("iface %p, desc %p, dashes %p, dash_count %u, stroke_style %p.\n", iface, desc, dashes, dash_count, stroke_style); - return E_NOTIMPL; + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d2d_stroke_style_init(object, (ID2D1Factory *)iface, + desc, dashes, dash_count))) + { + WARN("Failed to initialise stroke style, hr %#lx.\n", hr); + free(object); + return hr; + } + + TRACE("Created stroke style %p.\n", object); + *stroke_style = &object->ID2D1StrokeStyle1_iface; + + return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreatePathGeometry1(ID2D1Factory2 *iface, ID2D1PathGeometry1 **geometry) +static HRESULT STDMETHODCALLTYPE d2d_factory_CreatePathGeometry1(ID2D1Factory7 *iface, + ID2D1PathGeometry1 **geometry) { - FIXME("iface %p, geometry %p stub!\n", iface, geometry); + struct d2d_geometry *object; - return E_NOTIMPL; + TRACE("iface %p, geometry %p.\n", iface, geometry); + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + d2d_path_geometry_init(object, (ID2D1Factory *)iface); + + TRACE("Created path geometry %p.\n", object); + *geometry = (ID2D1PathGeometry1 *)&object->ID2D1Geometry_iface; + + return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock1(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock1(ID2D1Factory7 *iface, const D2D1_DRAWING_STATE_DESCRIPTION1 *desc, IDWriteRenderingParams *text_rendering_params, ID2D1DrawingStateBlock1 **state_block) { @@ -507,7 +596,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock1(ID2D1Facto TRACE("iface %p, desc %p, text_rendering_params %p, state_block %p.\n", iface, desc, text_rendering_params, state_block); - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; d2d_state_block_init(object, (ID2D1Factory *)iface, desc, text_rendering_params); @@ -518,7 +607,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock1(ID2D1Facto return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateGdiMetafile(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateGdiMetafile(ID2D1Factory7 *iface, IStream *stream, ID2D1GdiMetafile **metafile) { FIXME("iface %p, stream %p, metafile %p stub!\n", iface, stream, metafile); @@ -526,59 +615,638 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateGdiMetafile(ID2D1Factory2 *if return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromStream(ID2D1Factory2 *iface, +static HRESULT parse_effect_get_next_xml_node(IXmlReader *reader, XmlNodeType expected_type, + const WCHAR *expected_name, unsigned int *depth) +{ + const WCHAR *node_name; + XmlNodeType node_type; + HRESULT hr; + + assert(expected_type != XmlNodeType_Whitespace); + + while ((hr = IXmlReader_Read(reader, &node_type)) == S_OK) + { + if (node_type == XmlNodeType_Whitespace) + continue; + + if (expected_type != XmlNodeType_None && node_type != expected_type) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + if (expected_name) + { + if (FAILED(hr = IXmlReader_GetLocalName(reader, &node_name, NULL))) + return hr; + + if (wcscmp(node_name, expected_name)) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + } + + if (depth) + IXmlReader_GetDepth(reader, depth); + return S_OK; + } + + return hr; +} + +static HRESULT parse_effect_skip_element(IXmlReader *reader, unsigned int element_depth) +{ + XmlNodeType node_type; + unsigned int depth; + HRESULT hr; + + if (IXmlReader_IsEmptyElement(reader)) return S_OK; + + while ((hr = IXmlReader_Read(reader, &node_type)) == S_OK) + { + IXmlReader_GetDepth(reader, &depth); + if (node_type == XmlNodeType_EndElement && depth == element_depth + 1) + { + return S_OK; + } + } + + return hr; +} + +static HRESULT parse_effect_get_attribute(IXmlReader *reader, const WCHAR *name, WCHAR **ret) +{ + const WCHAR *value; + + *ret = NULL; + + if (IXmlReader_MoveToAttributeByName(reader, name, NULL) != S_OK) + return E_INVALIDARG; + if (IXmlReader_GetValue(reader, &value, NULL) != S_OK) + return E_INVALIDARG; + if (!(*ret = wcsdup(value))) + return E_OUTOFMEMORY; + + return S_OK; +} + +static HRESULT parse_effect_get_property_type(IXmlReader *reader, D2D1_PROPERTY_TYPE *type) +{ + static const WCHAR *types[] = + { + [D2D1_PROPERTY_TYPE_UNKNOWN] = L"", + [D2D1_PROPERTY_TYPE_STRING] = L"string", + [D2D1_PROPERTY_TYPE_BOOL] = L"bool", + [D2D1_PROPERTY_TYPE_UINT32] = L"uint32", + [D2D1_PROPERTY_TYPE_INT32] = L"int32", + [D2D1_PROPERTY_TYPE_FLOAT] = L"float", + [D2D1_PROPERTY_TYPE_VECTOR2] = L"vector2", + [D2D1_PROPERTY_TYPE_VECTOR3] = L"vector3", + [D2D1_PROPERTY_TYPE_VECTOR4] = L"vector4", + [D2D1_PROPERTY_TYPE_BLOB] = L"blob", + [D2D1_PROPERTY_TYPE_IUNKNOWN] = L"iunknown", + [D2D1_PROPERTY_TYPE_ENUM] = L"enum", + [D2D1_PROPERTY_TYPE_ARRAY] = L"array", + [D2D1_PROPERTY_TYPE_CLSID] = L"clsid", + [D2D1_PROPERTY_TYPE_MATRIX_3X2] = L"matrix3x2", + [D2D1_PROPERTY_TYPE_MATRIX_4X3] = L"matrix4x3", + [D2D1_PROPERTY_TYPE_MATRIX_4X4] = L"matrix4x4", + [D2D1_PROPERTY_TYPE_MATRIX_5X4] = L"matrix5x4", + [D2D1_PROPERTY_TYPE_COLOR_CONTEXT] = L"colorcontext", + }; + unsigned int i; + WCHAR *value; + HRESULT hr; + + if (FAILED(hr = parse_effect_get_attribute(reader, L"type", &value))) return hr; + + *type = D2D1_PROPERTY_TYPE_UNKNOWN; + + for (i = 0; i < ARRAY_SIZE(types); ++i) + { + if (!wcscmp(value, types[i])) + { + *type = i; + break; + } + } + + free(value); + + return *type == D2D1_PROPERTY_TYPE_UNKNOWN ? E_INVALIDARG : S_OK; +} + +static struct d2d_effect_property * parse_effect_get_property(const struct d2d_effect_registration *effect, + const WCHAR *name) +{ + unsigned int i; + + for (i = 0; i < effect->properties->count; ++i) + { + if (!wcscmp(name, effect->properties->properties[i].name)) + return &effect->properties->properties[i]; + } + + return NULL; +} + +static UINT32 parse_effect_get_property_index(struct d2d_effect_properties *props, + const WCHAR *name) +{ + if (!wcscmp(name, L"DisplayName")) return D2D1_PROPERTY_DISPLAYNAME; + if (!wcscmp(name, L"Author")) return D2D1_PROPERTY_AUTHOR; + if (!wcscmp(name, L"Category")) return D2D1_PROPERTY_CATEGORY; + if (!wcscmp(name, L"Description")) return D2D1_PROPERTY_DESCRIPTION; + return props->custom_count; +} + +static HRESULT parse_effect_property(IXmlReader *reader, struct d2d_effect_registration *effect) +{ + WCHAR *name = NULL, *value = NULL; + D2D1_PROPERTY_TYPE type; + unsigned int depth; + UINT32 index; + HRESULT hr; + + if (FAILED(hr = parse_effect_get_attribute(reader, L"name", &name))) + return hr; + + if (FAILED(hr = parse_effect_get_property_type(reader, &type))) + { + free(name); + return hr; + } + + /* Check for duplicates. */ + if (parse_effect_get_property(effect, name)) + hr = E_INVALIDARG; + + parse_effect_get_attribute(reader, L"value", &value); + + if (SUCCEEDED(hr)) + { + /* FIXME: sub properties are ignored */ + IXmlReader_MoveToElement(reader); + IXmlReader_GetDepth(reader, &depth); + hr = parse_effect_skip_element(reader, depth); + } + + if (SUCCEEDED(hr)) + { + index = parse_effect_get_property_index(effect->properties, name); + hr = d2d_effect_properties_add(effect->properties, name, index, type, value); + } + + free(value); + free(name); + + return hr; +} + +static HRESULT parse_effect_inputs(IXmlReader *reader, struct d2d_effect_registration *effect) +{ + struct d2d_effect_property *inputs, *min_inputs, *max_inputs; + struct d2d_effect_properties *subproperties; + UINT32 min_inputs_value, max_inputs_value; + unsigned int depth, input_count = 0; + XmlNodeType node_type; + WCHAR *name, *value; + WCHAR buffW[16]; + HRESULT hr; + + if (FAILED(hr = d2d_effect_properties_add(effect->properties, L"Inputs", + D2D1_PROPERTY_INPUTS, D2D1_PROPERTY_TYPE_ARRAY, NULL))) + return hr; + + if (!(inputs = d2d_effect_properties_get_property_by_name(effect->properties, L"Inputs"))) + return E_FAIL; + if (!(inputs->subproperties = calloc(1, sizeof(*inputs->subproperties)))) + return E_OUTOFMEMORY; + d2d_effect_init_properties(NULL, inputs->subproperties); + subproperties = inputs->subproperties; + + d2d_effect_subproperties_add(subproperties, L"IsReadOnly", D2D1_SUBPROPERTY_ISREADONLY, + D2D1_PROPERTY_TYPE_BOOL, L"true"); + d2d_effect_subproperties_add(subproperties, L"DisplayName", D2D1_SUBPROPERTY_DISPLAYNAME, + D2D1_PROPERTY_TYPE_STRING, L"Inputs"); + + if (SUCCEEDED(parse_effect_get_attribute(reader, L"minimum", &value))) + { + hr = d2d_effect_properties_add(effect->properties, L"MinInputs", D2D1_PROPERTY_MIN_INPUTS, + D2D1_PROPERTY_TYPE_UINT32, value); + free(value); + if (FAILED(hr)) return hr; + } + if (SUCCEEDED(parse_effect_get_attribute(reader, L"maximum", &value))) + { + hr = d2d_effect_properties_add(effect->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS, + D2D1_PROPERTY_TYPE_UINT32, value); + free(value); + if (FAILED(hr)) return hr; + } + + min_inputs = d2d_effect_properties_get_property_by_name(effect->properties, L"MinInputs"); + max_inputs = d2d_effect_properties_get_property_by_name(effect->properties, L"MaxInputs"); + + if (!IXmlReader_IsEmptyElement(reader)) + { + while (parse_effect_get_next_xml_node(reader, XmlNodeType_None, L"Input", &depth) == S_OK) + { + if (FAILED(hr = IXmlReader_GetNodeType(reader, &node_type))) return hr; + if (node_type == XmlNodeType_EndElement) continue; + if (node_type != XmlNodeType_Element) return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + if (FAILED(hr = parse_effect_get_attribute(reader, L"name", &name))) return hr; + + swprintf(buffW, ARRAY_SIZE(buffW), L"%lu", input_count); + d2d_effect_subproperties_add(subproperties, buffW, input_count, D2D1_PROPERTY_TYPE_STRING, name); + input_count++; + + free(name); + } + *(UINT32 *)(effect->properties->data.ptr + inputs->data.offset) = input_count; + + if (FAILED(hr = IXmlReader_GetNodeType(reader, &node_type))) return hr; + if (node_type != XmlNodeType_EndElement) return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + } + + if (min_inputs) + d2d_effect_property_get_uint32_value(effect->properties, min_inputs, &min_inputs_value); + if (max_inputs) + d2d_effect_property_get_uint32_value(effect->properties, max_inputs, &max_inputs_value); + + /* Validate the range */ + if (min_inputs && max_inputs) + { + if (min_inputs_value > max_inputs_value) + { + WARN("Invalid input count range %u - %u.\n", min_inputs_value, max_inputs_value); + return E_INVALIDARG; + } + } + + /* Validate actual input count with specified range. */ + if (min_inputs && min_inputs_value > input_count) + { + WARN("Too few inputs were declared, expected at least %u.\n", min_inputs_value); + return E_INVALIDARG; + } + + if (max_inputs && max_inputs_value < input_count) + { + WARN("Too many inputs were declared, expected at most %u.\n", max_inputs_value); + return E_INVALIDARG; + } + + /* Apply default value to a missing property. If both properties are missing, add them. */ + if (min_inputs != max_inputs) + { + swprintf(buffW, ARRAY_SIZE(buffW), L"%lu", min_inputs ? min_inputs_value : max_inputs_value); + if (min_inputs) + hr = d2d_effect_properties_add(effect->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS, D2D1_PROPERTY_TYPE_UINT32, buffW); + else + hr = d2d_effect_properties_add(effect->properties, L"MinInputs", D2D1_PROPERTY_MIN_INPUTS, D2D1_PROPERTY_TYPE_UINT32, buffW); + } + else if (!min_inputs) + { + swprintf(buffW, ARRAY_SIZE(buffW), L"%lu", input_count); + hr = d2d_effect_properties_add(effect->properties, L"MinInputs", D2D1_PROPERTY_MIN_INPUTS, D2D1_PROPERTY_TYPE_UINT32, buffW); + if (SUCCEEDED(hr)) + hr = d2d_effect_properties_add(effect->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS, D2D1_PROPERTY_TYPE_UINT32, buffW); + } + + return hr; +} + +static HRESULT parse_effect_xml(IXmlReader *reader, struct d2d_effect_registration *effect) +{ + const WCHAR *node_name; + XmlNodeType node_type; + unsigned int depth; + HRESULT hr; + + /* Xml declaration node is mandatory. */ + if ((hr = parse_effect_get_next_xml_node(reader, XmlNodeType_XmlDeclaration, L"xml", NULL)) != S_OK) + return hr; + + /* Top level "Effect" element. */ + if ((hr = parse_effect_get_next_xml_node(reader, XmlNodeType_Element, L"Effect", NULL)) != S_OK) + return hr; + + /* Loop inside effect node */ + while ((hr = parse_effect_get_next_xml_node(reader, XmlNodeType_None, NULL, &depth)) == S_OK) + { + if (FAILED(hr = IXmlReader_GetNodeType(reader, &node_type))) return hr; + if (node_type != XmlNodeType_Element && node_type != XmlNodeType_EndElement) continue; + if (FAILED(hr = IXmlReader_GetLocalName(reader, &node_name, NULL))) return hr; + if (node_type == XmlNodeType_EndElement) break; + + if (!wcscmp(node_name, L"Property")) + hr = parse_effect_property(reader, effect); + else if (!wcscmp(node_name, L"Inputs")) + hr = parse_effect_inputs(reader, effect); + else + { + WARN("Unexpected element %s.\n", debugstr_w(node_name)); + hr = parse_effect_skip_element(reader, depth); + } + + if (FAILED(hr)) + return hr; + } + + return hr; +} + +static HRESULT d2d_factory_register_effect_from_stream(struct d2d_factory *factory, + REFCLSID effect_id, IStream *property_xml, const D2D1_PROPERTY_BINDING *bindings, + UINT32 binding_count, PD2D1_EFFECT_FACTORY effect_factory, BOOL builtin) +{ + struct d2d_effect_registration *effect; + IXmlReader *reader; + unsigned int i; + HRESULT hr; + + LIST_FOR_EACH_ENTRY_REV(effect, &factory->effects, struct d2d_effect_registration, entry) + { + if (IsEqualGUID(effect_id, &effect->id)) + { + if (effect->builtin) return E_INVALIDARG; + ++effect->registration_count; + return S_OK; + } + } + + if (FAILED(hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL))) + return hr; + + if (FAILED(hr = IXmlReader_SetInput(reader, (IUnknown *)property_xml))) + { + IXmlReader_Release(reader); + return hr; + } + + if (!(effect = calloc(1, sizeof(*effect)))) + { + IXmlReader_Release(reader); + return E_OUTOFMEMORY; + } + if (!(effect->properties = calloc(1, sizeof(*effect->properties)))) + { + IXmlReader_Release(reader); + free(effect); + return E_OUTOFMEMORY; + } + d2d_effect_init_properties(NULL, effect->properties); + effect->builtin = builtin; + + hr = parse_effect_xml(reader, effect); + IXmlReader_Release(reader); + if (FAILED(hr)) + { + WARN("Failed to parse effect xml, hr %#lx.\n", hr); + d2d_effect_registration_cleanup(effect); + return hr; + } + + /* Check required properties. */ + if (!parse_effect_get_property(effect, L"DisplayName") + || !parse_effect_get_property(effect, L"Author") + || !parse_effect_get_property(effect, L"Category") + || !parse_effect_get_property(effect, L"Description") + || !parse_effect_get_property(effect, L"Inputs")) + { + WARN("Missing required properties.\n"); + d2d_effect_registration_cleanup(effect); + return E_INVALIDARG; + } + + /* Bind getter and setter. */ + for (i = 0; i < binding_count; ++i) + { + struct d2d_effect_property *property; + + if (!(property = parse_effect_get_property(effect, bindings[i].propertyName))) + { + WARN("Failed to bind to missing property.\n"); + d2d_effect_registration_cleanup(effect); + return D2DERR_INVALID_PROPERTY; + } + + property->get_function = bindings[i].getFunction; + property->set_function = bindings[i].setFunction; + } + + effect->registration_count = 1; + effect->id = *effect_id; + effect->factory = effect_factory; + + d2d_factory_register_effect(factory, effect); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromStream(ID2D1Factory7 *iface, REFCLSID effect_id, IStream *property_xml, const D2D1_PROPERTY_BINDING *bindings, UINT32 binding_count, PD2D1_EFFECT_FACTORY effect_factory) { - FIXME("iface %p, effect_id %s, property_xml %p, bindings %p, binding_count %u, effect_factory %p stub!\n", + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); + + TRACE("iface %p, effect_id %s, property_xml %p, bindings %p, binding_count %u, effect_factory %p.\n", iface, debugstr_guid(effect_id), property_xml, bindings, binding_count, effect_factory); - return E_NOTIMPL; + d2d_factory_init_builtin_effects(factory); + + return d2d_factory_register_effect_from_stream(factory, effect_id, property_xml, bindings, + binding_count, effect_factory, FALSE); +} + +static HRESULT d2d_factory_register_effect_from_string(struct d2d_factory *factory, + REFCLSID effect_id, const WCHAR *property_xml, const D2D1_PROPERTY_BINDING *bindings, + UINT32 binding_count, PD2D1_EFFECT_FACTORY effect_factory, BOOL builtin) +{ + static const LARGE_INTEGER zero; + IStream *stream; + ULONG size; + HRESULT hr; + + if (FAILED(hr = CreateStreamOnHGlobal(NULL, TRUE, &stream))) + return hr; + + size = sizeof(*property_xml) * (wcslen(property_xml) + 1); + if (SUCCEEDED(hr = IStream_Write(stream, property_xml, size, NULL))) + hr = IStream_Seek(stream, zero, SEEK_SET, NULL); + + if (SUCCEEDED(hr)) + hr = d2d_factory_register_effect_from_stream(factory, effect_id, stream, bindings, + binding_count, effect_factory, builtin); + + IStream_Release(stream); + return hr; +} + +HRESULT d2d_factory_register_builtin_effect(struct d2d_factory *factory, REFCLSID effect_id, + const WCHAR *property_xml, const D2D1_PROPERTY_BINDING *bindings, UINT32 binding_count, + PD2D1_EFFECT_FACTORY effect_factory) +{ + return d2d_factory_register_effect_from_string(factory, effect_id, property_xml, bindings, + binding_count, effect_factory, TRUE); } -static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromString(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromString(ID2D1Factory7 *iface, REFCLSID effect_id, const WCHAR *property_xml, const D2D1_PROPERTY_BINDING *bindings, UINT32 binding_count, PD2D1_EFFECT_FACTORY effect_factory) { - FIXME("iface %p, effect_id %s, property_xml %s, bindings %p, binding_count %u, effect_factory %p stub!\n", - iface, debugstr_guid(effect_id), debugstr_w(property_xml), bindings, binding_count, effect_factory); + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); - return S_OK; + TRACE("iface %p, effect_id %s, property_xml %s, bindings %p, binding_count %u, effect_factory %p.\n", + iface, debugstr_guid(effect_id), debugstr_w(property_xml), bindings, binding_count, effect_factory); + + d2d_factory_init_builtin_effects(factory); + + return d2d_factory_register_effect_from_string(factory, effect_id, property_xml, bindings, + binding_count, effect_factory, FALSE); } -static HRESULT STDMETHODCALLTYPE d2d_factory_UnregisterEffect(ID2D1Factory2 *iface, REFCLSID effect_id) +static HRESULT STDMETHODCALLTYPE d2d_factory_UnregisterEffect(ID2D1Factory7 *iface, REFCLSID effect_id) { - FIXME("iface %p, effect_id %s stub!\n", iface, debugstr_guid(effect_id)); + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); + struct d2d_effect_registration *effect; - return E_NOTIMPL; + TRACE("iface %p, effect_id %s.\n", iface, debugstr_guid(effect_id)); + + d2d_factory_init_builtin_effects(factory); + + LIST_FOR_EACH_ENTRY_REV(effect, &factory->effects, struct d2d_effect_registration, entry) + { + if (IsEqualGUID(effect_id, &effect->id)) + { + if (effect->builtin) break; + if (!--effect->registration_count) + { + list_remove(&effect->entry); + d2d_effect_registration_cleanup(effect); + } + return S_OK; + } + } + + return D2DERR_EFFECT_IS_NOT_REGISTERED; } -static HRESULT STDMETHODCALLTYPE d2d_factory_GetRegisteredEffects(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_GetRegisteredEffects(ID2D1Factory7 *iface, CLSID *effects, UINT32 effect_count, UINT32 *returned, UINT32 *registered) { - FIXME("iface %p, effects %p, effect_count %u, returned %p, registered %p stub!\n", + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); + struct d2d_effect_registration *effect; + UINT32 ret, reg; + + TRACE("iface %p, effects %p, effect_count %u, returned %p, registered %p.\n", iface, effects, effect_count, returned, registered); - return E_NOTIMPL; + if (!returned) returned = &ret; + if (!registered) registered = ® + + *registered = 0; + *returned = 0; + + d2d_factory_init_builtin_effects(factory); + + LIST_FOR_EACH_ENTRY(effect, &factory->effects, struct d2d_effect_registration, entry) + { + if (effects && effect_count) + { + *effects = effect->id; + effects++; + effect_count--; + *returned += 1; + } + + *registered += 1; + } + + if (!effects) return S_OK; + return *returned == *registered ? S_OK : D2DERR_INSUFFICIENT_BUFFER; } -static HRESULT STDMETHODCALLTYPE d2d_factory_GetEffectProperties(ID2D1Factory2 *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_GetEffectProperties(ID2D1Factory7 *iface, REFCLSID effect_id, ID2D1Properties **props) { - FIXME("iface %p, effect_id %s, props %p stub!\n", iface, debugstr_guid(effect_id), props); + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); + const struct d2d_effect_registration *reg; - return E_NOTIMPL; + TRACE("iface %p, effect_id %s, props %p.\n", iface, debugstr_guid(effect_id), props); + + d2d_factory_init_builtin_effects(factory); + + if (!(reg = d2d_factory_get_registered_effect((ID2D1Factory *)iface, effect_id))) + { + WARN("Effect id %s not found.\n", wine_dbgstr_guid(effect_id)); + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + } + + *props = ®->properties->ID2D1Properties_iface; + ID2D1Properties_AddRef(*props); + + return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_ID2D1Factory1_CreateDevice(ID2D1Factory2 *iface, IDXGIDevice *dxgi_device, - ID2D1Device1 **device) +static HRESULT STDMETHODCALLTYPE d2d_factory_ID2D1Factory2_CreateDevice(ID2D1Factory7 *iface, + IDXGIDevice *dxgi_device, ID2D1Device1 **device) { - FIXME("iface %p, dxgi_device %p, device %p stub!\n", iface, dxgi_device, device); + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); - return E_NOTIMPL; + TRACE("iface %p, dxgi_device %p, device %p.\n", iface, dxgi_device, device); + + return d2d_factory_create_device(factory, dxgi_device, &IID_ID2D1Device1, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d2d_factory_ID2D1Factory3_CreateDevice(ID2D1Factory7 *iface, + IDXGIDevice *dxgi_device, ID2D1Device2 **device) +{ + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); + + TRACE("iface %p, dxgi_device %p, device %p.\n", iface, dxgi_device, device); + + return d2d_factory_create_device(factory, dxgi_device, &IID_ID2D1Device2, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d2d_factory_ID2D1Factory4_CreateDevice(ID2D1Factory7 *iface, + IDXGIDevice *dxgi_device, ID2D1Device3 **device) +{ + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); + + TRACE("iface %p, dxgi_device %p, device %p.\n", iface, dxgi_device, device); + + return d2d_factory_create_device(factory, dxgi_device, &IID_ID2D1Device3, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d2d_factory_ID2D1Factory5_CreateDevice(ID2D1Factory7 *iface, + IDXGIDevice *dxgi_device, ID2D1Device4 **device) +{ + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); + + TRACE("iface %p, dxgi_device %p, device %p.\n", iface, dxgi_device, device); + + return d2d_factory_create_device(factory, dxgi_device, &IID_ID2D1Device4, (void **)device); } -static const struct ID2D1Factory2Vtbl d2d_factory_vtbl = +static HRESULT STDMETHODCALLTYPE d2d_factory_ID2D1Factory6_CreateDevice(ID2D1Factory7 *iface, + IDXGIDevice *dxgi_device, ID2D1Device5 **device) +{ + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); + + TRACE("iface %p, dxgi_device %p, device %p.\n", iface, dxgi_device, device); + + return d2d_factory_create_device(factory, dxgi_device, &IID_ID2D1Device5, (void **)device); +} + +static HRESULT STDMETHODCALLTYPE d2d_factory_ID2D1Factory7_CreateDevice(ID2D1Factory7 *iface, + IDXGIDevice *dxgi_device, ID2D1Device6 **device) +{ + struct d2d_factory *factory = impl_from_ID2D1Factory7(iface); + + TRACE("iface %p, dxgi_device %p, device %p.\n", iface, dxgi_device, device); + + return d2d_factory_create_device(factory, dxgi_device, &IID_ID2D1Device6, (void **)device); +} + +static const struct ID2D1Factory7Vtbl d2d_factory_vtbl = { d2d_factory_QueryInterface, d2d_factory_AddRef, @@ -607,25 +1275,30 @@ static const struct ID2D1Factory2Vtbl d2d_factory_vtbl = d2d_factory_UnregisterEffect, d2d_factory_GetRegisteredEffects, d2d_factory_GetEffectProperties, - d2d_factory_ID2D1Factory1_CreateDevice, + d2d_factory_ID2D1Factory2_CreateDevice, + d2d_factory_ID2D1Factory3_CreateDevice, + d2d_factory_ID2D1Factory4_CreateDevice, + d2d_factory_ID2D1Factory5_CreateDevice, + d2d_factory_ID2D1Factory6_CreateDevice, + d2d_factory_ID2D1Factory7_CreateDevice, }; static HRESULT STDMETHODCALLTYPE d2d_factory_mt_QueryInterface(ID2D1Multithread *iface, REFIID iid, void **out) { struct d2d_factory *factory = impl_from_ID2D1Multithread(iface); - return d2d_factory_QueryInterface(&factory->ID2D1Factory2_iface, iid, out); + return d2d_factory_QueryInterface(&factory->ID2D1Factory7_iface, iid, out); } static ULONG STDMETHODCALLTYPE d2d_factory_mt_AddRef(ID2D1Multithread *iface) { struct d2d_factory *factory = impl_from_ID2D1Multithread(iface); - return d2d_factory_AddRef(&factory->ID2D1Factory2_iface); + return d2d_factory_AddRef(&factory->ID2D1Factory7_iface); } static ULONG STDMETHODCALLTYPE d2d_factory_mt_Release(ID2D1Multithread *iface) { struct d2d_factory *factory = impl_from_ID2D1Multithread(iface); - return d2d_factory_Release(&factory->ID2D1Factory2_iface); + return d2d_factory_Release(&factory->ID2D1Factory7_iface); } static BOOL STDMETHODCALLTYPE d2d_factory_mt_GetMultithreadProtected(ID2D1Multithread *iface) @@ -690,12 +1363,15 @@ static void d2d_factory_init(struct d2d_factory *factory, D2D1_FACTORY_TYPE fact if (factory_options && factory_options->debugLevel != D2D1_DEBUG_LEVEL_NONE) WARN("Ignoring debug level %#x.\n", factory_options->debugLevel); - factory->ID2D1Factory2_iface.lpVtbl = &d2d_factory_vtbl; + factory->ID2D1Factory7_iface.lpVtbl = &d2d_factory_vtbl; factory->ID2D1Multithread_iface.lpVtbl = factory_type == D2D1_FACTORY_TYPE_SINGLE_THREADED ? &d2d_factory_multithread_noop_vtbl : &d2d_factory_multithread_vtbl; + factory->factory_type = factory_type; factory->refcount = 1; d2d_factory_reload_sysmetrics(factory); + list_init(&factory->effects); InitializeCriticalSection(&factory->cs); + InitOnceInitialize(&factory->init_builtins); } HRESULT WINAPI D2D1CreateFactory(D2D1_FACTORY_TYPE factory_type, REFIID iid, @@ -713,15 +1389,15 @@ HRESULT WINAPI D2D1CreateFactory(D2D1_FACTORY_TYPE factory_type, REFIID iid, return E_INVALIDARG; } - if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; d2d_factory_init(object, factory_type, factory_options); TRACE("Created factory %p.\n", object); - hr = ID2D1Factory2_QueryInterface(&object->ID2D1Factory2_iface, iid, factory); - ID2D1Factory2_Release(&object->ID2D1Factory2_iface); + hr = ID2D1Factory7_QueryInterface(&object->ID2D1Factory7_iface, iid, factory); + ID2D1Factory7_Release(&object->ID2D1Factory7_iface); return hr; } @@ -784,6 +1460,7 @@ HRESULT WINAPI D2D1CreateDevice(IDXGIDevice *dxgi_device, { D2D1_CREATION_PROPERTIES default_properties = {0}; D2D1_FACTORY_OPTIONS factory_options; + D2D1_FACTORY_TYPE factory_type; ID3D11Device *d3d_device; ID2D1Factory1 *factory; HRESULT hr; @@ -801,9 +1478,20 @@ HRESULT WINAPI D2D1CreateDevice(IDXGIDevice *dxgi_device, properties = &default_properties; } + switch (properties->threadingMode) + { + case D2D1_THREADING_MODE_SINGLE_THREADED: + factory_type = D2D1_FACTORY_TYPE_SINGLE_THREADED; + break; + case D2D1_THREADING_MODE_MULTI_THREADED: + factory_type = D2D1_FACTORY_TYPE_MULTI_THREADED; + break; + default: + return E_INVALIDARG; + } + factory_options.debugLevel = properties->debugLevel; - if (FAILED(hr = D2D1CreateFactory(properties->threadingMode, - &IID_ID2D1Factory1, &factory_options, (void **)&factory))) + if (FAILED(hr = D2D1CreateFactory(factory_type, &IID_ID2D1Factory1, &factory_options, (void **)&factory))) return hr; hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, device); @@ -910,9 +1598,10 @@ D2D1_COLOR_F WINAPI D2D1ConvertColorSpace(D2D1_COLOR_SPACE src_colour_space, return ret; } -static BOOL get_config_key_dword(HKEY default_key, HKEY application_key, const char *name, DWORD *value) +static bool get_config_key_u32(HKEY default_key, HKEY application_key, const char *name, uint32_t *value) { - DWORD type, data, size; + DWORD type, size; + uint32_t data; size = sizeof(data); if (application_key && !RegQueryValueExA(application_key, @@ -924,11 +1613,11 @@ static BOOL get_config_key_dword(HKEY default_key, HKEY application_key, const c name, 0, &type, (BYTE *)&data, &size) && type == REG_DWORD) goto success; - return FALSE; + return false; success: *value = data; - return TRUE; + return true; } static void d2d_settings_init(void) @@ -962,7 +1651,7 @@ static void d2d_settings_init(void) if (!default_key && !application_key) return; - if (get_config_key_dword(default_key, application_key, "max_version_factory", &d2d_settings.max_version_factory)) + if (get_config_key_u32(default_key, application_key, "max_version_factory", &d2d_settings.max_version_factory)) ERR_(winediag)("Limiting maximum Direct2D factory version to %#x.\n", d2d_settings.max_version_factory); if (application_key) diff --git a/wrappers/directx/wine/d2d1/geometry.c b/wrappers/directx/wine/d2d1/geometry.c index 6da93de3eb..3da3ad2e65 100644 --- a/wrappers/directx/wine/d2d1/geometry.c +++ b/wrappers/directx/wine/d2d1/geometry.c @@ -50,6 +50,7 @@ enum d2d_vertex_type D2D_VERTEX_TYPE_LINE, D2D_VERTEX_TYPE_BEZIER, D2D_VERTEX_TYPE_SPLIT_BEZIER, + D2D_VERTEX_TYPE_END, }; struct d2d_segment_idx @@ -72,6 +73,7 @@ struct d2d_figure size_t bezier_control_count; D2D1_POINT_2F *original_bezier_controls; + size_t original_bezier_controls_size; size_t original_bezier_control_count; D2D1_RECT_F bounds; @@ -401,11 +403,16 @@ static void d2d_point_calculate_bezier(D2D1_POINT_2F *out, const D2D1_POINT_2F * out->y = t_c * (t_c * p0->y + t * p1->y) + t * (t_c * p1->y + t * p2->y); } +static float d2d_point_length(const D2D1_POINT_2F *p) +{ + return sqrtf(d2d_point_dot(p, p)); +} + static void d2d_point_normalise(D2D1_POINT_2F *p) { float l; - if ((l = sqrtf(d2d_point_dot(p, p))) != 0.0f) + if ((l = d2d_point_length(p)) != 0.0f) d2d_point_scale(p, 1.0f / l); } @@ -503,6 +510,249 @@ static float d2d_point_ccw(const D2D1_POINT_2F *a, const D2D1_POINT_2F *b, const return det_d[det_d_len - 1]; } +/* Determine whether the point q is within the given tolerance of the line + * segment defined by p0 and p1, with the given stroke width and transform. + * Note that we don't care about the tolerance with respect to end-points or + * joins here; those are handled separately. */ +static BOOL d2d_point_on_line_segment(const D2D1_POINT_2F *q, const D2D1_POINT_2F *p0, + const D2D1_POINT_2F *p1, const D2D1_MATRIX_3X2_F *transform, float stroke_width, float tolerance) +{ + D2D1_POINT_2F v_n, v_p, v_q, v_r; + float l; + + d2d_point_subtract(&v_p, p1, p0); + if ((l = d2d_point_length(&v_p)) == 0.0f) + return FALSE; + + /* After (shear) transformation, the line segment is a parallelogram + * defined by p⃑' and n⃑': + * + * p⃑ = P₁ - P₀ + * n⃑ = wp̂⟂ + * p⃑' = p⃑T + * n⃑' = n⃑T */ + l = stroke_width / l; + d2d_point_set(&v_r, transform->_31, transform->_32); + d2d_point_transform(&v_n, transform, -v_p.y * l, v_p.x * l); + d2d_point_subtract(&v_n, &v_n, &v_r); + d2d_point_transform(&v_p, transform, v_p.x, v_p.y); + d2d_point_subtract(&v_p, &v_p, &v_r); + + /* Decompose the vector q⃑ = Q - P₀T into a linear combination of + * p⃑' and n⃑': + * + * lq⃑ = xp⃑' + yn⃑' */ + d2d_point_transform(&v_q, transform, p0->x, p0->y); + d2d_point_subtract(&v_q, q, &v_q); + l = v_p.x * v_n.y - v_p.y * v_n.x; + v_r.x = v_q.x * v_n.y - v_q.y * v_n.x; + v_r.y = v_q.x * v_p.y - v_q.y * v_p.x; + + if (l < 0.0f) + { + l *= -1.0f; + v_r.x *= -1.0f; + } + + /* Check where Q projects onto p⃑'. */ + if (v_r.x < 0.0f || v_r.x > l) + return FALSE; + + /* Check where Q projects onto n⃑'. */ + if (fabs(v_r.y) < l) + return TRUE; + + /* Q lies outside the segment. Check whether the distance to the edge is + * within the tolerance. + * + * P₀' = P₀T + n⃑' + * q⃑' = Q - P₀' + * = q⃑ - n⃑' + * + * The distance is then q⃑' · p̂'⟂. */ + + if (v_r.y > 0.0f) + d2d_point_scale(&v_n, -1.0f); + d2d_point_subtract(&v_q, &v_q, &v_n); + + /* Check where Q projects onto p⃑' + n⃑'. */ + l = d2d_point_dot(&v_q, &v_p); + if (l < 0.0f || l > d2d_point_dot(&v_p, &v_p)) + return FALSE; + + v_n.x = -v_p.y; + v_n.y = v_p.x; + d2d_point_normalise(&v_n); + + return fabsf(d2d_point_dot(&v_q, &v_n)) < tolerance; +} + +/* Approximate the Bézier segment with a (wide) line segment. If the point + * lies outside the approximation, we're done. If the width of the + * approximation is less than the tolerance and the point lies inside, we're + * also done. If neither of those is the case, we subdivide the Bézier segment + * and try again. */ +static BOOL d2d_point_on_bezier_segment(const D2D1_POINT_2F *q, const D2D1_POINT_2F *p0, + const D2D1_BEZIER_SEGMENT *b, const D2D1_MATRIX_3X2_F *transform, float stroke_width, float tolerance) +{ + float d1, d2, d3, d4, d, l, m, w, w2; + D2D1_POINT_2F t[7], start, end, v_p; + D2D1_BEZIER_SEGMENT b0, b1; + + m = 1.0f; + w = stroke_width * 0.5f; + + d2d_point_subtract(&v_p, &b->point3, p0); + /* If the endpoints coincide, use the line through the control points as + * the direction vector. That choice is somewhat arbitrary; other choices + * with tighter error bounds exist. */ + if ((l = d2d_point_dot(&v_p, &v_p)) == 0.0f) + { + d2d_point_subtract(&v_p, &b->point2, &b->point1); + /* If the control points also coincide, the curve is in fact a line. */ + if ((l = d2d_point_dot(&v_p, &v_p)) == 0.0f) + { + d2d_point_subtract(&v_p, &b->point1, p0); + end.x = p0->x + 0.75f * v_p.x; + end.y = p0->y + 0.75f * v_p.y; + + return d2d_point_on_line_segment(q, p0, &end, transform, w, tolerance); + } + m = 0.0f; + } + l = sqrtf(l); + d2d_point_scale(&v_p, 1.0f / l); + m *= l; + + /* Calculate the width w2 of the approximation. */ + + end.x = p0->x + v_p.x; + end.y = p0->y + v_p.y; + /* Here, d1 and d2 are the maximum (signed) distance of the control points + * from the line through the start and end points. */ + d1 = d2d_point_ccw(p0, &end, &b->point1); + d2 = d2d_point_ccw(p0, &end, &b->point2); + /* It can be shown that if the control points of a cubic Bézier curve lie + * on the same side of the line through the endpoints, the distance of the + * curve itself to that line will be within 3/4 of the distance of the + * control points to that line; if the control points lie on opposite + * sides, that distance will be within 4/9 of the distance of the + * corresponding control point. We're taking that as a given here. */ + if (d1 * d2 > 0.0f) + { + d1 *= 0.75f; + d2 *= 0.75f; + } + else + { + d1 = (d1 * 4.0f) / 9.0f; + d2 = (d2 * 4.0f) / 9.0f; + } + w2 = max(fabsf(d1), fabsf(d2)); + + /* Project the control points onto the line through the endpoints of the + * curve. We will use these to calculate the endpoints of the + * approximation. */ + d2d_point_subtract(&t[1], &b->point1, p0); + d1 = d2d_point_dot(&v_p, &t[1]); + d2d_point_subtract(&t[2], &b->point2, p0); + d2 = d2d_point_dot(&v_p, &t[2]); + + /* Calculate the start point of the approximation. Like further above, the + * actual curve is somewhat closer to the endpoints than the control + * points are. */ + d = min(min(d1, d2), 0); + if (d1 * d2 > 0.0f) + d *= 0.75f; + else + d = (d * 4.0f) / 9.0f; + /* Account for the stroke width and tolerance around the endpoints by + * adjusting the endpoints here. This matters because there are no joins + * in the original geometry for the places where we subdivide the original + * curve. We do this here because it's easy; alternatively we could + * explicitly test for this when subdividing the curve further below. */ + d -= min(w + tolerance, w2); + start.x = p0->x + d * v_p.x; + start.y = p0->y + d * v_p.y; + + /* Calculate the end point of the approximation. */ + d1 -= m; + d2 -= m; + d = max(max(d1, d2), 0); + if (d1 * d2 > 0.0f) + d = m + d * 0.75f; + else + d = m + (d * 4.0f) / 9.0f; + d += min(w2, w + tolerance); + end.x = p0->x + d * v_p.x; + end.y = p0->y + d * v_p.y; + + /* Calculate the error bounds of the approximation. We do this in + * transformed space because we need these to be relative to the given + * tolerance. */ + + d2d_point_transform(&t[0], transform, p0->x, p0->y); + d2d_point_transform(&t[1], transform, b->point1.x, b->point1.y); + d2d_point_transform(&t[2], transform, b->point2.x, b->point2.y); + d2d_point_transform(&t[3], transform, b->point3.x, b->point3.y); + d2d_point_transform(&t[4], transform, start.x, start.y); + d2d_point_transform(&t[5], transform, end.x, end.y); + + d2d_point_subtract(&t[6], &t[5], &t[4]); + l = d2d_point_length(&t[6]); + /* Here, d1 and d2 are the maximum (signed) distance of the control points + * from the line through the start and end points. */ + d1 = d2d_point_ccw(&t[4], &t[5], &t[1]) / l; + d2 = d2d_point_ccw(&t[4], &t[5], &t[2]) / l; + if (d1 * d2 > 0.0f) + { + d1 *= 0.75f; + d2 *= 0.75f; + } + else + { + d1 = (d1 * 4.0f) / 9.0f; + d2 = (d2 * 4.0f) / 9.0f; + } + l = max(max(d1, d2), 0) - min(min(d1, d2), 0); + + /* d3 and d4 are the (unsigned) distance of the endpoints of the + * approximation from the original endpoints. */ + d2d_point_subtract(&t[6], &t[4], &t[0]); + d3 = d2d_point_length(&t[6]); + d2d_point_subtract(&t[6], &t[5], &t[3]); + d4 = d2d_point_length(&t[6]); + l = max(max(d3, d4), l); + + /* If the error of the approximation is less than the tolerance, and Q + * lies on the approximation, the distance of Q to the stroked curve is + * definitely within the tolerance. */ + if (l <= tolerance && d2d_point_on_line_segment(q, &start, &end, transform, w, tolerance - l)) + return TRUE; + /* On the other hand, if the distance of Q to the stroked curve is more + * than the sum of the tolerance and d, the distance of Q to the stroked + * curve can't possibly be within the tolerance. */ + if (!d2d_point_on_line_segment(q, &start, &end, transform, w + w2, tolerance)) + return FALSE; + + /* Subdivide the curve. Note that simply splitting the segment in half + * here works and is easy, but may not be optimal. We could potentially + * reduce the number of iterations we need to do by splitting based on + * curvature or segment length. */ + d2d_point_lerp(&t[0], &b->point1, &b->point2, 0.5f); + + b1.point3 = b->point3; + d2d_point_lerp(&b1.point2, &b->point3, &b->point2, 0.5f); + d2d_point_lerp(&b1.point1, &t[0], &b1.point2, 0.5f); + + d2d_point_lerp(&b0.point1, p0, &b->point1, 0.5f); + d2d_point_lerp(&b0.point2, &t[0], &b0.point1, 0.5f); + d2d_point_lerp(&b0.point3, &b0.point2, &b1.point1, 0.5f); + + return d2d_point_on_bezier_segment(q, p0, &b0, transform, stroke_width, tolerance) + || d2d_point_on_bezier_segment(q, &b0.point3, &b1, transform, stroke_width, tolerance); +} + static void d2d_rect_union(D2D1_RECT_F *l, const D2D1_RECT_F *r) { l->left = min(l->left, r->left); @@ -656,6 +906,22 @@ static BOOL d2d_figure_add_bezier_controls(struct d2d_figure *figure, size_t cou return TRUE; } +static BOOL d2d_figure_add_original_bezier_controls(struct d2d_figure *figure, size_t count, const D2D1_POINT_2F *p) +{ + if (!d2d_array_reserve((void **)&figure->original_bezier_controls, &figure->original_bezier_controls_size, + figure->original_bezier_control_count + count, sizeof(*figure->original_bezier_controls))) + { + ERR("Failed to grow cubic Bézier controls array.\n"); + return FALSE; + } + + memcpy(&figure->original_bezier_controls[figure->original_bezier_control_count], + p, count * sizeof(*figure->original_bezier_controls)); + figure->original_bezier_control_count += count; + + return TRUE; +} + static void d2d_cdt_edge_rot(struct d2d_cdt_edge_ref *dst, const struct d2d_cdt_edge_ref *src) { dst->idx = src->idx; @@ -1269,7 +1535,7 @@ static BOOL d2d_cdt_triangulate(struct d2d_cdt *cdt, size_t start_vertex, size_t return TRUE; } - /* More than tree vertices, divide. */ + /* More than three vertices, divide. */ cut = vertex_count / 2; if (!d2d_cdt_triangulate(cdt, start_vertex, cut, &left_outer, &left_inner)) return FALSE; @@ -1413,7 +1679,7 @@ static BOOL d2d_cdt_generate_faces(const struct d2d_cdt *cdt, struct d2d_geometr return TRUE; fail: - heap_free(geometry->fill.faces); + free(geometry->fill.faces); geometry->fill.faces = NULL; geometry->fill.faces_size = 0; geometry->fill.face_count = 0; @@ -1741,8 +2007,6 @@ static BOOL d2d_geometry_intersect_bezier_line(struct d2d_geometry *geometry, p[0] = &figure->vertices[idx_p->vertex_idx]; p[1] = &figure->bezier_controls[idx_p->control_idx]; next = idx_p->vertex_idx + 1; - if (next == figure->vertex_count) - next = 0; p[2] = &figure->vertices[next]; figure = &geometry->u.path.figures[idx_q->figure_idx]; @@ -1819,16 +2083,12 @@ static BOOL d2d_geometry_intersect_bezier_bezier(struct d2d_geometry *geometry, p[0] = &figure->vertices[idx_p->vertex_idx]; p[1] = &figure->bezier_controls[idx_p->control_idx]; next = idx_p->vertex_idx + 1; - if (next == figure->vertex_count) - next = 0; p[2] = &figure->vertices[next]; figure = &geometry->u.path.figures[idx_q->figure_idx]; q[0] = &figure->vertices[idx_q->vertex_idx]; q[1] = &figure->bezier_controls[idx_q->control_idx]; next = idx_q->vertex_idx + 1; - if (next == figure->vertex_count) - next = 0; q[2] = &figure->vertices[next]; d2d_rect_get_bezier_segment_bounds(&p_bounds, p[0], p[1], p[2], start_p, end_p); @@ -1912,8 +2172,6 @@ static BOOL d2d_geometry_apply_intersections(struct d2d_geometry *geometry, p[0] = &figure->vertices[inter->vertex_idx + vertex_offset]; p[1] = &figure->bezier_controls[inter->control_idx + control_offset]; next = inter->vertex_idx + vertex_offset + 1; - if (next == figure->vertex_count) - next = 0; p[2] = &figure->vertices[next]; d2d_point_lerp(&q[0], p[0], p[1], t); @@ -1954,7 +2212,9 @@ static BOOL d2d_geometry_intersect_self(struct d2d_geometry *geometry) idx_p.control_idx = 0; for (idx_p.vertex_idx = 0; idx_p.vertex_idx < figure_p->vertex_count; ++idx_p.vertex_idx) { - type_p = figure_p->vertex_types[idx_p.vertex_idx]; + if ((type_p = figure_p->vertex_types[idx_p.vertex_idx]) == D2D_VERTEX_TYPE_END) + continue; + for (idx_q.figure_idx = 0; idx_q.figure_idx <= idx_p.figure_idx; ++idx_q.figure_idx) { figure_q = &geometry->u.path.figures[idx_q.figure_idx]; @@ -1962,7 +2222,9 @@ static BOOL d2d_geometry_intersect_self(struct d2d_geometry *geometry) { if (!d2d_rect_check_overlap(&figure_p->bounds, &figure_q->bounds)) continue; - max_q = figure_q->vertex_count; + if ((max_q = figure_q->vertex_count) + && figure_q->vertex_types[max_q - 1] == D2D_VERTEX_TYPE_END) + --max_q; } else { @@ -2013,7 +2275,7 @@ static BOOL d2d_geometry_intersect_self(struct d2d_geometry *geometry) ret = d2d_geometry_apply_intersections(geometry, &intersections); done: - heap_free(intersections.intersections); + free(intersections.intersections); return ret; } @@ -2023,6 +2285,9 @@ static HRESULT d2d_path_geometry_triangulate(struct d2d_geometry *geometry) size_t vertex_count, i, j; struct d2d_cdt cdt = {0}; D2D1_POINT_2F *vertices; +#ifdef __i386__ + unsigned int control_word_x87, mask = 0; +#endif for (i = 0, vertex_count = 0; i < geometry->u.path.figure_count; ++i) { @@ -2037,7 +2302,7 @@ static HRESULT d2d_path_geometry_triangulate(struct d2d_geometry *geometry) return S_OK; } - if (!(vertices = heap_calloc(vertex_count, sizeof(*vertices)))) + if (!(vertices = calloc(vertex_count, sizeof(*vertices)))) return E_OUTOFMEMORY; for (i = 0, j = 0; i < geometry->u.path.figure_count; ++i) @@ -2061,26 +2326,46 @@ static HRESULT d2d_path_geometry_triangulate(struct d2d_geometry *geometry) } } + if (vertex_count < 3) + { + WARN("Geometry has %lu vertices after eliminating duplicates.\n", (long)vertex_count); + free(vertices); + return S_OK; + } + geometry->fill.vertices = vertices; geometry->fill.vertex_count = vertex_count; cdt.free_edge = ~0u; cdt.vertices = vertices; + +#ifdef __i386__ + control_word_x87 = _controlfp(0, 0); + _controlfp(_PC_24, mask = _MCW_PC); +#endif if (!d2d_cdt_triangulate(&cdt, 0, vertex_count, &left_edge, &right_edge)) goto fail; if (!d2d_cdt_insert_segments(&cdt, geometry)) goto fail; +#ifdef __i386__ + _controlfp(control_word_x87, _MCW_PC); + mask = 0; +#endif + if (!d2d_cdt_generate_faces(&cdt, geometry)) goto fail; - heap_free(cdt.edges); + free(cdt.edges); return S_OK; fail: geometry->fill.vertices = NULL; geometry->fill.vertex_count = 0; - heap_free(vertices); - heap_free(cdt.edges); + free(vertices); + free(cdt.edges); +#ifdef __i386__ + if (mask) _controlfp(control_word_x87, mask); +#endif return E_FAIL; } @@ -2325,43 +2610,71 @@ static BOOL d2d_geometry_outline_add_arc_quadrant(struct d2d_geometry *geometry, static BOOL d2d_geometry_add_figure_outline(struct d2d_geometry *geometry, struct d2d_figure *figure, D2D1_FIGURE_END figure_end) { - const D2D1_POINT_2F *prev, *p0, *next; - enum d2d_vertex_type prev_type, type; - size_t bezier_idx, i; + const D2D1_POINT_2F *prev, *p0, *p1, *next, *next_prev; + size_t bezier_idx, i, vertex_count; + enum d2d_vertex_type type; + + if (!(vertex_count = figure->vertex_count)) + return TRUE; - for (i = 0, bezier_idx = 0; i < figure->vertex_count; ++i) + p0 = &figure->vertices[0]; + if (figure_end == D2D1_FIGURE_END_CLOSED) { - type = figure->vertex_types[i]; - if (type == D2D_VERTEX_TYPE_NONE) - continue; + if (figure->vertex_types[vertex_count - 1] == D2D_VERTEX_TYPE_END && !--vertex_count) + return TRUE; - p0 = &figure->vertices[i]; + /* In case of a CLOSED path, a join between first and last vertex is + * required. */ + if (d2d_vertex_type_is_bezier(figure->vertex_types[vertex_count - 1])) + prev = &figure->bezier_controls[figure->bezier_control_count - 1]; + else + prev = &figure->vertices[vertex_count - 1]; + } + else + { + if (!--vertex_count) + return TRUE; + prev = p0; + } - if (!i) + for (i = 0, bezier_idx = 0; i < vertex_count; ++i) + { + if ((type = figure->vertex_types[i]) == D2D_VERTEX_TYPE_NONE) { - prev_type = figure->vertex_types[figure->vertex_count - 1]; - if (d2d_vertex_type_is_bezier(prev_type)) - prev = &figure->bezier_controls[figure->bezier_control_count - 1]; - else - prev = &figure->vertices[figure->vertex_count - 1]; + prev = next_prev = &figure->vertices[i]; + continue; + } + + /* next: tangent along next segment, at p0. + * p1: next vertex. */ + if (d2d_vertex_type_is_bezier(type)) + { + next_prev = next = &figure->bezier_controls[bezier_idx++]; + /* type BEZIER implies i + 1 < figure->vertex_count. */ + p1 = &figure->vertices[i + 1]; + + if (!d2d_geometry_outline_add_bezier_segment(geometry, p0, next, p1)) + { + ERR("Failed to add bezier segment.\n"); + return FALSE; + } } else { - prev_type = figure->vertex_types[i - 1]; - if (d2d_vertex_type_is_bezier(prev_type)) - prev = &figure->bezier_controls[bezier_idx - 1]; + if (i + 1 == figure->vertex_count) + next = p1 = &figure->vertices[0]; else - prev = &figure->vertices[i - 1]; - } + next = p1 = &figure->vertices[i + 1]; + next_prev = p0; - if (d2d_vertex_type_is_bezier(type)) - next = &figure->bezier_controls[bezier_idx++]; - else if (i == figure->vertex_count - 1) - next = &figure->vertices[0]; - else - next = &figure->vertices[i + 1]; + if (!d2d_geometry_outline_add_line_segment(geometry, p0, p1)) + { + ERR("Failed to add line segment.\n"); + return FALSE; + } + } - if (figure_end == D2D1_FIGURE_END_CLOSED || (i && i < figure->vertex_count - 1)) + if (i || figure_end == D2D1_FIGURE_END_CLOSED) { D2D1_POINT_2F q_next, q_prev; @@ -2378,27 +2691,8 @@ static BOOL d2d_geometry_add_figure_outline(struct d2d_geometry *geometry, } } - if (type == D2D_VERTEX_TYPE_LINE && (figure_end == D2D1_FIGURE_END_CLOSED || i < figure->vertex_count - 1) - && !d2d_geometry_outline_add_line_segment(geometry, p0, next)) - { - ERR("Failed to add line segment.\n"); - return FALSE; - } - else if (d2d_vertex_type_is_bezier(type)) - { - const D2D1_POINT_2F *p2; - - if (i == figure->vertex_count - 1) - p2 = &figure->vertices[0]; - else - p2 = &figure->vertices[i + 1]; - - if (!d2d_geometry_outline_add_bezier_segment(geometry, p0, next, p2)) - { - ERR("Failed to add bezier segment.\n"); - return FALSE; - } - } + p0 = p1; + prev = next_prev; } return TRUE; @@ -2424,16 +2718,16 @@ static BOOL d2d_geometry_fill_add_arc_triangle(struct d2d_geometry *geometry, static void d2d_geometry_cleanup(struct d2d_geometry *geometry) { - heap_free(geometry->outline.arc_faces); - heap_free(geometry->outline.arcs); - heap_free(geometry->outline.bezier_faces); - heap_free(geometry->outline.beziers); - heap_free(geometry->outline.faces); - heap_free(geometry->outline.vertices); - heap_free(geometry->fill.arc_vertices); - heap_free(geometry->fill.bezier_vertices); - heap_free(geometry->fill.faces); - heap_free(geometry->fill.vertices); + free(geometry->outline.arc_faces); + free(geometry->outline.arcs); + free(geometry->outline.bezier_faces); + free(geometry->outline.beziers); + free(geometry->outline.faces); + free(geometry->outline.vertices); + free(geometry->fill.arc_vertices); + free(geometry->fill.bezier_vertices); + free(geometry->fill.faces); + free(geometry->fill.vertices); ID2D1Factory_Release(geometry->factory); } @@ -2501,7 +2795,10 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_SetFillMode(ID2D1GeometrySink *i static void STDMETHODCALLTYPE d2d_geometry_sink_SetSegmentFlags(ID2D1GeometrySink *iface, D2D1_PATH_SEGMENT flags) { - FIXME("iface %p, flags %#x stub!\n", iface, flags); + TRACE("iface %p, flags %#x.\n", iface, flags); + + if (flags != D2D1_PATH_SEGMENT_NONE) + FIXME("Ignoring flags %#x.\n", flags); } static void STDMETHODCALLTYPE d2d_geometry_sink_BeginFigure(ID2D1GeometrySink *iface, @@ -2588,7 +2885,15 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_AddBeziers(ID2D1GeometrySink *if { D2D1_RECT_F bezier_bounds; - /* FIXME: This tries to approximate a cubic bezier with a quadratic one. */ + if (!d2d_figure_add_original_bezier_controls(figure, 1, &beziers[i].point1) + || !d2d_figure_add_original_bezier_controls(figure, 1, &beziers[i].point2)) + { + ERR("Failed to add cubic Bézier controls.\n"); + geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR; + return; + } + + /* FIXME: This tries to approximate a cubic Bézier with a quadratic one. */ p.x = (beziers[i].point1.x + beziers[i].point2.x) * 0.75f; p.y = (beziers[i].point1.y + beziers[i].point2.y) * 0.75f; p.x -= (figure->vertices[figure->vertex_count - 1].x + beziers[i].point3.x) * 0.25f; @@ -2632,13 +2937,14 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_EndFigure(ID2D1GeometrySink *ifa } figure = &geometry->u.path.figures[geometry->u.path.figure_count - 1]; - figure->vertex_types[figure->vertex_count - 1] = D2D_VERTEX_TYPE_LINE; + if (memcmp(&figure->vertices[0], &figure->vertices[figure->vertex_count - 1], sizeof(*figure->vertices))) + figure->vertex_types[figure->vertex_count - 1] = D2D_VERTEX_TYPE_LINE; + else + figure->vertex_types[figure->vertex_count - 1] = D2D_VERTEX_TYPE_END; if (figure_end == D2D1_FIGURE_END_CLOSED) { ++geometry->u.path.segment_count; figure->flags |= D2D_FIGURE_FLAG_CLOSED; - if (!memcmp(&figure->vertices[0], &figure->vertices[figure->vertex_count - 1], sizeof(*figure->vertices))) - --figure->vertex_count; } if (!d2d_geometry_add_figure_outline(geometry, figure, figure_end)) @@ -2660,11 +2966,11 @@ static void d2d_path_geometry_free_figures(struct d2d_geometry *geometry) for (i = 0; i < geometry->u.path.figure_count; ++i) { - heap_free(geometry->u.path.figures[i].bezier_controls); - heap_free(geometry->u.path.figures[i].original_bezier_controls); - heap_free(geometry->u.path.figures[i].vertices); + free(geometry->u.path.figures[i].original_bezier_controls); + free(geometry->u.path.figures[i].bezier_controls); + free(geometry->u.path.figures[i].vertices); } - heap_free(geometry->u.path.figures); + free(geometry->u.path.figures); geometry->u.path.figures = NULL; geometry->u.path.figures_size = 0; } @@ -2718,18 +3024,12 @@ static BOOL d2d_geometry_check_bezier_overlap(struct d2d_geometry *geometry, figure = &geometry->u.path.figures[idx_p->figure_idx]; a[0] = &figure->vertices[idx_p->vertex_idx]; a[1] = &figure->bezier_controls[idx_p->control_idx]; - if (idx_p->vertex_idx == figure->vertex_count - 1) - a[2] = &figure->vertices[0]; - else - a[2] = &figure->vertices[idx_p->vertex_idx + 1]; + a[2] = &figure->vertices[idx_p->vertex_idx + 1]; figure = &geometry->u.path.figures[idx_q->figure_idx]; b[0] = &figure->vertices[idx_q->vertex_idx]; b[1] = &figure->bezier_controls[idx_q->control_idx]; - if (idx_q->vertex_idx == figure->vertex_count - 1) - b[2] = &figure->vertices[0]; - else - b[2] = &figure->vertices[idx_q->vertex_idx + 1]; + b[2] = &figure->vertices[idx_q->vertex_idx + 1]; if (d2d_point_ccw(a[0], a[1], a[2]) == 0.0f || d2d_point_ccw(b[0], b[1], b[2]) == 0.0f) return FALSE; @@ -2799,9 +3099,6 @@ static float d2d_geometry_bezier_ccw(struct d2d_geometry *geometry, const struct const struct d2d_figure *figure = &geometry->u.path.figures[idx->figure_idx]; size_t next = idx->vertex_idx + 1; - if (next == figure->vertex_count) - next = 0; - return d2d_point_ccw(&figure->vertices[idx->vertex_idx], &figure->bezier_controls[idx->control_idx], &figure->vertices[next]); } @@ -2817,8 +3114,6 @@ static BOOL d2d_geometry_split_bezier(struct d2d_geometry *geometry, const struc p[0] = &figure->vertices[idx->vertex_idx]; p[1] = &figure->bezier_controls[idx->control_idx]; next = idx->vertex_idx + 1; - if (next == figure->vertex_count) - next = 0; p[2] = &figure->vertices[next]; d2d_point_lerp(&q[0], p[0], p[1], 0.5f); @@ -2881,7 +3176,7 @@ static HRESULT d2d_geometry_resolve_beziers(struct d2d_geometry *geometry) geometry->fill.bezier_vertex_count += 3 * geometry->u.path.figures[i].bezier_control_count; } - if (!(geometry->fill.bezier_vertices = heap_calloc(geometry->fill.bezier_vertex_count, + if (!(geometry->fill.bezier_vertices = calloc(geometry->fill.bezier_vertex_count, sizeof(*geometry->fill.bezier_vertices)))) { ERR("Failed to allocate bezier vertices array.\n"); @@ -2930,7 +3225,6 @@ static HRESULT STDMETHODCALLTYPE d2d_geometry_sink_Close(ID2D1GeometrySink *ifac { struct d2d_geometry *geometry = impl_from_ID2D1GeometrySink(iface); HRESULT hr = E_FAIL; - size_t i; TRACE("iface %p.\n", iface); @@ -2942,15 +3236,6 @@ static HRESULT STDMETHODCALLTYPE d2d_geometry_sink_Close(ID2D1GeometrySink *ifac } geometry->u.path.state = D2D_GEOMETRY_STATE_CLOSED; - for (i = 0; i < geometry->u.path.figure_count; ++i) - { - struct d2d_figure *figure = &geometry->u.path.figures[i]; - size_t size = figure->bezier_control_count * sizeof(*figure->original_bezier_controls); - if (!(figure->original_bezier_controls = heap_alloc(size))) - goto done; - memcpy(figure->original_bezier_controls, figure->bezier_controls, size); - } - if (!d2d_geometry_intersect_self(geometry)) goto done; if (FAILED(hr = d2d_geometry_resolve_beziers(geometry))) @@ -2961,7 +3246,8 @@ static HRESULT STDMETHODCALLTYPE d2d_geometry_sink_Close(ID2D1GeometrySink *ifac done: if (FAILED(hr)) { - heap_free(geometry->fill.bezier_vertices); + free(geometry->fill.bezier_vertices); + geometry->fill.bezier_vertices = NULL; geometry->fill.bezier_vertex_count = 0; d2d_path_geometry_free_figures(geometry); geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR; @@ -3009,6 +3295,17 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_AddQuadraticBeziers(ID2D1Geometr for (i = 0; i < bezier_count; ++i) { D2D1_RECT_F bezier_bounds; + D2D1_POINT_2F p[2]; + + /* Construct a cubic curve. */ + d2d_point_lerp(&p[0], &figure->vertices[figure->vertex_count - 1], &beziers[i].point1, 2.0f / 3.0f); + d2d_point_lerp(&p[1], &beziers[i].point2, &beziers[i].point1, 2.0f / 3.0f); + if (!d2d_figure_add_original_bezier_controls(figure, 2, p)) + { + ERR("Failed to add cubic Bézier controls.\n"); + geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR; + return; + } d2d_rect_get_bezier_bounds(&bezier_bounds, &figure->vertices[figure->vertex_count - 1], &beziers[i].point1, &beziers[i].point2); @@ -3074,21 +3371,22 @@ static const struct ID2D1GeometrySinkVtbl d2d_geometry_sink_vtbl = d2d_geometry_sink_AddArc, }; -static inline struct d2d_geometry *impl_from_ID2D1PathGeometry(ID2D1PathGeometry *iface) +static inline struct d2d_geometry *impl_from_ID2D1PathGeometry1(ID2D1PathGeometry1 *iface) { return CONTAINING_RECORD(iface, struct d2d_geometry, ID2D1Geometry_iface); } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_QueryInterface(ID2D1PathGeometry *iface, REFIID iid, void **out) +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_QueryInterface(ID2D1PathGeometry1 *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); - if (IsEqualGUID(iid, &IID_ID2D1PathGeometry) + if (IsEqualGUID(iid, &IID_ID2D1PathGeometry1) + || IsEqualGUID(iid, &IID_ID2D1PathGeometry) || IsEqualGUID(iid, &IID_ID2D1Geometry) || IsEqualGUID(iid, &IID_ID2D1Resource) || IsEqualGUID(iid, &IID_IUnknown)) { - ID2D1PathGeometry_AddRef(iface); + ID2D1PathGeometry1_AddRef(iface); *out = iface; return S_OK; } @@ -3099,46 +3397,46 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_QueryInterface(ID2D1PathGeome return E_NOINTERFACE; } -static ULONG STDMETHODCALLTYPE d2d_path_geometry_AddRef(ID2D1PathGeometry *iface) +static ULONG STDMETHODCALLTYPE d2d_path_geometry_AddRef(ID2D1PathGeometry1 *iface) { - struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface); + struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry1(iface); ULONG refcount = InterlockedIncrement(&geometry->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } -static ULONG STDMETHODCALLTYPE d2d_path_geometry_Release(ID2D1PathGeometry *iface) +static ULONG STDMETHODCALLTYPE d2d_path_geometry_Release(ID2D1PathGeometry1 *iface) { - struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface); + struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry1(iface); ULONG refcount = InterlockedDecrement(&geometry->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { d2d_path_geometry_free_figures(geometry); d2d_geometry_cleanup(geometry); - heap_free(geometry); + free(geometry); } return refcount; } -static void STDMETHODCALLTYPE d2d_path_geometry_GetFactory(ID2D1PathGeometry *iface, ID2D1Factory **factory) +static void STDMETHODCALLTYPE d2d_path_geometry_GetFactory(ID2D1PathGeometry1 *iface, ID2D1Factory **factory) { - struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface); + struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry1(iface); TRACE("iface %p, factory %p.\n", iface, factory); ID2D1Factory_AddRef(*factory = geometry->factory); } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetBounds(ID2D1PathGeometry *iface, +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetBounds(ID2D1PathGeometry1 *iface, const D2D1_MATRIX_3X2_F *transform, D2D1_RECT_F *bounds) { - struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface); + struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry1(iface); size_t i; TRACE("iface %p, transform %p, bounds %p.\n", iface, transform, bounds); @@ -3186,14 +3484,6 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetBounds(ID2D1PathGeometry * if (figure->flags & D2D_FIGURE_FLAG_HOLLOW) continue; - /* Single vertex figures are reduced by CloseFigure(). */ - if (figure->vertex_count == 0) - { - d2d_point_transform(&p, transform, figure->bounds.left, figure->bounds.top); - d2d_rect_expand(bounds, &p); - continue; - } - for (j = 0; j < figure->vertex_count; ++j) { if (figure->vertex_types[j] == D2D_VERTEX_TYPE_NONE) @@ -3208,8 +3498,10 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetBounds(ID2D1PathGeometry * for (bezier_idx = 0, ++j; j < figure->vertex_count; ++j) { - if (figure->vertex_types[j] == D2D_VERTEX_TYPE_NONE - || d2d_vertex_type_is_split_bezier(figure->vertex_types[j])) + enum d2d_vertex_type next_type; + + if ((next_type = figure->vertex_types[j]) == D2D_VERTEX_TYPE_NONE + || d2d_vertex_type_is_split_bezier(next_type)) continue; switch (type) @@ -3221,10 +3513,19 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetBounds(ID2D1PathGeometry * break; case D2D_VERTEX_TYPE_BEZIER: + /* FIXME: This attempts to approximate a cubic Bézier with + * a quadratic one. */ p1 = figure->original_bezier_controls[bezier_idx++]; d2d_point_transform(&p1, transform, p1.x, p1.y); + p2 = figure->original_bezier_controls[bezier_idx++]; + d2d_point_transform(&p2, transform, p2.x, p2.y); + p1.x = (p1.x + p2.x) * 0.75f; + p1.y = (p1.y + p2.y) * 0.75f; p2 = figure->vertices[j]; d2d_point_transform(&p2, transform, p2.x, p2.y); + p1.x -= (p.x + p2.x) * 0.25f; + p1.y -= (p.y + p2.y) * 0.25f; + d2d_rect_get_bezier_bounds(&bezier_bounds, &p, &p1, &p2); d2d_rect_union(bounds, &bezier_bounds); p = p2; @@ -3238,17 +3539,7 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetBounds(ID2D1PathGeometry * break; } - type = figure->vertex_types[j]; - } - - if (d2d_vertex_type_is_bezier(type)) - { - p1 = figure->original_bezier_controls[bezier_idx++]; - d2d_point_transform(&p1, transform, p1.x, p1.y); - p2 = figure->vertices[0]; - d2d_point_transform(&p2, transform, p2.x, p2.y); - d2d_rect_get_bezier_bounds(&bezier_bounds, &p, &p1, &p2); - d2d_rect_union(bounds, &bezier_bounds); + type = next_type; } } @@ -3263,7 +3554,7 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetBounds(ID2D1PathGeometry * return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetWidenedBounds(ID2D1PathGeometry *iface, float stroke_width, +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetWidenedBounds(ID2D1PathGeometry1 *iface, float stroke_width, ID2D1StrokeStyle *stroke_style, const D2D1_MATRIX_3X2_F *transform, float tolerance, D2D1_RECT_F *bounds) { FIXME("iface %p, stroke_width %.8e, stroke_style %p, transform %p, tolerance %.8e, bounds %p stub!\n", @@ -3272,21 +3563,95 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetWidenedBounds(ID2D1PathGeo return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_StrokeContainsPoint(ID2D1PathGeometry *iface, +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_StrokeContainsPoint(ID2D1PathGeometry1 *iface, D2D1_POINT_2F point, float stroke_width, ID2D1StrokeStyle *stroke_style, const D2D1_MATRIX_3X2_F *transform, float tolerance, BOOL *contains) { - FIXME("iface %p, point %s, stroke_width %.8e, stroke_style %p, " - "transform %p, tolerance %.8e, contains %p stub!\n", + struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry1(iface); + enum d2d_vertex_type type = D2D_VERTEX_TYPE_NONE; + unsigned int i, j, bezier_idx; + D2D1_BEZIER_SEGMENT b; + D2D1_POINT_2F p, p1; + + TRACE("iface %p, point %s, stroke_width %.8e, stroke_style %p, transform %p, tolerance %.8e, contains %p.\n", iface, debug_d2d_point_2f(&point), stroke_width, stroke_style, transform, tolerance, contains); - return E_NOTIMPL; + if (stroke_style) + FIXME("Ignoring stroke style %p.\n", stroke_style); + + if (!transform) + transform = &identity; + + if (tolerance <= 0.0f) + tolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE; + + *contains = FALSE; + for (i = 0; i < geometry->u.path.figure_count; ++i) + { + const struct d2d_figure *figure = &geometry->u.path.figures[i]; + + for (j = 0; j < figure->vertex_count; ++j) + { + if (figure->vertex_types[j] == D2D_VERTEX_TYPE_NONE) + continue; + + p = figure->vertices[j]; + type = figure->vertex_types[j]; + break; + } + + for (bezier_idx = 0, ++j; j < figure->vertex_count; ++j) + { + enum d2d_vertex_type next_type; + + if ((next_type = figure->vertex_types[j]) == D2D_VERTEX_TYPE_NONE + || d2d_vertex_type_is_split_bezier(next_type)) + continue; + + switch (type) + { + case D2D_VERTEX_TYPE_LINE: + p1 = figure->vertices[j]; + *contains = d2d_point_on_line_segment(&point, &p, &p1, transform, stroke_width * 0.5f, tolerance); + p = p1; + break; + + case D2D_VERTEX_TYPE_BEZIER: + b.point1 = figure->original_bezier_controls[bezier_idx++]; + b.point2 = figure->original_bezier_controls[bezier_idx++]; + b.point3 = figure->vertices[j]; + *contains = d2d_point_on_bezier_segment(&point, &p, &b, transform, stroke_width, tolerance); + p = b.point3; + break; + + default: + FIXME("Unhandled vertex type %#x.\n", type); + p = figure->vertices[j]; + break; + } + if (*contains) + return S_OK; + type = next_type; + } + + if (type == D2D_VERTEX_TYPE_LINE) + { + p1 = figure->vertices[0]; + if (figure->flags & D2D_FIGURE_FLAG_CLOSED) + *contains = d2d_point_on_line_segment(&point, &p, &p1, transform, stroke_width * 0.5f, tolerance); + } + + if (*contains) + return S_OK; + } + + return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_FillContainsPoint(ID2D1PathGeometry *iface, +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_FillContainsPoint(ID2D1PathGeometry1 *iface, D2D1_POINT_2F point, const D2D1_MATRIX_3X2_F *transform, float tolerance, BOOL *contains) { - struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface); + struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry1(iface); D2D1_MATRIX_3X2_F g_i; TRACE("iface %p, point %s, transform %p, tolerance %.8e, contains %p.\n", @@ -3306,7 +3671,7 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_FillContainsPoint(ID2D1PathGe return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_CompareWithGeometry(ID2D1PathGeometry *iface, +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_CompareWithGeometry(ID2D1PathGeometry1 *iface, ID2D1Geometry *geometry, const D2D1_MATRIX_3X2_F *transform, float tolerance, D2D1_GEOMETRY_RELATION *relation) { FIXME("iface %p, geometry %p, transform %p, tolerance %.8e, relation %p stub!\n", @@ -3360,32 +3725,17 @@ static void d2d_geometry_flatten_cubic(ID2D1SimplifiedGeometrySink *sink, const ID2D1SimplifiedGeometrySink_SetSegmentFlags(sink, D2D1_PATH_SEGMENT_NONE); } -static void d2d_geometry_simplify_quadratic(ID2D1SimplifiedGeometrySink *sink, - D2D1_GEOMETRY_SIMPLIFICATION_OPTION option, const D2D1_POINT_2F *p0, - const D2D1_POINT_2F *p1, const D2D1_POINT_2F *p2, float tolerance) -{ - D2D1_BEZIER_SEGMENT b; - - d2d_point_lerp(&b.point1, p0, p1, 2.0f / 3.0f); - d2d_point_lerp(&b.point2, p2, p1, 2.0f / 3.0f); - b.point3 = *p2; - - if (option == D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES) - d2d_geometry_flatten_cubic(sink, p0, &b, tolerance); - else - ID2D1SimplifiedGeometrySink_AddBeziers(sink, &b, 1); -} - -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Simplify(ID2D1PathGeometry *iface, +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Simplify(ID2D1PathGeometry1 *iface, D2D1_GEOMETRY_SIMPLIFICATION_OPTION option, const D2D1_MATRIX_3X2_F *transform, float tolerance, ID2D1SimplifiedGeometrySink *sink) { - struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface); + struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry1(iface); enum d2d_vertex_type type = D2D_VERTEX_TYPE_NONE; unsigned int i, j, bezier_idx; D2D1_FIGURE_BEGIN begin; - D2D1_POINT_2F p, p1, p2; + D2D1_BEZIER_SEGMENT b; D2D1_FIGURE_END end; + D2D1_POINT_2F p; TRACE("iface %p, option %#x, transform %p, tolerance %.8e, sink %p.\n", iface, option, transform, tolerance, sink); @@ -3411,8 +3761,10 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Simplify(ID2D1PathGeometry *i for (bezier_idx = 0, ++j; j < figure->vertex_count; ++j) { - if (figure->vertex_types[j] == D2D_VERTEX_TYPE_NONE - || d2d_vertex_type_is_split_bezier(figure->vertex_types[j])) + enum d2d_vertex_type next_type; + + if ((next_type = figure->vertex_types[j]) == D2D_VERTEX_TYPE_NONE + || d2d_vertex_type_is_split_bezier(next_type)) continue; switch (type) @@ -3425,14 +3777,21 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Simplify(ID2D1PathGeometry *i break; case D2D_VERTEX_TYPE_BEZIER: - p1 = figure->original_bezier_controls[bezier_idx++]; + b.point1 = figure->original_bezier_controls[bezier_idx++]; + b.point2 = figure->original_bezier_controls[bezier_idx++]; + b.point3 = figure->vertices[j]; if (transform) - d2d_point_transform(&p1, transform, p1.x, p1.y); - p2 = figure->vertices[j]; - if (transform) - d2d_point_transform(&p2, transform, p2.x, p2.y); - d2d_geometry_simplify_quadratic(sink, option, &p, &p1, &p2, tolerance); - p = p2; + { + d2d_point_transform(&b.point1, transform, b.point1.x, b.point1.y); + d2d_point_transform(&b.point2, transform, b.point2.x, b.point2.y); + d2d_point_transform(&b.point3, transform, b.point3.x, b.point3.y); + } + + if (option == D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES) + d2d_geometry_flatten_cubic(sink, &p, &b, tolerance); + else + ID2D1SimplifiedGeometrySink_AddBeziers(sink, &b, 1); + p = b.point3; break; default: @@ -3444,18 +3803,7 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Simplify(ID2D1PathGeometry *i break; } - type = figure->vertex_types[j]; - } - - if (d2d_vertex_type_is_bezier(type)) - { - p1 = figure->original_bezier_controls[bezier_idx++]; - if (transform) - d2d_point_transform(&p1, transform, p1.x, p1.y); - p2 = figure->vertices[0]; - if (transform) - d2d_point_transform(&p2, transform, p2.x, p2.y); - d2d_geometry_simplify_quadratic(sink, option, &p, &p1, &p2, tolerance); + type = next_type; } end = figure->flags & D2D_FIGURE_FLAG_CLOSED ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN; @@ -3465,7 +3813,7 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Simplify(ID2D1PathGeometry *i return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Tessellate(ID2D1PathGeometry *iface, +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Tessellate(ID2D1PathGeometry1 *iface, const D2D1_MATRIX_3X2_F *transform, float tolerance, ID2D1TessellationSink *sink) { FIXME("iface %p, transform %p, tolerance %.8e, sink %p stub!\n", iface, transform, tolerance, sink); @@ -3473,7 +3821,7 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Tessellate(ID2D1PathGeometry return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_CombineWithGeometry(ID2D1PathGeometry *iface, +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_CombineWithGeometry(ID2D1PathGeometry1 *iface, ID2D1Geometry *geometry, D2D1_COMBINE_MODE combine_mode, const D2D1_MATRIX_3X2_F *transform, float tolerance, ID2D1SimplifiedGeometrySink *sink) { @@ -3483,7 +3831,7 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_CombineWithGeometry(ID2D1Path return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Outline(ID2D1PathGeometry *iface, +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Outline(ID2D1PathGeometry1 *iface, const D2D1_MATRIX_3X2_F *transform, float tolerance, ID2D1SimplifiedGeometrySink *sink) { FIXME("iface %p, transform %p, tolerance %.8e, sink %p stub!\n", iface, transform, tolerance, sink); @@ -3491,7 +3839,7 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Outline(ID2D1PathGeometry *if return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_ComputeArea(ID2D1PathGeometry *iface, +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_ComputeArea(ID2D1PathGeometry1 *iface, const D2D1_MATRIX_3X2_F *transform, float tolerance, float *area) { FIXME("iface %p, transform %p, tolerance %.8e, area %p stub!\n", iface, transform, tolerance, area); @@ -3499,7 +3847,7 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_ComputeArea(ID2D1PathGeometry return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_ComputeLength(ID2D1PathGeometry *iface, +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_ComputeLength(ID2D1PathGeometry1 *iface, const D2D1_MATRIX_3X2_F *transform, float tolerance, float *length) { FIXME("iface %p, transform %p, tolerance %.8e, length %p stub!\n", iface, transform, tolerance, length); @@ -3507,7 +3855,7 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_ComputeLength(ID2D1PathGeomet return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_ComputePointAtLength(ID2D1PathGeometry *iface, float length, +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_ComputePointAtLength(ID2D1PathGeometry1 *iface, float length, const D2D1_MATRIX_3X2_F *transform, float tolerance, D2D1_POINT_2F *point, D2D1_POINT_2F *tangent) { FIXME("iface %p, length %.8e, transform %p, tolerance %.8e, point %p, tangent %p stub!\n", @@ -3516,7 +3864,7 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_ComputePointAtLength(ID2D1Pat return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Widen(ID2D1PathGeometry *iface, float stroke_width, +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Widen(ID2D1PathGeometry1 *iface, float stroke_width, ID2D1StrokeStyle *stroke_style, const D2D1_MATRIX_3X2_F *transform, float tolerance, ID2D1SimplifiedGeometrySink *sink) { @@ -3526,9 +3874,9 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Widen(ID2D1PathGeometry *ifac return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Open(ID2D1PathGeometry *iface, ID2D1GeometrySink **sink) +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Open(ID2D1PathGeometry1 *iface, ID2D1GeometrySink **sink) { - struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface); + struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry1(iface); TRACE("iface %p, sink %p.\n", iface, sink); @@ -3543,16 +3891,16 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Open(ID2D1PathGeometry *iface return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Stream(ID2D1PathGeometry *iface, ID2D1GeometrySink *sink) +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Stream(ID2D1PathGeometry1 *iface, ID2D1GeometrySink *sink) { FIXME("iface %p, sink %p stub!\n", iface, sink); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetSegmentCount(ID2D1PathGeometry *iface, UINT32 *count) +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetSegmentCount(ID2D1PathGeometry1 *iface, UINT32 *count) { - struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface); + struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry1(iface); TRACE("iface %p, count %p.\n", iface, count); @@ -3564,9 +3912,9 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetSegmentCount(ID2D1PathGeom return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetFigureCount(ID2D1PathGeometry *iface, UINT32 *count) +static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetFigureCount(ID2D1PathGeometry1 *iface, UINT32 *count) { - struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface); + struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry1(iface); TRACE("iface %p, count %p.\n", iface, count); @@ -3578,7 +3926,17 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetFigureCount(ID2D1PathGeome return S_OK; } -static const struct ID2D1PathGeometryVtbl d2d_path_geometry_vtbl = +static HRESULT STDMETHODCALLTYPE d2d_path_geometry1_ComputePointAndSegmentAtLength(ID2D1PathGeometry1 *iface, + float length, UINT32 start_segment, const D2D1_MATRIX_3X2_F *transform, float tolerance, + D2D1_POINT_DESCRIPTION *point_desc) +{ + FIXME("iface %p, length %.8e, start_segment %u, transform %p, tolerance %.8e, point_desc %p.\n", + iface, length, start_segment, transform, tolerance, point_desc); + + return E_NOTIMPL; +} + +static const struct ID2D1PathGeometry1Vtbl d2d_path_geometry_vtbl = { d2d_path_geometry_QueryInterface, d2d_path_geometry_AddRef, @@ -3601,6 +3959,7 @@ static const struct ID2D1PathGeometryVtbl d2d_path_geometry_vtbl = d2d_path_geometry_Stream, d2d_path_geometry_GetSegmentCount, d2d_path_geometry_GetFigureCount, + d2d_path_geometry1_ComputePointAndSegmentAtLength, }; void d2d_path_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *factory) @@ -3644,7 +4003,7 @@ static ULONG STDMETHODCALLTYPE d2d_ellipse_geometry_AddRef(ID2D1EllipseGeometry struct d2d_geometry *geometry = impl_from_ID2D1EllipseGeometry(iface); ULONG refcount = InterlockedIncrement(&geometry->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -3654,12 +4013,12 @@ static ULONG STDMETHODCALLTYPE d2d_ellipse_geometry_Release(ID2D1EllipseGeometry struct d2d_geometry *geometry = impl_from_ID2D1EllipseGeometry(iface); ULONG refcount = InterlockedDecrement(&geometry->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { d2d_geometry_cleanup(geometry); - heap_free(geometry); + free(geometry); } return refcount; @@ -3832,7 +4191,7 @@ HRESULT d2d_ellipse_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *f d2d_geometry_init(geometry, factory, &identity, (ID2D1GeometryVtbl *)&d2d_ellipse_geometry_vtbl); geometry->u.ellipse.ellipse = *ellipse; - if (!(geometry->fill.vertices = heap_alloc(4 * sizeof(*geometry->fill.vertices)))) + if (!(geometry->fill.vertices = malloc(4 * sizeof(*geometry->fill.vertices)))) goto fail; if (!d2d_array_reserve((void **)&geometry->fill.faces, &geometry->fill.faces_size, 2, sizeof(*geometry->fill.faces))) @@ -3916,7 +4275,7 @@ static ULONG STDMETHODCALLTYPE d2d_rectangle_geometry_AddRef(ID2D1RectangleGeome struct d2d_geometry *geometry = impl_from_ID2D1RectangleGeometry(iface); ULONG refcount = InterlockedIncrement(&geometry->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -3926,12 +4285,12 @@ static ULONG STDMETHODCALLTYPE d2d_rectangle_geometry_Release(ID2D1RectangleGeom struct d2d_geometry *geometry = impl_from_ID2D1RectangleGeometry(iface); ULONG refcount = InterlockedDecrement(&geometry->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { d2d_geometry_cleanup(geometry); - heap_free(geometry); + free(geometry); } return refcount; @@ -3993,10 +4352,76 @@ static HRESULT STDMETHODCALLTYPE d2d_rectangle_geometry_StrokeContainsPoint(ID2D D2D1_POINT_2F point, float stroke_width, ID2D1StrokeStyle *stroke_style, const D2D1_MATRIX_3X2_F *transform, float tolerance, BOOL *contains) { - FIXME("iface %p, point %s, stroke_width %.8e, stroke_style %p, transform %p, tolerance %.8e, contains %p stub!\n", + const struct d2d_geometry *geometry = impl_from_ID2D1RectangleGeometry(iface); + const D2D1_RECT_F *rect = &geometry->u.rectangle.rect; + unsigned int i; + struct + { + D2D1_POINT_2F s, e; + } + segments[4]; + + TRACE("iface %p, point %s, stroke_width %.8e, stroke_style %p, transform %p, tolerance %.8e, contains %p.\n", iface, debug_d2d_point_2f(&point), stroke_width, stroke_style, transform, tolerance, contains); - return E_NOTIMPL; + if (stroke_style) + FIXME("Ignoring stroke style %p.\n", stroke_style); + + tolerance = fabsf(tolerance); + + if (!transform) + { + D2D1_POINT_2F d, s; + + s.x = rect->right - rect->left; + s.y = rect->bottom - rect->top; + d.x = fabsf((rect->right + rect->left) * 0.5f - point.x); + d.y = fabsf((rect->bottom + rect->top) * 0.5f - point.y); + + /* Inside test. */ + if (d.x <= (s.x - stroke_width) * 0.5f - tolerance && d.y <= (s.y - stroke_width) * 0.5f - tolerance) + { + *contains = FALSE; + return S_OK; + } + + if (tolerance == 0.0f) + { + *contains = d.x < (s.x + stroke_width) * 0.5f && d.y < (s.y + stroke_width) * 0.5f; + } + else + { + d.x = max(d.x - (s.x + stroke_width) * 0.5f, 0.0f); + d.y = max(d.y - (s.y + stroke_width) * 0.5f, 0.0f); + + *contains = d2d_point_dot(&d, &d) < tolerance * tolerance; + } + + return S_OK; + } + + stroke_width *= 0.5f; + + d2d_point_set(&segments[0].s, rect->left - stroke_width, rect->bottom); + d2d_point_set(&segments[0].e, rect->right + stroke_width, rect->bottom); + d2d_point_set(&segments[1].s, rect->right, rect->bottom + stroke_width); + d2d_point_set(&segments[1].e, rect->right, rect->top - stroke_width); + d2d_point_set(&segments[2].s, rect->right + stroke_width, rect->top); + d2d_point_set(&segments[2].e, rect->left - stroke_width, rect->top); + d2d_point_set(&segments[3].s, rect->left, rect->top - stroke_width); + d2d_point_set(&segments[3].e, rect->left, rect->bottom + stroke_width); + + *contains = FALSE; + for (i = 0; i < ARRAY_SIZE(segments); ++i) + { + if (d2d_point_on_line_segment(&point, &segments[i].s, &segments[i].e, transform, stroke_width, tolerance)) + { + *contains = TRUE; + break; + } + } + + return S_OK; } static HRESULT STDMETHODCALLTYPE d2d_rectangle_geometry_FillContainsPoint(ID2D1RectangleGeometry *iface, @@ -4187,7 +4612,7 @@ HRESULT d2d_rectangle_geometry_init(struct d2d_geometry *geometry, ID2D1Factory d2d_geometry_init(geometry, factory, &identity, (ID2D1GeometryVtbl *)&d2d_rectangle_geometry_vtbl); geometry->u.rectangle.rect = *rect; - if (!(geometry->fill.vertices = heap_alloc(4 * sizeof(*geometry->fill.vertices)))) + if (!(geometry->fill.vertices = malloc(4 * sizeof(*geometry->fill.vertices)))) goto fail; if (!d2d_array_reserve((void **)&geometry->fill.faces, &geometry->fill.faces_size, 2, sizeof(*geometry->fill.faces))) @@ -4266,7 +4691,7 @@ static ULONG STDMETHODCALLTYPE d2d_rounded_rectangle_geometry_AddRef(ID2D1Rounde struct d2d_geometry *geometry = impl_from_ID2D1RoundedRectangleGeometry(iface); ULONG refcount = InterlockedIncrement(&geometry->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -4276,12 +4701,12 @@ static ULONG STDMETHODCALLTYPE d2d_rounded_rectangle_geometry_Release(ID2D1Round struct d2d_geometry *geometry = impl_from_ID2D1RoundedRectangleGeometry(iface); ULONG refcount = InterlockedDecrement(&geometry->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { d2d_geometry_cleanup(geometry); - heap_free(geometry); + free(geometry); } return refcount; @@ -4459,7 +4884,7 @@ HRESULT d2d_rounded_rectangle_geometry_init(struct d2d_geometry *geometry, d2d_geometry_init(geometry, factory, &identity, (ID2D1GeometryVtbl *)&d2d_rounded_rectangle_geometry_vtbl); geometry->u.rounded_rectangle.rounded_rect = *rounded_rect; - if (!(geometry->fill.vertices = heap_alloc(8 * sizeof(*geometry->fill.vertices)))) + if (!(geometry->fill.vertices = malloc(8 * sizeof(*geometry->fill.vertices)))) goto fail; if (!d2d_array_reserve((void **)&geometry->fill.faces, &geometry->fill.faces_size, 6, sizeof(*geometry->fill.faces))) @@ -4562,7 +4987,7 @@ static ULONG STDMETHODCALLTYPE d2d_transformed_geometry_AddRef(ID2D1TransformedG struct d2d_geometry *geometry = impl_from_ID2D1TransformedGeometry(iface); ULONG refcount = InterlockedIncrement(&geometry->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -4572,7 +4997,7 @@ static ULONG STDMETHODCALLTYPE d2d_transformed_geometry_Release(ID2D1Transformed struct d2d_geometry *geometry = impl_from_ID2D1TransformedGeometry(iface); ULONG refcount = InterlockedDecrement(&geometry->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { @@ -4588,7 +5013,7 @@ static ULONG STDMETHODCALLTYPE d2d_transformed_geometry_Release(ID2D1Transformed geometry->fill.vertices = NULL; ID2D1Geometry_Release(geometry->u.transformed.src_geometry); d2d_geometry_cleanup(geometry); - heap_free(geometry); + free(geometry); } return refcount; @@ -4640,9 +5065,13 @@ static HRESULT STDMETHODCALLTYPE d2d_transformed_geometry_StrokeContainsPoint(ID iface, debug_d2d_point_2f(&point), stroke_width, stroke_style, transform, tolerance, contains); g = geometry->transform; + stroke_width /= g.m11; if (transform) d2d_matrix_multiply(&g, transform); + if (tolerance <= 0.0f) + tolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE; + return ID2D1Geometry_StrokeContainsPoint(geometry->u.transformed.src_geometry, point, stroke_width, stroke_style, &g, tolerance, contains); } @@ -4842,7 +5271,7 @@ static ULONG STDMETHODCALLTYPE d2d_geometry_group_AddRef(ID2D1GeometryGroup *ifa struct d2d_geometry *geometry = impl_from_ID2D1GeometryGroup(iface); ULONG refcount = InterlockedIncrement(&geometry->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -4853,15 +5282,15 @@ static ULONG STDMETHODCALLTYPE d2d_geometry_group_Release(ID2D1GeometryGroup *if ULONG refcount = InterlockedDecrement(&geometry->refcount); unsigned int i; - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { for (i = 0; i < geometry->u.group.geometry_count; ++i) ID2D1Geometry_Release(geometry->u.group.src_geometries[i]); - heap_free(geometry->u.group.src_geometries); + free(geometry->u.group.src_geometries); d2d_geometry_cleanup(geometry); - heap_free(geometry); + free(geometry); } return refcount; @@ -5072,7 +5501,7 @@ HRESULT d2d_geometry_group_init(struct d2d_geometry *geometry, ID2D1Factory *fac d2d_geometry_init(geometry, factory, &identity, (ID2D1GeometryVtbl *)&d2d_geometry_group_vtbl); - if (!(geometry->u.group.src_geometries = heap_calloc(geometry_count, sizeof(*geometries)))) + if (!(geometry->u.group.src_geometries = calloc(geometry_count, sizeof(*geometries)))) { d2d_geometry_cleanup(geometry); return E_OUTOFMEMORY; diff --git a/wrappers/directx/wine/d2d1/hwnd_render_target.c b/wrappers/directx/wine/d2d1/hwnd_render_target.c index 625f101eaa..7f16ff00d4 100644 --- a/wrappers/directx/wine/d2d1/hwnd_render_target.c +++ b/wrappers/directx/wine/d2d1/hwnd_render_target.c @@ -32,7 +32,7 @@ static HRESULT d2d_hwnd_render_target_present(IUnknown *outer_unknown) HRESULT hr; if (FAILED(hr = IDXGISwapChain_Present(render_target->swapchain, render_target->sync_interval, 0))) - WARN("Present failed, %#x.\n", hr); + WARN("Present failed, %#lx.\n", hr); return S_OK; } @@ -67,7 +67,7 @@ static ULONG STDMETHODCALLTYPE d2d_hwnd_render_target_AddRef(ID2D1HwndRenderTarg struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); ULONG refcount = InterlockedIncrement(&render_target->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -77,13 +77,13 @@ static ULONG STDMETHODCALLTYPE d2d_hwnd_render_target_Release(ID2D1HwndRenderTar struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); ULONG refcount = InterlockedDecrement(&render_target->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { IUnknown_Release(render_target->dxgi_inner); IDXGISwapChain_Release(render_target->swapchain); - heap_free(render_target); + free(render_target); } return refcount; @@ -652,10 +652,32 @@ static BOOL STDMETHODCALLTYPE d2d_hwnd_render_target_IsSupported(ID2D1HwndRender const D2D1_RENDER_TARGET_PROPERTIES *desc) { struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + const D2D1_RENDER_TARGET_PROPERTIES *target_desc = &render_target->desc; + D2D1_PIXEL_FORMAT pixel_format; TRACE("iface %p, desc %p.\n", iface, desc); - return ID2D1RenderTarget_IsSupported(render_target->dxgi_target, desc); + if (desc->type != D2D1_RENDER_TARGET_TYPE_DEFAULT + && target_desc->type != desc->type) + { + return FALSE; + } + + pixel_format = ID2D1RenderTarget_GetPixelFormat(render_target->dxgi_target); + + if (desc->pixelFormat.format != DXGI_FORMAT_UNKNOWN + && pixel_format.format != desc->pixelFormat.format) + { + return FALSE; + } + + if (desc->pixelFormat.alphaMode != D2D1_ALPHA_MODE_UNKNOWN + && pixel_format.alphaMode != desc->pixelFormat.alphaMode) + { + return FALSE; + } + + return (target_desc->usage & desc->usage) == desc->usage; } static D2D1_WINDOW_STATE STDMETHODCALLTYPE d2d_hwnd_render_target_CheckWindowState(ID2D1HwndRenderTarget *iface) @@ -687,7 +709,7 @@ static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_Resize(ID2D1HwndRenderTa if (FAILED(hr = IDXGISwapChain_GetBuffer(render_target->swapchain, 0, &IID_IDXGISurface1, (void **)&dxgi_surface))) { - WARN("Failed to get buffer, hr %#x.\n", hr); + WARN("Failed to get buffer, hr %#lx.\n", hr); ID2D1DeviceContext_Release(context); return hr; } @@ -696,7 +718,7 @@ static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_Resize(ID2D1HwndRenderTa IDXGISurface1_Release(dxgi_surface); if (FAILED(hr)) { - WARN("Failed to create target bitmap, hr %#x.\n", hr); + WARN("Failed to create target bitmap, hr %#lx.\n", hr); ID2D1DeviceContext_Release(context); return hr; } @@ -810,7 +832,7 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target if (FAILED(hr = ID3D10Device1_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&dxgi_device))) { - WARN("Failed to get IDXGIDevice interface, hr %#x.\n", hr); + WARN("Failed to get IDXGIDevice interface, hr %#lx.\n", hr); return hr; } @@ -818,7 +840,7 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target IDXGIDevice_Release(dxgi_device); if (FAILED(hr)) { - WARN("Failed to get IDXGIAdapter interface, hr %#x.\n", hr); + WARN("Failed to get IDXGIAdapter interface, hr %#lx.\n", hr); return hr; } @@ -826,7 +848,7 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target IDXGIAdapter_Release(dxgi_adapter); if (FAILED(hr)) { - WARN("Failed to get IDXGIFactory interface, hr %#x.\n", hr); + WARN("Failed to get IDXGIFactory interface, hr %#lx.\n", hr); return hr; } @@ -835,11 +857,23 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target ID2D1Factory1_GetDesktopDpi(factory, &dxgi_rt_desc.dpiX, &dxgi_rt_desc.dpiY); if (dxgi_rt_desc.pixelFormat.format == DXGI_FORMAT_UNKNOWN) - { dxgi_rt_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + + if (dxgi_rt_desc.pixelFormat.alphaMode == D2D1_ALPHA_MODE_UNKNOWN) dxgi_rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE; + + if (dxgi_rt_desc.pixelFormat.alphaMode == D2D1_ALPHA_MODE_STRAIGHT) + { + IDXGIFactory_Release(dxgi_factory); + WARN("Alpha mode %u is not supported.\n", dxgi_rt_desc.pixelFormat.alphaMode); + return D2DERR_UNSUPPORTED_PIXEL_FORMAT; } + render_target->desc = dxgi_rt_desc; + /* FIXME: should be resolved to either HW or SW type. */ + if (render_target->desc.type == D2D1_RENDER_TARGET_TYPE_DEFAULT) + render_target->desc.type = D2D1_RENDER_TARGET_TYPE_HARDWARE; + swapchain_desc.BufferDesc.Width = hwnd_rt_desc->pixelSize.width; swapchain_desc.BufferDesc.Height = hwnd_rt_desc->pixelSize.height; swapchain_desc.BufferDesc.RefreshRate.Numerator = 60; @@ -855,19 +889,21 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target swapchain_desc.Windowed = TRUE; swapchain_desc.SwapEffect = hwnd_rt_desc->presentOptions & D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS ? DXGI_SWAP_EFFECT_SEQUENTIAL : DXGI_SWAP_EFFECT_DISCARD; - swapchain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE; + swapchain_desc.Flags = 0; + if (desc->usage & D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE) + swapchain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE; hr = IDXGIFactory_CreateSwapChain(dxgi_factory, (IUnknown *)d3d_device, &swapchain_desc, &render_target->swapchain); IDXGIFactory_Release(dxgi_factory); if (FAILED(hr)) { - WARN("Failed to create a swapchain, hr %#x.\n", hr); + WARN("Failed to create a swapchain, hr %#lx.\n", hr); return hr; } if (FAILED(hr = IDXGISwapChain_GetBuffer(render_target->swapchain, 0, &IID_IDXGISurface, (void **)&dxgi_surface))) { - WARN("Failed to get buffer, hr %#x.\n", hr); + WARN("Failed to get buffer, hr %#lx.\n", hr); IDXGISwapChain_Release(render_target->swapchain); return hr; } @@ -876,7 +912,7 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target if (FAILED(hr = IDXGISurface_GetDevice(dxgi_surface, &IID_IDXGIDevice, (void **)&dxgi_device))) { - WARN("Failed to get DXGI device, hr %#X.\n", hr); + WARN("Failed to get DXGI device, hr %#lx.\n", hr); IDXGISurface_Release(dxgi_surface); IDXGISwapChain_Release(render_target->swapchain); return hr; @@ -886,20 +922,20 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target IDXGIDevice_Release(dxgi_device); if (FAILED(hr)) { - WARN("Failed to create D2D device, hr %#X.\n", hr); + WARN("Failed to create D2D device, hr %#lx.\n", hr); IDXGISurface_Release(dxgi_surface); IDXGISwapChain_Release(render_target->swapchain); return hr; } - hr = d2d_d3d_create_render_target(device, dxgi_surface, + hr = d2d_d3d_create_render_target(unsafe_impl_from_ID2D1Device((ID2D1Device1 *)device), dxgi_surface, (IUnknown *)&render_target->ID2D1HwndRenderTarget_iface, &d2d_hwnd_render_target_ops, &dxgi_rt_desc, (void **)&render_target->dxgi_inner); IDXGISurface_Release(dxgi_surface); ID2D1Device_Release(device); if (FAILED(hr)) { - WARN("Failed to create DXGI surface render target, hr %#x.\n", hr); + WARN("Failed to create DXGI surface render target, hr %#lx.\n", hr); IDXGISwapChain_Release(render_target->swapchain); return hr; } @@ -907,7 +943,7 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target if (FAILED(hr = IUnknown_QueryInterface(render_target->dxgi_inner, &IID_ID2D1RenderTarget, (void **)&render_target->dxgi_target))) { - WARN("Failed to retrieve ID2D1RenderTarget interface, hr %#x.\n", hr); + WARN("Failed to retrieve ID2D1RenderTarget interface, hr %#lx.\n", hr); IUnknown_Release(render_target->dxgi_inner); IDXGISwapChain_Release(render_target->swapchain); return hr; diff --git a/wrappers/directx/wine/d2d1/layer.c b/wrappers/directx/wine/d2d1/layer.c index 3eb2f3695d..eead61dc54 100644 --- a/wrappers/directx/wine/d2d1/layer.c +++ b/wrappers/directx/wine/d2d1/layer.c @@ -49,7 +49,7 @@ static ULONG STDMETHODCALLTYPE d2d_layer_AddRef(ID2D1Layer *iface) struct d2d_layer *layer = impl_from_ID2D1Layer(iface); ULONG refcount = InterlockedIncrement(&layer->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -59,12 +59,12 @@ static ULONG STDMETHODCALLTYPE d2d_layer_Release(ID2D1Layer *iface) struct d2d_layer *layer = impl_from_ID2D1Layer(iface); ULONG refcount = InterlockedDecrement(&layer->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { ID2D1Factory_Release(layer->factory); - heap_free(layer); + free(layer); } return refcount; @@ -100,7 +100,7 @@ static const struct ID2D1LayerVtbl d2d_layer_vtbl = HRESULT d2d_layer_create(ID2D1Factory *factory, const D2D1_SIZE_F *size, struct d2d_layer **layer) { - if (!(*layer = heap_alloc_zero(sizeof(**layer)))) + if (!(*layer = calloc(1, sizeof(**layer)))) return E_OUTOFMEMORY; (*layer)->ID2D1Layer_iface.lpVtbl = &d2d_layer_vtbl; diff --git a/wrappers/directx/wine/d2d1/mesh.c b/wrappers/directx/wine/d2d1/mesh.c index 1e64a0ea16..cd6a5d13a8 100644 --- a/wrappers/directx/wine/d2d1/mesh.c +++ b/wrappers/directx/wine/d2d1/mesh.c @@ -49,7 +49,7 @@ static ULONG STDMETHODCALLTYPE d2d_mesh_AddRef(ID2D1Mesh *iface) struct d2d_mesh *mesh = impl_from_ID2D1Mesh(iface); ULONG refcount = InterlockedIncrement(&mesh->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -59,12 +59,12 @@ static ULONG STDMETHODCALLTYPE d2d_mesh_Release(ID2D1Mesh *iface) struct d2d_mesh *mesh = impl_from_ID2D1Mesh(iface); ULONG refcount = InterlockedDecrement(&mesh->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { ID2D1Factory_Release(mesh->factory); - heap_free(mesh); + free(mesh); } return refcount; @@ -97,7 +97,7 @@ static const struct ID2D1MeshVtbl d2d_mesh_vtbl = HRESULT d2d_mesh_create(ID2D1Factory *factory, struct d2d_mesh **mesh) { - if (!(*mesh = heap_alloc_zero(sizeof(**mesh)))) + if (!(*mesh = calloc(1, sizeof(**mesh)))) return E_OUTOFMEMORY; (*mesh)->ID2D1Mesh_iface.lpVtbl = &d2d_mesh_vtbl; diff --git a/wrappers/directx/wine/d2d1/state_block.c b/wrappers/directx/wine/d2d1/state_block.c index 501d94ae3e..770c165fd9 100644 --- a/wrappers/directx/wine/d2d1/state_block.c +++ b/wrappers/directx/wine/d2d1/state_block.c @@ -50,7 +50,7 @@ static ULONG STDMETHODCALLTYPE d2d_state_block_AddRef(ID2D1DrawingStateBlock1 *i struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock1(iface); ULONG refcount = InterlockedIncrement(&state_block->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -60,14 +60,14 @@ static ULONG STDMETHODCALLTYPE d2d_state_block_Release(ID2D1DrawingStateBlock1 * struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock1(iface); ULONG refcount = InterlockedDecrement(&state_block->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { if (state_block->text_rendering_params) IDWriteRenderingParams_Release(state_block->text_rendering_params); ID2D1Factory_Release(state_block->factory); - heap_free(state_block); + free(state_block); } return refcount; @@ -186,6 +186,10 @@ struct d2d_state_block *unsafe_impl_from_ID2D1DrawingStateBlock(ID2D1DrawingStat { if (!iface) return NULL; - assert(iface->lpVtbl == (ID2D1DrawingStateBlockVtbl *)&d2d_state_block_vtbl); + if (iface->lpVtbl != (ID2D1DrawingStateBlockVtbl *)&d2d_state_block_vtbl) + { + WARN("Unexpected state block vtbl %p.\n", iface->lpVtbl); + return NULL; + } return CONTAINING_RECORD(iface, struct d2d_state_block, ID2D1DrawingStateBlock1_iface); } diff --git a/wrappers/directx/wine/d2d1/stroke.c b/wrappers/directx/wine/d2d1/stroke.c index 0ba44e0b1d..fc12d4eb97 100644 --- a/wrappers/directx/wine/d2d1/stroke.c +++ b/wrappers/directx/wine/d2d1/stroke.c @@ -20,12 +20,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(d2d); -static inline struct d2d_stroke_style *impl_from_ID2D1StrokeStyle(ID2D1StrokeStyle *iface) +static inline struct d2d_stroke_style *impl_from_ID2D1StrokeStyle1(ID2D1StrokeStyle1 *iface) { - return CONTAINING_RECORD(iface, struct d2d_stroke_style, ID2D1StrokeStyle_iface); + return CONTAINING_RECORD(iface, struct d2d_stroke_style, ID2D1StrokeStyle1_iface); } -static HRESULT STDMETHODCALLTYPE d2d_stroke_style_QueryInterface(ID2D1StrokeStyle *iface, REFIID iid, void **out) +static HRESULT STDMETHODCALLTYPE d2d_stroke_style_QueryInterface(ID2D1StrokeStyle1 *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); @@ -33,7 +33,7 @@ static HRESULT STDMETHODCALLTYPE d2d_stroke_style_QueryInterface(ID2D1StrokeStyl || IsEqualGUID(iid, &IID_ID2D1Resource) || IsEqualGUID(iid, &IID_IUnknown)) { - ID2D1StrokeStyle_AddRef(iface); + ID2D1StrokeStyle1_AddRef(iface); *out = iface; return S_OK; } @@ -44,118 +44,118 @@ static HRESULT STDMETHODCALLTYPE d2d_stroke_style_QueryInterface(ID2D1StrokeStyl return E_NOINTERFACE; } -static ULONG STDMETHODCALLTYPE d2d_stroke_style_AddRef(ID2D1StrokeStyle *iface) +static ULONG STDMETHODCALLTYPE d2d_stroke_style_AddRef(ID2D1StrokeStyle1 *iface) { - struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface); + struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle1(iface); ULONG refcount = InterlockedIncrement(&style->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } -static ULONG STDMETHODCALLTYPE d2d_stroke_style_Release(ID2D1StrokeStyle *iface) +static ULONG STDMETHODCALLTYPE d2d_stroke_style_Release(ID2D1StrokeStyle1 *iface) { - struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface); + struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle1(iface); ULONG refcount = InterlockedDecrement(&style->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { ID2D1Factory_Release(style->factory); if (style->desc.dashStyle == D2D1_DASH_STYLE_CUSTOM) - heap_free(style->dashes); - heap_free(style); + free(style->dashes); + free(style); } return refcount; } -static void STDMETHODCALLTYPE d2d_stroke_style_GetFactory(ID2D1StrokeStyle *iface, ID2D1Factory **factory) +static void STDMETHODCALLTYPE d2d_stroke_style_GetFactory(ID2D1StrokeStyle1 *iface, ID2D1Factory **factory) { - struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface); + struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle1(iface); TRACE("iface %p, factory %p.\n", iface, factory); ID2D1Factory_AddRef(*factory = style->factory); } -static D2D1_CAP_STYLE STDMETHODCALLTYPE d2d_stroke_style_GetStartCap(ID2D1StrokeStyle *iface) +static D2D1_CAP_STYLE STDMETHODCALLTYPE d2d_stroke_style_GetStartCap(ID2D1StrokeStyle1 *iface) { - struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface); + struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle1(iface); TRACE("iface %p.\n", iface); return style->desc.startCap; } -static D2D1_CAP_STYLE STDMETHODCALLTYPE d2d_stroke_style_GetEndCap(ID2D1StrokeStyle *iface) +static D2D1_CAP_STYLE STDMETHODCALLTYPE d2d_stroke_style_GetEndCap(ID2D1StrokeStyle1 *iface) { - struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface); + struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle1(iface); TRACE("iface %p.\n", iface); return style->desc.endCap; } -static D2D1_CAP_STYLE STDMETHODCALLTYPE d2d_stroke_style_GetDashCap(ID2D1StrokeStyle *iface) +static D2D1_CAP_STYLE STDMETHODCALLTYPE d2d_stroke_style_GetDashCap(ID2D1StrokeStyle1 *iface) { - struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface); + struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle1(iface); TRACE("iface %p.\n", iface); return style->desc.dashCap; } -static float STDMETHODCALLTYPE d2d_stroke_style_GetMiterLimit(ID2D1StrokeStyle *iface) +static float STDMETHODCALLTYPE d2d_stroke_style_GetMiterLimit(ID2D1StrokeStyle1 *iface) { - struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface); + struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle1(iface); TRACE("iface %p.\n", iface); return style->desc.miterLimit; } -static D2D1_LINE_JOIN STDMETHODCALLTYPE d2d_stroke_style_GetLineJoin(ID2D1StrokeStyle *iface) +static D2D1_LINE_JOIN STDMETHODCALLTYPE d2d_stroke_style_GetLineJoin(ID2D1StrokeStyle1 *iface) { - struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface); + struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle1(iface); TRACE("iface %p.\n", iface); return style->desc.lineJoin; } -static float STDMETHODCALLTYPE d2d_stroke_style_GetDashOffset(ID2D1StrokeStyle *iface) +static float STDMETHODCALLTYPE d2d_stroke_style_GetDashOffset(ID2D1StrokeStyle1 *iface) { - struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface); + struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle1(iface); TRACE("iface %p.\n", iface); return style->desc.dashOffset; } -static D2D1_DASH_STYLE STDMETHODCALLTYPE d2d_stroke_style_GetDashStyle(ID2D1StrokeStyle *iface) +static D2D1_DASH_STYLE STDMETHODCALLTYPE d2d_stroke_style_GetDashStyle(ID2D1StrokeStyle1 *iface) { - struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface); + struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle1(iface); TRACE("iface %p.\n", iface); return style->desc.dashStyle; } -static UINT32 STDMETHODCALLTYPE d2d_stroke_style_GetDashesCount(ID2D1StrokeStyle *iface) +static UINT32 STDMETHODCALLTYPE d2d_stroke_style_GetDashesCount(ID2D1StrokeStyle1 *iface) { - struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface); + struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle1(iface); TRACE("iface %p.\n", iface); return style->dash_count; } -static void STDMETHODCALLTYPE d2d_stroke_style_GetDashes(ID2D1StrokeStyle *iface, float *dashes, UINT32 dash_count) +static void STDMETHODCALLTYPE d2d_stroke_style_GetDashes(ID2D1StrokeStyle1 *iface, float *dashes, UINT32 dash_count) { - struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface); + struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle1(iface); TRACE("iface %p, dashes %p, count %u.\n", iface, dashes, dash_count); @@ -164,7 +164,16 @@ static void STDMETHODCALLTYPE d2d_stroke_style_GetDashes(ID2D1StrokeStyle *iface memset(dashes + style->dash_count, 0, (dash_count - style->dash_count) * sizeof(*dashes)); } -static const struct ID2D1StrokeStyleVtbl d2d_stroke_style_vtbl = +static D2D1_STROKE_TRANSFORM_TYPE STDMETHODCALLTYPE d2d_stroke_style_GetStrokeTransformType(ID2D1StrokeStyle1 *iface) +{ + struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle1(iface); + + TRACE("iface %p.\n", iface); + + return style->desc.transformType; +} + +static const struct ID2D1StrokeStyle1Vtbl d2d_stroke_style_vtbl = { d2d_stroke_style_QueryInterface, d2d_stroke_style_AddRef, @@ -179,10 +188,19 @@ static const struct ID2D1StrokeStyleVtbl d2d_stroke_style_vtbl = d2d_stroke_style_GetDashStyle, d2d_stroke_style_GetDashesCount, d2d_stroke_style_GetDashes, + d2d_stroke_style_GetStrokeTransformType }; +struct d2d_stroke_style *unsafe_impl_from_ID2D1StrokeStyle(ID2D1StrokeStyle *iface) +{ + if (!iface) + return NULL; + assert((const struct ID2D1StrokeStyle1Vtbl *)iface->lpVtbl == &d2d_stroke_style_vtbl); + return CONTAINING_RECORD(iface, struct d2d_stroke_style, ID2D1StrokeStyle1_iface); +} + HRESULT d2d_stroke_style_init(struct d2d_stroke_style *style, ID2D1Factory *factory, - const D2D1_STROKE_STYLE_PROPERTIES *desc, const float *dashes, UINT32 dash_count) + const D2D1_STROKE_STYLE_PROPERTIES1 *desc, const float *dashes, UINT32 dash_count) { static const struct { @@ -201,7 +219,10 @@ HRESULT d2d_stroke_style_init(struct d2d_stroke_style *style, ID2D1Factory *fact if (desc->dashStyle > D2D1_DASH_STYLE_CUSTOM) return E_INVALIDARG; - style->ID2D1StrokeStyle_iface.lpVtbl = &d2d_stroke_style_vtbl; + if (desc->transformType != D2D1_STROKE_TRANSFORM_TYPE_NORMAL) + FIXME("transformType %d is not supported\n", desc->transformType); + + style->ID2D1StrokeStyle1_iface.lpVtbl = &d2d_stroke_style_vtbl; style->refcount = 1; if (desc->dashStyle == D2D1_DASH_STYLE_CUSTOM) @@ -209,7 +230,7 @@ HRESULT d2d_stroke_style_init(struct d2d_stroke_style *style, ID2D1Factory *fact if (!dashes || !dash_count) return E_INVALIDARG; - if (!(style->dashes = heap_calloc(dash_count, sizeof(*style->dashes)))) + if (!(style->dashes = calloc(dash_count, sizeof(*style->dashes)))) return E_OUTOFMEMORY; memcpy(style->dashes, dashes, dash_count * sizeof(*style->dashes)); style->dash_count = dash_count; diff --git a/wrappers/directx/wine/d2d1/version.rc b/wrappers/directx/wine/d2d1/version.rc index 2f99637346..ab7a911c12 100644 --- a/wrappers/directx/wine/d2d1/version.rc +++ b/wrappers/directx/wine/d2d1/version.rc @@ -18,5 +18,9 @@ #define WINE_FILEDESCRIPTION_STR "Wine Direct2D" #define WINE_FILENAME_STR "d2d1.dll" +#define WINE_FILEVERSION 6,2,9200,16765 +#define WINE_FILEVERSION_STR "6.2.9200.16765" +#define WINE_PRODUCTVERSION 6,2,9200,16765 +#define WINE_PRODUCTVERSION_STR "6.2.9200.16765" -#include "common_wrappers_ver.rc" +#include "wine/wine_common_ver.rc" diff --git a/wrappers/directx/wine/d2d1/wic_render_target.c b/wrappers/directx/wine/d2d1/wic_render_target.c index 9b57a5d2c3..ccbe194d29 100644 --- a/wrappers/directx/wine/d2d1/wic_render_target.c +++ b/wrappers/directx/wine/d2d1/wic_render_target.c @@ -43,7 +43,7 @@ static HRESULT d2d_wic_render_target_present(IUnknown *outer_unknown) if (FAILED(hr = IDXGISurface_QueryInterface(render_target->dxgi_surface, &IID_ID3D10Resource, (void **)&src_resource))) { - ERR("Failed to get source resource interface, hr %#x.\n", hr); + ERR("Failed to get source resource interface, hr %#lx.\n", hr); goto end; } @@ -58,27 +58,27 @@ static HRESULT d2d_wic_render_target_present(IUnknown *outer_unknown) dst_rect.Height = render_target->height; if (FAILED(hr = IWICBitmap_Lock(render_target->bitmap, &dst_rect, WICBitmapLockWrite, &bitmap_lock))) { - ERR("Failed to lock destination bitmap, hr %#x.\n", hr); + ERR("Failed to lock destination bitmap, hr %#lx.\n", hr); goto end; } if (FAILED(hr = IWICBitmapLock_GetDataPointer(bitmap_lock, &dst_size, &dst))) { - ERR("Failed to get data pointer, hr %#x.\n", hr); + ERR("Failed to get data pointer, hr %#lx.\n", hr); IWICBitmapLock_Release(bitmap_lock); goto end; } if (FAILED(hr = IWICBitmapLock_GetStride(bitmap_lock, &dst_pitch))) { - ERR("Failed to get stride, hr %#x.\n", hr); + ERR("Failed to get stride, hr %#lx.\n", hr); IWICBitmapLock_Release(bitmap_lock); goto end; } if (FAILED(hr = ID3D10Texture2D_Map(render_target->readback_texture, 0, D3D10_MAP_READ, 0, &mapped_texture))) { - ERR("Failed to map readback texture, hr %#x.\n", hr); + ERR("Failed to map readback texture, hr %#lx.\n", hr); IWICBitmapLock_Release(bitmap_lock); goto end; } @@ -113,7 +113,7 @@ static ULONG STDMETHODCALLTYPE d2d_wic_render_target_AddRef(IUnknown *iface) struct d2d_wic_render_target *render_target = impl_from_IUnknown(iface); ULONG refcount = InterlockedIncrement(&render_target->refcount); - TRACE("%p increasing refcount to %u.\n", iface, refcount); + TRACE("%p increasing refcount to %lu.\n", iface, refcount); return refcount; } @@ -123,7 +123,7 @@ static ULONG STDMETHODCALLTYPE d2d_wic_render_target_Release(IUnknown *iface) struct d2d_wic_render_target *render_target = impl_from_IUnknown(iface); ULONG refcount = InterlockedDecrement(&render_target->refcount); - TRACE("%p decreasing refcount to %u.\n", iface, refcount); + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); if (!refcount) { @@ -131,7 +131,7 @@ static ULONG STDMETHODCALLTYPE d2d_wic_render_target_Release(IUnknown *iface) ID3D10Texture2D_Release(render_target->readback_texture); IUnknown_Release(render_target->dxgi_inner); IDXGISurface_Release(render_target->dxgi_surface); - heap_free(render_target); + free(render_target); } return refcount; @@ -162,7 +162,7 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, if (FAILED(hr = IWICBitmap_GetSize(bitmap, &render_target->width, &render_target->height))) { - WARN("Failed to get bitmap dimensions, hr %#x.\n", hr); + WARN("Failed to get bitmap dimensions, hr %#lx.\n", hr); return hr; } @@ -178,7 +178,7 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, if (FAILED(hr = IWICBitmap_GetPixelFormat(bitmap, &bitmap_format))) { - WARN("Failed to get bitmap format, hr %#x.\n", hr); + WARN("Failed to get bitmap format, hr %#lx.\n", hr); return hr; } @@ -187,6 +187,11 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, { texture_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; } + else if (IsEqualGUID(&bitmap_format, &GUID_WICPixelFormat32bppPRGBA) + || IsEqualGUID(&bitmap_format, &GUID_WICPixelFormat32bppRGB)) + { + texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + } else { WARN("Unsupported WIC bitmap format %s.\n", debugstr_guid(&bitmap_format)); @@ -197,6 +202,7 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, switch (texture_desc.Format) { case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM: render_target->bpp = 4; break; @@ -215,7 +221,7 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, if (FAILED(hr = ID3D10Device1_CreateTexture2D(d3d_device, &texture_desc, NULL, &texture))) { - WARN("Failed to create texture, hr %#x.\n", hr); + WARN("Failed to create texture, hr %#lx.\n", hr); return hr; } @@ -223,7 +229,7 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, ID3D10Texture2D_Release(texture); if (FAILED(hr)) { - WARN("Failed to get DXGI surface interface, hr %#x.\n", hr); + WARN("Failed to get DXGI surface interface, hr %#lx.\n", hr); return hr; } @@ -234,14 +240,14 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, if (FAILED(hr = ID3D10Device1_CreateTexture2D(d3d_device, &texture_desc, NULL, &render_target->readback_texture))) { - WARN("Failed to create readback texture, hr %#x.\n", hr); + WARN("Failed to create readback texture, hr %#lx.\n", hr); IDXGISurface_Release(render_target->dxgi_surface); return hr; } if (FAILED(hr = ID3D10Device1_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&dxgi_device))) { - WARN("Failed to get DXGI device, hr %#x.\n", hr); + WARN("Failed to get DXGI device, hr %#lx.\n", hr); IDXGISurface_Release(render_target->dxgi_surface); return hr; } @@ -250,17 +256,18 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, IDXGIDevice_Release(dxgi_device); if (FAILED(hr)) { - WARN("Failed to create D2D device, hr %#x.\n", hr); + WARN("Failed to create D2D device, hr %#lx.\n", hr); IDXGISurface_Release(render_target->dxgi_surface); return hr; } - hr = d2d_d3d_create_render_target(device, render_target->dxgi_surface, &render_target->IUnknown_iface, + hr = d2d_d3d_create_render_target(unsafe_impl_from_ID2D1Device((ID2D1Device1 *)device), + render_target->dxgi_surface, &render_target->IUnknown_iface, &d2d_wic_render_target_ops, desc, (void **)&render_target->dxgi_inner); ID2D1Device_Release(device); if (FAILED(hr)) { - WARN("Failed to create DXGI surface render target, hr %#x.\n", hr); + WARN("Failed to create DXGI surface render target, hr %#lx.\n", hr); ID3D10Texture2D_Release(render_target->readback_texture); IDXGISurface_Release(render_target->dxgi_surface); return hr; @@ -269,7 +276,7 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, if (FAILED(hr = IUnknown_QueryInterface(render_target->dxgi_inner, &IID_ID2D1RenderTarget, (void **)&render_target->dxgi_target))) { - WARN("Failed to retrieve ID2D1RenderTarget interface, hr %#x.\n", hr); + WARN("Failed to retrieve ID2D1RenderTarget interface, hr %#lx.\n", hr); IUnknown_Release(render_target->dxgi_inner); ID3D10Texture2D_Release(render_target->readback_texture); IDXGISurface_Release(render_target->dxgi_surface); diff --git a/wrappers/drivers/new/CMakeLists.txt b/wrappers/drivers/new/CMakeLists.txt index 6fc5607670..e3cc1de2da 100644 --- a/wrappers/drivers/new/CMakeLists.txt +++ b/wrappers/drivers/new/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(appid) add_subdirectory(bootanim) add_subdirectory(netio) #add_subdirectory(nsiproxy) \ No newline at end of file diff --git a/wrappers/extensions/CMakeLists.txt b/wrappers/extensions/CMakeLists.txt index d1ec21419e..6c2fc44fb3 100644 --- a/wrappers/extensions/CMakeLists.txt +++ b/wrappers/extensions/CMakeLists.txt @@ -1,8 +1,8 @@ add_subdirectory(advapiex) -#add_subdirectory(bcryptext) +add_subdirectory(bcryptext) #add_subdirectory(browseex) add_subdirectory(cfgmgrex) -add_subdirectory(comdlgex) +#add_subdirectory(comdlgex) add_subdirectory(cryptex) add_subdirectory(dnsapiext) add_subdirectory(dxgiext) @@ -15,9 +15,10 @@ add_subdirectory(pdhext) add_subdirectory(powrpext) add_subdirectory(rpcrtext) add_subdirectory(securex) -add_subdirectory(setupext) +#add_subdirectory(setupext) add_subdirectory(shellex) -add_subdirectory(shlwext) +#add_subdirectory(shlwext) +add_subdirectory(uiautomationcoreext) add_subdirectory(userenvext) add_subdirectory(uxthext) add_subdirectory(winstaext) diff --git a/wrappers/extensions/advapiex/CMakeLists.txt b/wrappers/extensions/advapiex/CMakeLists.txt index 5c56343a9e..956823c701 100644 --- a/wrappers/extensions/advapiex/CMakeLists.txt +++ b/wrappers/extensions/advapiex/CMakeLists.txt @@ -14,6 +14,7 @@ spec2def(advapiex.dll advapiex.spec ADD_IMPORTLIB) set(baseaddress_advapiex 0x6c520000) list(APPEND SOURCE + cred.c efs.c eventlog.c hooks.c diff --git a/wrappers/extensions/advapiex/advapiex.spec b/wrappers/extensions/advapiex/advapiex.spec index 89ffc331e4..68fd351ca5 100644 --- a/wrappers/extensions/advapiex/advapiex.spec +++ b/wrappers/extensions/advapiex/advapiex.spec @@ -462,7 +462,6 @@ 485 stdcall RegGetKeySecurity(long long ptr ptr) 488 stdcall RegLoadKeyA(long str str) 489 stdcall RegLoadKeyW(long wstr wstr) -490 stdcall RegNotifyChangeKeyValue(long long long long long) 491 stdcall RegOpenCurrentUser(long ptr) 492 stdcall RegOpenKeyA(long str ptr) 493 stdcall RegOpenKeyExA(long str long long ptr) @@ -669,8 +668,7 @@ 471 stdcall RegDeleteKeyExW(long wstr long long) 477 stdcall RegEnableReflectionKey(ptr) @ stdcall RegDisablePredefinedCacheEx() -@ stdcall RegGetValueA(long str str long ptr ptr ptr) -@ stdcall RegGetValueW(long wstr wstr long ptr ptr ptr) +486 stdcall RegGetValueA(long str str long ptr ptr ptr) 502 stdcall RegQueryReflectionKey(ptr ptr) ;native on Server 2003, but, missing on XP (needed for synchronization) #Vista function, however, is supported by advapi32 from XP/2003 post-SP with updates @@ -678,6 +676,13 @@ #Vista Functions implemented (without redirection) @ stdcall AddMandatoryAce(ptr long long long ptr) +@ stdcall CredFindBestCredentialA(str long long ptr) +@ stdcall CredFindBestCredentialW(wstr long long ptr) +@ stdcall CredIsProtectedA(str ptr) +@ stdcall CredIsProtectedW(wstr ptr) +@ stdcall CredProtectA(long str long str long ptr) +@ stdcall CredProtectW(long wstr long wstr long ptr) +@ stdcall CredUnprotectA(long str long str ptr) @ stdcall CredUnprotectW(long wstr long wstr ptr) @ stdcall EnableTraceEx(ptr ptr int64 long long long long long long long ptr) @ stdcall EventAccessControl(ptr long ptr long long) @@ -776,19 +781,11 @@ ; @ stdcall ControlServiceExW(ptr long long ptr) ; @ stdcall CredBackupCredentials(long ptr ptr long long) ; @ stdcall CredEncryptAndMarshalBinaryBlob(long long long) -; @ stdcall CredFindBestCredentialA(str long long ptr) -; @ stdcall CredFindBestCredentialW(wstr long long ptr) -; @ stdcall CredIsProtectedA(str ptr) -; @ stdcall CredIsProtectedW(wstr ptr) ; @ stdcall CredpConvertOneCredentialSize(long long) ; @ stdcall CredpEncodeSecret(long ptr long long long) ; @ stdcall CredProfileUnloaded() -; @ stdcall CredProtectA(long str long str long ptr) -; @ stdcall CredProtectW(long wstr long wstr long ptr) ; @ stdcall CredReadByTokenHandle(long ptr long long long) ; @ stdcall CredRestoreCredentials(ptr ptr long long) -; @ stdcall CredUnprotectA(long str long str ptr) -; @ stdcall CredUnprotectW(long wstr long wstr ptr) ; @ stdcall EnumerateTraceGuidsEx(long ptr long ptr long ptr) ; @ stdcall EventAccessQuery(ptr ptr ptr) ; @ stdcall EventAccessRemove(ptr) @@ -881,6 +878,8 @@ 322 stdcall IsWellKnownSid(ptr long) IsWellKnownSidInternal 429 stdcall OpenProcessToken(long long ptr) #OpenProcessTokenInternal 434 stdcall OpenThreadToken(ptr long long ptr) #OpenThreadTokenInternal +487 stdcall RegGetValueW(long wstr wstr long ptr ptr ptr) RegGetValueWInternal +490 stdcall RegNotifyChangeKeyValue(long long long long long) RegNotifyChangeKeyValueInternal 563 stdcall SetKernelObjectSecurity(long long ptr) SetKernelObjectSecurityInternal 567 stdcall SetNamedSecurityInfoW(wstr long ptr ptr ptr ptr ptr) SetNamedSecurityInfoWInternal 576 stdcall SetSecurityInfo(long long long ptr ptr ptr ptr) SetSecurityInfoInternal diff --git a/wrappers/extensions/advapiex/hooks.c b/wrappers/extensions/advapiex/hooks.c index e3638aceb6..a9d53eeeb9 100644 --- a/wrappers/extensions/advapiex/hooks.c +++ b/wrappers/extensions/advapiex/hooks.c @@ -23,6 +23,30 @@ Revision History: WINE_DEFAULT_DEBUG_CHANNEL(advapi32_hooks); +#define REG_NOTIFY_THREAD_AGNOSTIC 0x10000000 + +LSTATUS +WINAPI +RegGetValueWNative( + HKEY hkey, + LPCWSTR lpSubKey, + LPCWSTR lpValue, + DWORD dwFlags, + LPDWORD pdwType, + PVOID pvData, + LPDWORD pcbData +); + +LSTATUS +WINAPI +RegNotifyChangeKeyValueNative( + HKEY hKey, + BOOL bWatchSubtree, + DWORD dwNotifyFilter, + HANDLE hEvent, + BOOL fAsynchronous +); + typedef struct _MAX_SID { /* same fields as struct _SID */ @@ -411,11 +435,19 @@ GetTokenInformationInternal ( return TRUE; } + if(TokenInformationClass == TokenAppContainerSid ){ + *ReturnLength = sizeof(PSID); + if(TokenInformationLength < sizeof(PSID)) + return FALSE; + TokenInformation = NULL; + return TRUE; + } + if(TokenInformationClass == TokenElevationType ){ TokenInformation = (PVOID)2; TokenInformationLength = sizeof(ULONG); return TRUE; - } + } if(TokenInformationClass == TokenIntegrityLevel || TokenInformationClass == TokenElevation || @@ -1716,4 +1748,189 @@ BOOL WINAPI IsWellKnownSidInternal( PSID sid, WELL_KNOWN_SID_TYPE type ) return TRUE; return FALSE; +} + +static void apply_restrictions(DWORD dwFlags, DWORD dwType, DWORD cbData, PLONG ret) +{ + /* Check if the type is restricted by the passed flags */ + if (*ret == ERROR_SUCCESS || *ret == ERROR_MORE_DATA) + { + DWORD dwMask = 0; + + switch (dwType) + { + case REG_NONE: dwMask = RRF_RT_REG_NONE; break; + case REG_SZ: dwMask = RRF_RT_REG_SZ; break; + case REG_EXPAND_SZ: dwMask = RRF_RT_REG_EXPAND_SZ; break; + case REG_MULTI_SZ: dwMask = RRF_RT_REG_MULTI_SZ; break; + case REG_BINARY: dwMask = RRF_RT_REG_BINARY; break; + case REG_DWORD: dwMask = RRF_RT_REG_DWORD; break; + case REG_QWORD: dwMask = RRF_RT_REG_QWORD; break; + } + + if (dwFlags & dwMask) + { + /* Type is not restricted, check for size mismatch */ + if (dwType == REG_BINARY) + { + DWORD cbExpect = 0; + + if ((dwFlags & RRF_RT_ANY) == RRF_RT_DWORD) + cbExpect = 4; + else if ((dwFlags & RRF_RT_ANY) == RRF_RT_QWORD) + cbExpect = 8; + + if (cbExpect && cbData != cbExpect) + *ret = ERROR_DATATYPE_MISMATCH; + } + } else *ret = ERROR_UNSUPPORTED_TYPE; + } +} + +static inline BOOL is_string(DWORD type) +{ + return (type == REG_SZ) || (type == REG_EXPAND_SZ) || (type == REG_MULTI_SZ); +} + +static LSTATUS Py_RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, + DWORD dwFlags, LPDWORD pdwType, PVOID pvData, + LPDWORD pcbData) +{ + DWORD dwType, cbData = (pvData && pcbData) ? *pcbData : 0; + PVOID pvBuf = NULL; + LONG ret; + + if (pvData && !pcbData) + return ERROR_INVALID_PARAMETER; + + if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & (RRF_NOEXPAND | RRF_RT_REG_SZ)) && + ((dwFlags & RRF_RT_ANY) != RRF_RT_ANY)) + return ERROR_INVALID_PARAMETER; + + if ((dwFlags & RRF_WOW64_MASK) == RRF_WOW64_MASK) + return ERROR_INVALID_PARAMETER; + + if (pszSubKey && pszSubKey[0]) + { + REGSAM samDesired = KEY_QUERY_VALUE; + + if (dwFlags & RRF_WOW64_MASK) + samDesired |= (dwFlags & RRF_SUBKEY_WOW6432KEY) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY; + + ret = RegOpenKeyExW(hKey, pszSubKey, 0, samDesired, &hKey); + if (ret != ERROR_SUCCESS) return ret; + } + + ret = RegQueryValueExW(hKey, pszValue, NULL, &dwType, pvData, &cbData); + + /* If the value is a string, we need to read in the whole value to be able + * to know exactly how many bytes are needed after expanding the string and + * ensuring that it is null-terminated. */ + if (is_string(dwType) && + (ret == ERROR_MORE_DATA || + (ret == ERROR_SUCCESS && dwType == REG_EXPAND_SZ && !(dwFlags & RRF_NOEXPAND)) || + (ret == ERROR_SUCCESS && (cbData < sizeof(WCHAR) || (pvData && *((WCHAR *)pvData + cbData / sizeof(WCHAR) - 1)))))) + { + do { + HeapFree(GetProcessHeap(), 0, pvBuf); + + pvBuf = HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR)); + if (!pvBuf) + { + ret = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + if (ret == ERROR_MORE_DATA || !pvData) + ret = RegQueryValueExW(hKey, pszValue, NULL, + &dwType, pvBuf, &cbData); + else + { + /* Even if cbData was large enough we have to copy the + * string since ExpandEnvironmentStrings can't handle + * overlapping buffers. */ + CopyMemory(pvBuf, pvData, cbData); + } + } while (ret == ERROR_MORE_DATA); + + if (ret == ERROR_SUCCESS) + { + /* Ensure null termination */ + if (cbData < sizeof(WCHAR) || *((WCHAR *)pvBuf + cbData / sizeof(WCHAR) - 1)) + { + *((WCHAR *)pvBuf + cbData / sizeof(WCHAR)) = 0; + cbData = sizeof(WCHAR); + } + + /* Recheck dwType in case it changed since the first call */ + if (dwType == REG_EXPAND_SZ && !(dwFlags & RRF_NOEXPAND)) + { + cbData = ExpandEnvironmentStringsW(pvBuf, pvData, + pcbData ? *pcbData : 0) * sizeof(WCHAR); + dwType = REG_SZ; + if (pvData && cbData > *pcbData) + ret = ERROR_MORE_DATA; + } else if (pvData) + { + if (cbData > *pcbData) + ret = ERROR_MORE_DATA; + else + CopyMemory(pvData, pvBuf, cbData); + } + } + + HeapFree(GetProcessHeap(), 0, pvBuf); + } + + if (pszSubKey && pszSubKey[0]) + RegCloseKey(hKey); + + apply_restrictions(dwFlags, dwType, cbData, &ret); + + if (pvData && ret != ERROR_SUCCESS && (dwFlags & RRF_ZEROONFAILURE)) + ZeroMemory(pvData, *pcbData); + + if (pdwType) *pdwType = dwType; + if (pcbData) *pcbData = cbData; + + return ret; +} + +// Prior to Windows 8.1, RegGetValueW does not support using REG_EXPAND_SZ without also using REG_NOEXPAND. +// While it's a minor thing, the launcher for Python 3.11 and above will fail to detect any Python installations. +// Work around this bug. +LSTATUS +WINAPI +RegGetValueWInternal( + HKEY hkey, + LPCWSTR lpSubKey, + LPCWSTR lpValue, + DWORD dwFlags, + LPDWORD pdwType, + PVOID pvData, + LPDWORD pcbData +) +{ + // First, check if the flags conflict. This is completely unsupported prior to Windows 8.1. While it's possible + // to remove the check, it WILL result in issues. + if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & RRF_NOEXPAND)) { + // Call RegGetValueW from PythonWin7, which is confirmed to fix this exact sceneraio. + return Py_RegGetValueW(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData); + } + // Otherwise, call RegGetValueW like normal. + return RegGetValueW(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData); +} + +LSTATUS +WINAPI +RegNotifyChangeKeyValueInternal( + HKEY hKey, + BOOL bWatchSubtree, + DWORD dwNotifyFilter, + HANDLE hEvent, + BOOL fAsynchronous +) +{ + //For fix Dns Error on Electron + return RegNotifyChangeKeyValueNative(hKey, bWatchSubtree, dwNotifyFilter & ~REG_NOTIFY_THREAD_AGNOSTIC, hEvent, fAsynchronous); } \ No newline at end of file diff --git a/wrappers/extensions/advapiex/main.h b/wrappers/extensions/advapiex/main.h index 7e71b4e8f9..6d4dbf268a 100644 --- a/wrappers/extensions/advapiex/main.h +++ b/wrappers/extensions/advapiex/main.h @@ -34,6 +34,26 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +/* + * RegGetValue() restrictions + */ + +#define RRF_RT_REG_NONE (1 << 0) +#define RRF_RT_REG_SZ (1 << 1) +#define RRF_RT_REG_EXPAND_SZ (1 << 2) +#define RRF_RT_REG_BINARY (1 << 3) +#define RRF_RT_REG_DWORD (1 << 4) +#define RRF_RT_REG_MULTI_SZ (1 << 5) +#define RRF_RT_REG_QWORD (1 << 6) +#define RRF_RT_DWORD (RRF_RT_REG_BINARY | RRF_RT_REG_DWORD) +#define RRF_RT_QWORD (RRF_RT_REG_BINARY | RRF_RT_REG_QWORD) +//#define RRF_RT_ANY 0xffff +#define RRF_SUBKEY_WOW6464KEY (1 << 16) +#define RRF_SUBKEY_WOW6432KEY (1 << 17) +#define RRF_WOW64_MASK (RRF_SUBKEY_WOW6432KEY | RRF_SUBKEY_WOW6464KEY) +#define RRF_NOEXPAND (1 << 28) +#define RRF_ZEROONFAILURE (1 << 29) + /* FUNCTIONS ****************************************************************/ FORCEINLINE BOOL @@ -220,6 +240,13 @@ typedef struct _PERF_DATA_HEADER { SYSTEMTIME SystemTime; } PERF_DATA_HEADER, *PPERF_DATA_HEADER; +typedef enum _CRED_PROTECTION_TYPE { + CredUnprotected, + CredUserProtection, + CredTrustedProtection, + CredForSystemProtection +} CRED_PROTECTION_TYPE, *PCRED_PROTECTION_TYPE; + /* memory allocation functions */ static inline WCHAR *strdupAW( const char *src ) diff --git a/wrappers/extensions/advapiex/reg.c b/wrappers/extensions/advapiex/reg.c index 7f23a2c07b..c57c8b88c3 100644 --- a/wrappers/extensions/advapiex/reg.c +++ b/wrappers/extensions/advapiex/reg.c @@ -1266,8 +1266,7 @@ LSTATUS WINAPI RegLoadAppKeyA(const char *file, HKEY *result, REGSAM sam, DWORD if (!file || reserved) return ERROR_INVALID_PARAMETER; - *result = (HKEY)0xdeadbeef; - return ERROR_SUCCESS; + return RegOpenKeyExA(HKEY_CURRENT_USER, "", KEY_ALL_ACCESS, 0, result); } /****************************************************************************** @@ -1281,8 +1280,7 @@ LSTATUS WINAPI RegLoadAppKeyW(const WCHAR *file, HKEY *result, REGSAM sam, DWORD if (!file || reserved) return ERROR_INVALID_PARAMETER; - *result = (HKEY)0xdeadbeef; - return ERROR_SUCCESS; + return RegOpenKeyExW(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS, 0, result); } LSTATUS diff --git a/wrappers/extensions/advapiex/security.c b/wrappers/extensions/advapiex/security.c index 52528c02d3..1b00f1344e 100644 --- a/wrappers/extensions/advapiex/security.c +++ b/wrappers/extensions/advapiex/security.c @@ -56,17 +56,6 @@ AddMandatoryAce( return result; } -BOOL CredUnprotectW( - BOOL fAsSelf, - LPWSTR pszProtectedCredentials, - DWORD cchProtectedCredentials, - LPWSTR pszCredentials, - DWORD *pcchMaxChars -) -{ - return FALSE; -} - /* * @implemented */ diff --git a/wrappers/extensions/bcryptext/CMakeLists.txt b/wrappers/extensions/bcryptext/CMakeLists.txt index ca2a353d1f..ba6b372046 100644 --- a/wrappers/extensions/bcryptext/CMakeLists.txt +++ b/wrappers/extensions/bcryptext/CMakeLists.txt @@ -13,5 +13,5 @@ list(APPEND SOURCE add_library(bcryptext SHARED ${SOURCE}) set_module_type(bcryptext win32dll) target_link_libraries(bcryptext wine) -add_importlibs(bcryptext advapi32 msvcrt kernel32 ntdll) +add_importlibs(bcryptext bcrypt advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET bcryptext DESTINATION reactos/system32 FOR all) \ No newline at end of file diff --git a/wrappers/extensions/bcryptext/bcryptext.spec b/wrappers/extensions/bcryptext/bcryptext.spec index 0b159c924e..3f8abe6f1a 100644 --- a/wrappers/extensions/bcryptext/bcryptext.spec +++ b/wrappers/extensions/bcryptext/bcryptext.spec @@ -1,61 +1,3 @@ -; @ stdcall BCryptAddContextFunction(long wstr long wstr long) -; @ stdcall BCryptAddContextFunctionProvider(long wstr long wstr wstr long) -; @ stdcall BCryptCloseAlgorithmProvider(ptr long) -; @ stub BCryptConfigureContext -; @ stub BCryptConfigureContextFunction -; @ stub BCryptCreateContext -; @ stdcall BCryptCreateHash(ptr ptr ptr long ptr long long) -; @ stdcall BCryptDecrypt(ptr ptr long ptr ptr long ptr long ptr long) -; @ stub BCryptDeleteContext -; @ stdcall BCryptDeriveKey(ptr wstr ptr ptr long ptr long) @ stdcall BCryptDeriveKeyCapi(ptr ptr ptr long long) @ stdcall BCryptDeriveKeyPBKDF2(ptr ptr long ptr long int64 ptr long long) -; @ stdcall BCryptDestroyHash(ptr) -; @ stdcall BCryptDestroyKey(ptr) -; @ stdcall BCryptDestroySecret(ptr) -; @ stdcall BCryptDuplicateHash(ptr ptr ptr long long) -; @ stdcall BCryptDuplicateKey(ptr ptr ptr long long) -; @ stdcall BCryptEncrypt(ptr ptr long ptr ptr long ptr long ptr long) -; @ stdcall BCryptEnumAlgorithms(long ptr ptr long) -; @ stub BCryptEnumContextFunctionProviders -; @ stdcall BCryptEnumContextFunctions(long wstr long ptr ptr) -; @ stub BCryptEnumContexts -; @ stub BCryptEnumProviders -; @ stub BCryptEnumRegisteredProviders -; @ stdcall BCryptExportKey(ptr ptr wstr ptr long ptr long) -; @ stdcall BCryptFinalizeKeyPair(ptr long) -; @ stdcall BCryptFinishHash(ptr ptr long long) -; @ stdcall BCryptFreeBuffer(ptr) -; @ stdcall BCryptGenRandom(ptr ptr long long) -; @ stdcall BCryptGenerateKeyPair(ptr ptr long long) -; @ stdcall BCryptGenerateSymmetricKey(ptr ptr ptr long ptr long long) -; @ stdcall BCryptGetFipsAlgorithmMode(ptr) -; @ stdcall BCryptGetProperty(ptr wstr ptr long ptr long) -@ stdcall BCryptHash(ptr ptr long ptr long ptr long) -; @ stdcall BCryptHashData(ptr ptr long long) -; @ stdcall BCryptImportKey(ptr ptr wstr ptr ptr long ptr long long) -; @ stdcall BCryptImportKeyPair(ptr ptr wstr ptr ptr long long) -; @ stdcall BCryptOpenAlgorithmProvider(ptr wstr wstr long) -; @ stub BCryptQueryContextConfiguration -; @ stub BCryptQueryContextFunctionConfiguration -; @ stub BCryptQueryContextFunctionProperty -; @ stub BCryptQueryProviderRegistration -; @ stub BCryptRegisterConfigChangeNotify -; @ stdcall BCryptRegisterProvider(wstr long ptr) -; @ stdcall BCryptRemoveContextFunction(long wstr long wstr) -; @ stdcall BCryptRemoveContextFunctionProvider(long wstr long wstr wstr) -; @ stub BCryptResolveProviders -; @ stdcall BCryptSecretAgreement(ptr ptr ptr long) -; @ stub BCryptSetAuditingInterface -; @ stub BCryptSetContextFunctionProperty -; @ stdcall BCryptSetProperty(ptr wstr ptr long long) -; @ stdcall BCryptSignHash(ptr ptr ptr long ptr long ptr long) -; @ stub BCryptUnregisterConfigChangeNotify -; @ stdcall BCryptUnregisterProvider(wstr) -; @ stdcall BCryptVerifySignature(ptr ptr ptr long ptr long long) -; @ stub GetAsymmetricEncryptionInterface -; @ stub GetCipherInterface -; @ stub GetHashInterface -; @ stub GetRngInterface -; @ stub GetSecretAgreementInterface -; @ stub GetSignatureInterface +@ stdcall BCryptCreateHash(ptr ptr ptr long ptr long long) BCryptCreateHashInternal \ No newline at end of file diff --git a/wrappers/extensions/bcryptext/main.c b/wrappers/extensions/bcryptext/main.c index e92d466275..33c07cbfcf 100644 --- a/wrappers/extensions/bcryptext/main.c +++ b/wrappers/extensions/bcryptext/main.c @@ -33,1960 +33,53 @@ #include "wine/debug.h" #include "wine/heap.h" -WINE_DEFAULT_DEBUG_CHANNEL(bcrypt); - -// static HINSTANCE instance; - -// static const struct key_funcs *key_funcs; - -// NTSTATUS WINAPI BCryptAddContextFunction(ULONG table, LPCWSTR context, ULONG iface, LPCWSTR function, ULONG pos) -// { - // FIXME("%08x, %s, %08x, %s, %u: stub\n", table, debugstr_w(context), iface, debugstr_w(function), pos); - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptAddContextFunctionProvider(ULONG table, LPCWSTR context, ULONG iface, LPCWSTR function, LPCWSTR provider, ULONG pos) -// { - // FIXME("%08x, %s, %08x, %s, %s, %u: stub\n", table, debugstr_w(context), iface, debugstr_w(function), debugstr_w(provider), pos); - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptRemoveContextFunction(ULONG table, LPCWSTR context, ULONG iface, LPCWSTR function) -// { - // FIXME("%08x, %s, %08x, %s: stub\n", table, debugstr_w(context), iface, debugstr_w(function)); - // return STATUS_NOT_IMPLEMENTED; -// } - -// NTSTATUS WINAPI BCryptRemoveContextFunctionProvider(ULONG table, LPCWSTR context, ULONG iface, LPCWSTR function, LPCWSTR provider) -// { - // FIXME("%08x, %s, %08x, %s, %s: stub\n", table, debugstr_w(context), iface, debugstr_w(function), debugstr_w(provider)); - // return STATUS_NOT_IMPLEMENTED; -// } - -// NTSTATUS WINAPI BCryptEnumContextFunctions( ULONG table, const WCHAR *ctx, ULONG iface, ULONG *buflen, - // CRYPT_CONTEXT_FUNCTIONS **buffer ) -// { - // FIXME( "%u, %s, %u, %p, %p\n", table, debugstr_w(ctx), iface, buflen, buffer ); - // return STATUS_NOT_IMPLEMENTED; -// } - -// void WINAPI BCryptFreeBuffer( void *buffer ) -// { - // FIXME( "%p\n", buffer ); -// } - -// NTSTATUS WINAPI BCryptRegisterProvider(LPCWSTR provider, ULONG flags, PCRYPT_PROVIDER_REG reg) -// { - // FIXME("%s, %08x, %p: stub\n", debugstr_w(provider), flags, reg); - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptUnregisterProvider(LPCWSTR provider) -// { - // FIXME("%s: stub\n", debugstr_w(provider)); - // return STATUS_NOT_IMPLEMENTED; -// } - -// #define MAX_HASH_OUTPUT_BYTES 64 -// #define MAX_HASH_BLOCK_BITS 1024 - -// /* ordered by class, keep in sync with enum alg_id */ -// static const struct -// { - // const WCHAR *name; - // ULONG class; - // ULONG object_length; - // ULONG hash_length; - // ULONG block_bits; -// } -// builtin_algorithms[] = -// { - // { BCRYPT_3DES_ALGORITHM, BCRYPT_CIPHER_INTERFACE, 522, 0, 0 }, - // { BCRYPT_AES_ALGORITHM, BCRYPT_CIPHER_INTERFACE, 654, 0, 0 }, - // { BCRYPT_SHA256_ALGORITHM, BCRYPT_HASH_INTERFACE, 286, 32, 512 }, - // { BCRYPT_SHA384_ALGORITHM, BCRYPT_HASH_INTERFACE, 382, 48, 1024 }, - // { BCRYPT_SHA512_ALGORITHM, BCRYPT_HASH_INTERFACE, 382, 64, 1024 }, - // { BCRYPT_SHA1_ALGORITHM, BCRYPT_HASH_INTERFACE, 278, 20, 512 }, - // { BCRYPT_MD5_ALGORITHM, BCRYPT_HASH_INTERFACE, 274, 16, 512 }, - // { BCRYPT_MD4_ALGORITHM, BCRYPT_HASH_INTERFACE, 270, 16, 512 }, - // { BCRYPT_MD2_ALGORITHM, BCRYPT_HASH_INTERFACE, 270, 16, 128 }, - // { BCRYPT_RSA_ALGORITHM, BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE, 0, 0, 0 }, - // { BCRYPT_ECDH_P256_ALGORITHM, BCRYPT_SECRET_AGREEMENT_INTERFACE, 0, 0, 0 }, - // { BCRYPT_RSA_SIGN_ALGORITHM, BCRYPT_SIGNATURE_INTERFACE, 0, 0, 0 }, - // { BCRYPT_ECDSA_P256_ALGORITHM, BCRYPT_SIGNATURE_INTERFACE, 0, 0, 0 }, - // { BCRYPT_ECDSA_P384_ALGORITHM, BCRYPT_SIGNATURE_INTERFACE, 0, 0, 0 }, - // { BCRYPT_DSA_ALGORITHM, BCRYPT_SIGNATURE_INTERFACE, 0, 0, 0 }, - // { BCRYPT_RNG_ALGORITHM, BCRYPT_RNG_INTERFACE, 0, 0, 0 }, -// }; - -// static BOOL match_operation_type( ULONG type, ULONG class ) -// { - // if (!type) return TRUE; - // switch (class) - // { - // case BCRYPT_CIPHER_INTERFACE: return type & BCRYPT_CIPHER_OPERATION; - // case BCRYPT_HASH_INTERFACE: return type & BCRYPT_HASH_OPERATION; - // case BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE: return type & BCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION; - // case BCRYPT_SECRET_AGREEMENT_INTERFACE: return type & BCRYPT_SECRET_AGREEMENT_OPERATION; - // case BCRYPT_SIGNATURE_INTERFACE: return type & BCRYPT_SIGNATURE_OPERATION; - // case BCRYPT_RNG_INTERFACE: return type & BCRYPT_RNG_OPERATION; - // default: break; - // } - // return FALSE; -// } - -// NTSTATUS WINAPI BCryptEnumAlgorithms( ULONG type, ULONG *ret_count, BCRYPT_ALGORITHM_IDENTIFIER **ret_list, ULONG flags ) -// { - // static const ULONG supported = BCRYPT_CIPHER_OPERATION |\ - // BCRYPT_HASH_OPERATION |\ - // BCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION |\ - // BCRYPT_SECRET_AGREEMENT_OPERATION |\ - // BCRYPT_SIGNATURE_OPERATION |\ - // BCRYPT_RNG_OPERATION; - // BCRYPT_ALGORITHM_IDENTIFIER *list; - // ULONG i, count = 0; - - // TRACE( "%08x, %p, %p, %08x\n", type, ret_count, ret_list, flags ); - - // if (!ret_count || !ret_list || (type & ~supported)) return STATUS_INVALID_PARAMETER; - - // for (i = 0; i < ARRAY_SIZE( builtin_algorithms ); i++) - // { - // if (match_operation_type( type, builtin_algorithms[i].class )) count++; - // } - - // if (!(list = heap_alloc( count * sizeof(*list) ))) return STATUS_NO_MEMORY; - - // for (i = 0; i < ARRAY_SIZE( builtin_algorithms ); i++) - // { - // if (!match_operation_type( type, builtin_algorithms[i].class )) continue; - // list[i].pszName = (WCHAR *)builtin_algorithms[i].name; - // list[i].dwClass = builtin_algorithms[i].class; - // list[i].dwFlags = 0; - // } - - // *ret_count = count; - // *ret_list = list; - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE handle, UCHAR *buffer, ULONG count, ULONG flags) -// { - // const DWORD supported_flags = BCRYPT_USE_SYSTEM_PREFERRED_RNG; - // struct algorithm *algorithm = handle; - - // TRACE("%p, %p, %u, %08x - semi-stub\n", handle, buffer, count, flags); - - // if (!algorithm) - // { - // /* It's valid to call without an algorithm if BCRYPT_USE_SYSTEM_PREFERRED_RNG - // * is set. In this case the preferred system RNG is used. - // */ - // if (!(flags & BCRYPT_USE_SYSTEM_PREFERRED_RNG)) - // return STATUS_INVALID_HANDLE; - // } - // else if (algorithm->hdr.magic != MAGIC_ALG || algorithm->id != ALG_ID_RNG) - // return STATUS_INVALID_HANDLE; - - // if (!buffer) - // return STATUS_INVALID_PARAMETER; - - // if (flags & ~supported_flags) - // FIXME("unsupported flags %08x\n", flags & ~supported_flags); - - // if (algorithm) - // FIXME("ignoring selected algorithm\n"); - - // /* When zero bytes are requested the function returns success too. */ - // if (!count) - // return STATUS_SUCCESS; - - // if (algorithm || (flags & BCRYPT_USE_SYSTEM_PREFERRED_RNG)) - // { - // if (RtlGenRandom(buffer, count)) - // return STATUS_SUCCESS; - // } - - // FIXME("called with unsupported parameters, returning error\n"); - // return STATUS_NOT_IMPLEMENTED; -// } - -// NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR id, LPCWSTR implementation, DWORD flags ) -// { - // const DWORD supported_flags = BCRYPT_ALG_HANDLE_HMAC_FLAG | BCRYPT_HASH_REUSABLE_FLAG; - // struct algorithm *alg; - // enum alg_id alg_id; - // ULONG i; - - // TRACE( "%p, %s, %s, %08x\n", handle, wine_dbgstr_w(id), wine_dbgstr_w(implementation), flags ); - - // if (!handle || !id) return STATUS_INVALID_PARAMETER; - // if (flags & ~supported_flags) - // { - // FIXME( "unsupported flags %08x\n", flags & ~supported_flags); - // return STATUS_NOT_IMPLEMENTED; - // } - - // for (i = 0; i < ARRAY_SIZE( builtin_algorithms ); i++) - // { - // if (!wcscmp( id, builtin_algorithms[i].name)) - // { - // alg_id = i; - // break; - // } - // } - // if (i == ARRAY_SIZE( builtin_algorithms )) - // { - // FIXME( "algorithm %s not supported\n", debugstr_w(id) ); - // return STATUS_NOT_IMPLEMENTED; - // } - - // if (implementation && wcscmp( implementation, MS_PRIMITIVE_PROVIDER )) - // { - // FIXME( "implementation %s not supported\n", debugstr_w(implementation) ); - // return STATUS_NOT_IMPLEMENTED; - // } - - // if (!(alg = heap_alloc( sizeof(*alg) ))) return STATUS_NO_MEMORY; - // alg->hdr.magic = MAGIC_ALG; - // alg->id = alg_id; - // alg->mode = MODE_ID_CBC; - // alg->flags = flags; - - // *handle = alg; - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptCloseAlgorithmProvider( BCRYPT_ALG_HANDLE handle, DWORD flags ) -// { - // struct algorithm *alg = handle; - - // TRACE( "%p, %08x\n", handle, flags ); - - // if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE; - // alg->hdr.magic = 0; - // heap_free( alg ); - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptGetFipsAlgorithmMode(BOOLEAN *enabled) -// { - // FIXME("%p - semi-stub\n", enabled); - - // if (!enabled) - // return STATUS_INVALID_PARAMETER; - - // *enabled = FALSE; - // return STATUS_SUCCESS; -// } - -// struct hash_impl -// { - // union - // { - // MD2_CTX md2; - // MD4_CTX md4; - // MD5_CTX md5; - // SHA_CTX sha1; - // SHA256_CTX sha256; - // SHA512_CTX sha512; - // } u; -// }; - -// static NTSTATUS hash_init( struct hash_impl *hash, enum alg_id alg_id ) -// { - // switch (alg_id) - // { - // case ALG_ID_MD2: - // md2_init( &hash->u.md2 ); - // break; - - // case ALG_ID_MD4: - // MD4Init( &hash->u.md4 ); - // break; - - // case ALG_ID_MD5: - // MD5Init( &hash->u.md5 ); - // break; - - // case ALG_ID_SHA1: - // A_SHAInit( &hash->u.sha1 ); - // break; - - // case ALG_ID_SHA256: - // sha256_init( &hash->u.sha256 ); - // break; - - // case ALG_ID_SHA384: - // sha384_init( &hash->u.sha512 ); - // break; - - // case ALG_ID_SHA512: - // sha512_init( &hash->u.sha512 ); - // break; - - // default: - // ERR( "unhandled id %u\n", alg_id ); - // return STATUS_NOT_IMPLEMENTED; - // } - // return STATUS_SUCCESS; -// } - -// static NTSTATUS hash_update( struct hash_impl *hash, enum alg_id alg_id, - // UCHAR *input, ULONG size ) -// { - // switch (alg_id) - // { - // case ALG_ID_MD2: - // md2_update( &hash->u.md2, input, size ); - // break; - - // case ALG_ID_MD4: - // MD4Update( &hash->u.md4, input, size ); - // break; - - // case ALG_ID_MD5: - // MD5Update( &hash->u.md5, input, size ); - // break; - - // case ALG_ID_SHA1: - // A_SHAUpdate( &hash->u.sha1, input, size ); - // break; - - // case ALG_ID_SHA256: - // sha256_update( &hash->u.sha256, input, size ); - // break; - - // case ALG_ID_SHA384: - // sha384_update( &hash->u.sha512, input, size ); - // break; - - // case ALG_ID_SHA512: - // sha512_update( &hash->u.sha512, input, size ); - // break; - - // default: - // ERR( "unhandled id %u\n", alg_id ); - // return STATUS_NOT_IMPLEMENTED; - // } - // return STATUS_SUCCESS; -// } - -// static NTSTATUS hash_finish( struct hash_impl *hash, enum alg_id alg_id, - // UCHAR *output, ULONG size ) -// { - // switch (alg_id) - // { - // case ALG_ID_MD2: - // md2_finalize( &hash->u.md2, output ); - // break; - - // case ALG_ID_MD4: - // MD4Final( &hash->u.md4 ); - // memcpy( output, hash->u.md4.digest, 16 ); - // break; - - // case ALG_ID_MD5: - // MD5Final( &hash->u.md5 ); - // memcpy( output, hash->u.md5.digest, 16 ); - // break; - - // case ALG_ID_SHA1: - // A_SHAFinal( &hash->u.sha1, (ULONG *)output ); - // break; - - // case ALG_ID_SHA256: - // sha256_finalize( &hash->u.sha256, output ); - // break; - - // case ALG_ID_SHA384: - // sha384_finalize( &hash->u.sha512, output ); - // break; - - // case ALG_ID_SHA512: - // sha512_finalize( &hash->u.sha512, output ); - // break; - - // default: - // ERR( "unhandled id %u\n", alg_id ); - // return STATUS_NOT_IMPLEMENTED; - // } - // return STATUS_SUCCESS; -// } - -// #define HASH_FLAG_HMAC 0x01 -// #define HASH_FLAG_REUSABLE 0x02 -// struct hash -// { - // struct object hdr; - // enum alg_id alg_id; - // ULONG flags; - // UCHAR *secret; - // ULONG secret_len; - // struct hash_impl outer; - // struct hash_impl inner; -// }; - -// #define BLOCK_LENGTH_3DES 8 -// #define BLOCK_LENGTH_AES 16 - -// static NTSTATUS generic_alg_property( enum alg_id id, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) -// { - // if (!wcscmp( prop, BCRYPT_OBJECT_LENGTH )) - // { - // if (!builtin_algorithms[id].object_length) - // return STATUS_NOT_SUPPORTED; - // *ret_size = sizeof(ULONG); - // if (size < sizeof(ULONG)) - // return STATUS_BUFFER_TOO_SMALL; - // if (buf) - // *(ULONG *)buf = builtin_algorithms[id].object_length; - // return STATUS_SUCCESS; - // } - - // if (!wcscmp( prop, BCRYPT_HASH_LENGTH )) - // { - // if (!builtin_algorithms[id].hash_length) - // return STATUS_NOT_SUPPORTED; - // *ret_size = sizeof(ULONG); - // if (size < sizeof(ULONG)) - // return STATUS_BUFFER_TOO_SMALL; - // if(buf) - // *(ULONG*)buf = builtin_algorithms[id].hash_length; - // return STATUS_SUCCESS; - // } - - // if (!wcscmp( prop, BCRYPT_ALGORITHM_NAME )) - // { - // *ret_size = (lstrlenW(builtin_algorithms[id].name) + 1) * sizeof(WCHAR); - // if (size < *ret_size) - // return STATUS_BUFFER_TOO_SMALL; - // if(buf) - // memcpy(buf, builtin_algorithms[id].name, *ret_size); - // return STATUS_SUCCESS; - // } - - // return STATUS_NOT_IMPLEMENTED; -// } - -// static NTSTATUS get_3des_property( enum mode_id mode, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) -// { - // if (!wcscmp( prop, BCRYPT_BLOCK_LENGTH )) - // { - // *ret_size = sizeof(ULONG); - // if (size < sizeof(ULONG)) return STATUS_BUFFER_TOO_SMALL; - // if (buf) *(ULONG *)buf = BLOCK_LENGTH_3DES; - // return STATUS_SUCCESS; - // } - // if (!wcscmp( prop, BCRYPT_CHAINING_MODE )) - // { - // const WCHAR *str; - // switch (mode) - // { - // case MODE_ID_CBC: str = BCRYPT_CHAIN_MODE_CBC; break; - // default: return STATUS_NOT_IMPLEMENTED; - // } - - // *ret_size = 64; - // if (size < *ret_size) return STATUS_BUFFER_TOO_SMALL; - // memcpy( buf, str, (lstrlenW(str) + 1) * sizeof(WCHAR) ); - // return STATUS_SUCCESS; - // } - // if (!wcscmp( prop, BCRYPT_KEY_LENGTHS )) - // { - // BCRYPT_KEY_LENGTHS_STRUCT *key_lengths = (void *)buf; - // *ret_size = sizeof(*key_lengths); - // if (key_lengths && size < *ret_size) return STATUS_BUFFER_TOO_SMALL; - // if (key_lengths) - // { - // key_lengths->dwMinLength = 192; - // key_lengths->dwMaxLength = 192; - // key_lengths->dwIncrement = 0; - // } - // return STATUS_SUCCESS; - // } - // FIXME( "unsupported property %s\n", debugstr_w(prop) ); - // return STATUS_NOT_IMPLEMENTED; -// } - -// static NTSTATUS get_aes_property( enum mode_id mode, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) -// { - // if (!wcscmp( prop, BCRYPT_BLOCK_LENGTH )) - // { - // *ret_size = sizeof(ULONG); - // if (size < sizeof(ULONG)) return STATUS_BUFFER_TOO_SMALL; - // if (buf) *(ULONG *)buf = BLOCK_LENGTH_AES; - // return STATUS_SUCCESS; - // } - // if (!wcscmp( prop, BCRYPT_CHAINING_MODE )) - // { - // const WCHAR *str; - // switch (mode) - // { - // case MODE_ID_ECB: str = BCRYPT_CHAIN_MODE_ECB; break; - // case MODE_ID_CBC: str = BCRYPT_CHAIN_MODE_CBC; break; - // case MODE_ID_GCM: str = BCRYPT_CHAIN_MODE_GCM; break; - // default: return STATUS_NOT_IMPLEMENTED; - // } - - // *ret_size = 64; - // if (size < *ret_size) return STATUS_BUFFER_TOO_SMALL; - // memcpy( buf, str, (lstrlenW(str) + 1) * sizeof(WCHAR) ); - // return STATUS_SUCCESS; - // } - // if (!wcscmp( prop, BCRYPT_KEY_LENGTHS )) - // { - // BCRYPT_KEY_LENGTHS_STRUCT *key_lengths = (void *)buf; - // *ret_size = sizeof(*key_lengths); - // if (key_lengths && size < *ret_size) return STATUS_BUFFER_TOO_SMALL; - // if (key_lengths) - // { - // key_lengths->dwMinLength = 128; - // key_lengths->dwMaxLength = 256; - // key_lengths->dwIncrement = 64; - // } - // return STATUS_SUCCESS; - // } - // if (!wcscmp( prop, BCRYPT_AUTH_TAG_LENGTH )) - // { - // BCRYPT_AUTH_TAG_LENGTHS_STRUCT *tag_length = (void *)buf; - // if (mode != MODE_ID_GCM) return STATUS_NOT_SUPPORTED; - // *ret_size = sizeof(*tag_length); - // if (tag_length && size < *ret_size) return STATUS_BUFFER_TOO_SMALL; - // if (tag_length) - // { - // tag_length->dwMinLength = 12; - // tag_length->dwMaxLength = 16; - // tag_length->dwIncrement = 1; - // } - // return STATUS_SUCCESS; - // } - - // FIXME( "unsupported property %s\n", debugstr_w(prop) ); - // return STATUS_NOT_IMPLEMENTED; -// } - -// static NTSTATUS get_rsa_property( enum mode_id mode, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) -// { - // if (!wcscmp( prop, BCRYPT_PADDING_SCHEMES )) - // { - // *ret_size = sizeof(ULONG); - // if (size < sizeof(ULONG)) return STATUS_BUFFER_TOO_SMALL; - // if (buf) *(ULONG *)buf = BCRYPT_SUPPORTED_PAD_PKCS1_SIG; - // return STATUS_SUCCESS; - // } - - // FIXME( "unsupported property %s\n", debugstr_w(prop) ); - // return STATUS_NOT_IMPLEMENTED; -// } - -// static NTSTATUS get_dsa_property( enum mode_id mode, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) -// { - // if (!wcscmp( prop, BCRYPT_PADDING_SCHEMES )) return STATUS_NOT_SUPPORTED; - // FIXME( "unsupported property %s\n", debugstr_w(prop) ); - // return STATUS_NOT_IMPLEMENTED; -// } - -// static NTSTATUS get_alg_property( const struct algorithm *alg, const WCHAR *prop, - // UCHAR *buf, ULONG size, ULONG *ret_size ) -// { - // NTSTATUS status; - - // status = generic_alg_property( alg->id, prop, buf, size, ret_size ); - // if (status != STATUS_NOT_IMPLEMENTED) - // return status; - - // switch (alg->id) - // { - // case ALG_ID_3DES: - // return get_3des_property( alg->mode, prop, buf, size, ret_size ); - - // case ALG_ID_AES: - // return get_aes_property( alg->mode, prop, buf, size, ret_size ); - - // case ALG_ID_RSA: - // return get_rsa_property( alg->mode, prop, buf, size, ret_size ); - - // case ALG_ID_DSA: - // return get_dsa_property( alg->mode, prop, buf, size, ret_size ); - - // default: - // break; - // } - - // FIXME( "unsupported property %s algorithm %u\n", debugstr_w(prop), alg->id ); - // return STATUS_NOT_IMPLEMENTED; -// } - -// static NTSTATUS set_alg_property( struct algorithm *alg, const WCHAR *prop, UCHAR *value, ULONG size, ULONG flags ) -// { - // switch (alg->id) - // { - // case ALG_ID_3DES: - // if (!wcscmp( prop, BCRYPT_CHAINING_MODE )) - // { - // if (!wcscmp( (WCHAR *)value, BCRYPT_CHAIN_MODE_CBC )) - // { - // alg->mode = MODE_ID_CBC; - // return STATUS_SUCCESS; - // } - // else - // { - // FIXME( "unsupported mode %s\n", debugstr_w((WCHAR *)value) ); - // return STATUS_NOT_SUPPORTED; - // } - // } - // FIXME( "unsupported 3des algorithm property %s\n", debugstr_w(prop) ); - // return STATUS_NOT_IMPLEMENTED; - - // case ALG_ID_AES: - // if (!wcscmp( prop, BCRYPT_CHAINING_MODE )) - // { - // if (!wcscmp( (WCHAR *)value, BCRYPT_CHAIN_MODE_ECB )) - // { - // alg->mode = MODE_ID_ECB; - // return STATUS_SUCCESS; - // } - // else if (!wcscmp( (WCHAR *)value, BCRYPT_CHAIN_MODE_CBC )) - // { - // alg->mode = MODE_ID_CBC; - // return STATUS_SUCCESS; - // } - // else if (!wcscmp( (WCHAR *)value, BCRYPT_CHAIN_MODE_GCM )) - // { - // alg->mode = MODE_ID_GCM; - // return STATUS_SUCCESS; - // } - // else - // { - // FIXME( "unsupported mode %s\n", debugstr_w((WCHAR *)value) ); - // return STATUS_NOT_IMPLEMENTED; - // } - // } - // FIXME( "unsupported aes algorithm property %s\n", debugstr_w(prop) ); - // return STATUS_NOT_IMPLEMENTED; - - // default: - // FIXME( "unsupported algorithm %u\n", alg->id ); - // return STATUS_NOT_IMPLEMENTED; - // } -// } - -// static NTSTATUS get_hash_property( const struct hash *hash, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) -// { - // NTSTATUS status; - - // status = generic_alg_property( hash->alg_id, prop, buf, size, ret_size ); - // if (status == STATUS_NOT_IMPLEMENTED) - // FIXME( "unsupported property %s\n", debugstr_w(prop) ); - // return status; -// } - -// static NTSTATUS get_key_property( const struct key *key, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) -// { - // switch (key->alg_id) - // { - // case ALG_ID_3DES: - // return get_3des_property( key->u.s.mode, prop, buf, size, ret_size ); - - // case ALG_ID_AES: - // if (!wcscmp( prop, BCRYPT_AUTH_TAG_LENGTH )) return STATUS_NOT_SUPPORTED; - // return get_aes_property( key->u.s.mode, prop, buf, size, ret_size ); - - // default: - // FIXME( "unsupported algorithm %u\n", key->alg_id ); - // return STATUS_NOT_IMPLEMENTED; - // } -// } - -// NTSTATUS WINAPI BCryptGetProperty( BCRYPT_HANDLE handle, LPCWSTR prop, UCHAR *buffer, ULONG count, ULONG *res, ULONG flags ) -// { - // struct object *object = handle; - - // TRACE( "%p, %s, %p, %u, %p, %08x\n", handle, wine_dbgstr_w(prop), buffer, count, res, flags ); - - // if (!object) return STATUS_INVALID_HANDLE; - // if (!prop || !res) return STATUS_INVALID_PARAMETER; - - // switch (object->magic) - // { - // case MAGIC_ALG: - // { - // const struct algorithm *alg = (const struct algorithm *)object; - // return get_alg_property( alg, prop, buffer, count, res ); - // } - // case MAGIC_KEY: - // { - // const struct key *key = (const struct key *)object; - // return get_key_property( key, prop, buffer, count, res ); - // } - // case MAGIC_HASH: - // { - // const struct hash *hash = (const struct hash *)object; - // return get_hash_property( hash, prop, buffer, count, res ); - // } - // default: - // WARN( "unknown magic %08x\n", object->magic ); - // return STATUS_INVALID_HANDLE; - // } -// } - -// static NTSTATUS hash_prepare( struct hash *hash ) -// { - // UCHAR buffer[MAX_HASH_BLOCK_BITS / 8] = {0}; - // int block_bytes, i; - // NTSTATUS status; - - // /* initialize hash */ - // if ((status = hash_init( &hash->inner, hash->alg_id ))) return status; - // if (!(hash->flags & HASH_FLAG_HMAC)) return STATUS_SUCCESS; - - // /* initialize hmac */ - // if ((status = hash_init( &hash->outer, hash->alg_id ))) return status; - // block_bytes = builtin_algorithms[hash->alg_id].block_bits / 8; - // if (hash->secret_len > block_bytes) - // { - // struct hash_impl temp; - // if ((status = hash_init( &temp, hash->alg_id ))) return status; - // if ((status = hash_update( &temp, hash->alg_id, hash->secret, hash->secret_len ))) return status; - // if ((status = hash_finish( &temp, hash->alg_id, buffer, - // builtin_algorithms[hash->alg_id].hash_length ))) return status; - // } - // else memcpy( buffer, hash->secret, hash->secret_len ); - - // for (i = 0; i < block_bytes; i++) buffer[i] ^= 0x5c; - // if ((status = hash_update( &hash->outer, hash->alg_id, buffer, block_bytes ))) return status; - // for (i = 0; i < block_bytes; i++) buffer[i] ^= (0x5c ^ 0x36); - // return hash_update( &hash->inner, hash->alg_id, buffer, block_bytes ); -// } - -// static NTSTATUS hash_create( const struct algorithm *alg, UCHAR *secret, ULONG secret_len, ULONG flags, - // struct hash **ret_hash ) -// { - // struct hash *hash; - // NTSTATUS status; - - // if (!(hash = heap_alloc_zero( sizeof(*hash) ))) return STATUS_NO_MEMORY; - // hash->hdr.magic = MAGIC_HASH; - // hash->alg_id = alg->id; - // if (alg->flags & BCRYPT_ALG_HANDLE_HMAC_FLAG) hash->flags = HASH_FLAG_HMAC; - // if ((alg->flags & BCRYPT_HASH_REUSABLE_FLAG) || (flags & BCRYPT_HASH_REUSABLE_FLAG)) - // hash->flags |= HASH_FLAG_REUSABLE; - - // if (secret_len && !(hash->secret = heap_alloc( secret_len ))) - // { - // heap_free( hash ); - // return STATUS_NO_MEMORY; - // } - // memcpy( hash->secret, secret, secret_len ); - // hash->secret_len = secret_len; - - // if ((status = hash_prepare( hash ))) - // { - // heap_free( hash->secret ); - // heap_free( hash ); - // return status; - // } - - // *ret_hash = hash; - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptCreateHash( BCRYPT_ALG_HANDLE algorithm, BCRYPT_HASH_HANDLE *handle, UCHAR *object, - // ULONG object_len, UCHAR *secret, ULONG secret_len, ULONG flags ) -// { - // struct algorithm *alg = algorithm; - // struct hash *hash; - // NTSTATUS status; - - // TRACE( "%p, %p, %p, %u, %p, %u, %08x\n", algorithm, handle, object, object_len, - // secret, secret_len, flags ); - // if (flags & ~BCRYPT_HASH_REUSABLE_FLAG) - // { - // FIXME( "unimplemented flags %08x\n", flags ); - // return STATUS_NOT_IMPLEMENTED; - // } - - // if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE; - // if (object) FIXME( "ignoring object buffer\n" ); - - // if ((status = hash_create( alg, secret, secret_len, flags, &hash ))) return status; - // *handle = hash; - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptDuplicateHash( BCRYPT_HASH_HANDLE handle, BCRYPT_HASH_HANDLE *handle_copy, - // UCHAR *object, ULONG objectlen, ULONG flags ) -// { - // struct hash *hash_orig = handle; - // struct hash *hash_copy; - - // TRACE( "%p, %p, %p, %u, %u\n", handle, handle_copy, object, objectlen, flags ); - - // if (!hash_orig || hash_orig->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE; - // if (!handle_copy) return STATUS_INVALID_PARAMETER; - // if (object) FIXME( "ignoring object buffer\n" ); - - // if (!(hash_copy = heap_alloc( sizeof(*hash_copy) ))) - // return STATUS_NO_MEMORY; - - // memcpy( hash_copy, hash_orig, sizeof(*hash_orig) ); - // if (hash_orig->secret && !(hash_copy->secret = heap_alloc( hash_orig->secret_len ))) - // { - // heap_free( hash_copy ); - // return STATUS_NO_MEMORY; - // } - // memcpy( hash_copy->secret, hash_orig->secret, hash_orig->secret_len ); - - // *handle_copy = hash_copy; - // return STATUS_SUCCESS; -// } - -// static void hash_destroy( struct hash *hash ) -// { - // if (!hash) return; - // hash->hdr.magic = 0; - // heap_free( hash->secret ); - // heap_free( hash ); -// } - -// NTSTATUS WINAPI BCryptDestroyHash( BCRYPT_HASH_HANDLE handle ) -// { - // struct hash *hash = handle; - - // TRACE( "%p\n", handle ); - - // if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_PARAMETER; - // hash_destroy( hash ); - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptHashData( BCRYPT_HASH_HANDLE handle, UCHAR *input, ULONG size, ULONG flags ) -// { - // struct hash *hash = handle; - - // TRACE( "%p, %p, %u, %08x\n", handle, input, size, flags ); - - // if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE; - // if (!input) return STATUS_SUCCESS; - - // return hash_update( &hash->inner, hash->alg_id, input, size ); -// } - -// static NTSTATUS hash_finalize( struct hash *hash, UCHAR *output, ULONG size ) -// { - // UCHAR buffer[MAX_HASH_OUTPUT_BYTES]; - // int hash_length; - // NTSTATUS status; - - // if (!(hash->flags & HASH_FLAG_HMAC)) - // { - // if ((status = hash_finish( &hash->inner, hash->alg_id, output, size ))) return status; - // if (hash->flags & HASH_FLAG_REUSABLE) return hash_prepare( hash ); - // return STATUS_SUCCESS; - // } - - // hash_length = builtin_algorithms[hash->alg_id].hash_length; - // if ((status = hash_finish( &hash->inner, hash->alg_id, buffer, hash_length ))) return status; - // if ((status = hash_update( &hash->outer, hash->alg_id, buffer, hash_length ))) return status; - // if ((status = hash_finish( &hash->outer, hash->alg_id, output, size ))) return status; - - // if (hash->flags & HASH_FLAG_REUSABLE) return hash_prepare( hash ); - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptFinishHash( BCRYPT_HASH_HANDLE handle, UCHAR *output, ULONG size, ULONG flags ) -// { - // struct hash *hash = handle; - - // TRACE( "%p, %p, %u, %08x\n", handle, output, size, flags ); - - // if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE; - // if (!output) return STATUS_INVALID_PARAMETER; - - // return hash_finalize( hash, output, size ); -// } - -// NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG secret_len, - // UCHAR *input, ULONG input_len, UCHAR *output, ULONG output_len ) -// { - // struct algorithm *alg = algorithm; - // struct hash *hash; - // NTSTATUS status; - - // TRACE( "%p, %p, %u, %p, %u, %p, %u\n", algorithm, secret, secret_len, input, input_len, output, output_len ); - - // if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE; - - // if ((status = hash_create( alg, secret, secret_len, 0, &hash ))) return status; - // if ((status = hash_update( &hash->inner, hash->alg_id, input, input_len ))) - // { - // hash_destroy( hash ); - // return status; - // } - // status = hash_finalize( hash, output, output_len ); - // hash_destroy( hash ); - // return status; -// } - -// static NTSTATUS key_asymmetric_create( struct key **ret_key, struct algorithm *alg, ULONG bitlen, - // const UCHAR *pubkey, ULONG pubkey_len ) -// { - // struct key *key; - // NTSTATUS status; - - // if (!key_funcs) - // { - // ERR( "no encryption support\n" ); - // return STATUS_NOT_IMPLEMENTED; - // } - - // if (!(key = heap_alloc_zero( sizeof(*key) ))) return STATUS_NO_MEMORY; - // key->hdr.magic = MAGIC_KEY; - // key->alg_id = alg->id; - // key->u.a.bitlen = bitlen; - - // if (pubkey_len) - // { - // if (!(key->u.a.pubkey = heap_alloc( pubkey_len ))) - // { - // heap_free( key ); - // return STATUS_NO_MEMORY; - // } - // memcpy( key->u.a.pubkey, pubkey, pubkey_len ); - // key->u.a.pubkey_len = pubkey_len; - // } - // if ((status = key_funcs->key_asymmetric_init( key ))) - // { - // heap_free( key->u.a.pubkey ); - // heap_free( key ); - // return status; - // } - // *ret_key = key; - // return STATUS_SUCCESS; -// } - -// static BOOL key_is_symmetric( struct key *key ) -// { - // return builtin_algorithms[key->alg_id].class == BCRYPT_CIPHER_INTERFACE; -// } - -// static BOOL is_zero_vector( const UCHAR *vector, ULONG len ) -// { - // ULONG i; - // if (!vector) return FALSE; - // for (i = 0; i < len; i++) if (vector[i]) return FALSE; - // return TRUE; -// } - -// static BOOL is_equal_vector( const UCHAR *vector, ULONG len, const UCHAR *vector2, ULONG len2 ) -// { - // if (!vector && !vector2) return TRUE; - // if (len != len2) return FALSE; - // return !memcmp( vector, vector2, len ); -// } - -// static NTSTATUS key_symmetric_set_vector( struct key *key, UCHAR *vector, ULONG vector_len ) -// { - // BOOL needs_reset = (!is_zero_vector( vector, vector_len ) || - // !is_equal_vector( key->u.s.vector, key->u.s.vector_len, vector, vector_len )); - - // heap_free( key->u.s.vector ); - // key->u.s.vector = NULL; - // key->u.s.vector_len = 0; - // if (vector) - // { - // if (!(key->u.s.vector = heap_alloc( vector_len ))) return STATUS_NO_MEMORY; - // memcpy( key->u.s.vector, vector, vector_len ); - // key->u.s.vector_len = vector_len; - // } - // if (needs_reset) key_funcs->key_symmetric_vector_reset( key ); - // return STATUS_SUCCESS; -// } - -// static NTSTATUS key_import( BCRYPT_ALG_HANDLE algorithm, const WCHAR *type, BCRYPT_KEY_HANDLE *key, UCHAR *object, - // ULONG object_len, UCHAR *input, ULONG input_len ) -// { - // ULONG len; - - // if (!wcscmp( type, BCRYPT_KEY_DATA_BLOB )) - // { - // BCRYPT_KEY_DATA_BLOB_HEADER *header = (BCRYPT_KEY_DATA_BLOB_HEADER *)input; - - // if (input_len < sizeof(BCRYPT_KEY_DATA_BLOB_HEADER)) return STATUS_BUFFER_TOO_SMALL; - // if (header->dwMagic != BCRYPT_KEY_DATA_BLOB_MAGIC) return STATUS_INVALID_PARAMETER; - // if (header->dwVersion != BCRYPT_KEY_DATA_BLOB_VERSION1) - // { - // FIXME( "unknown key data blob version %u\n", header->dwVersion ); - // return STATUS_INVALID_PARAMETER; - // } - // len = header->cbKeyData; - // if (len + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) > input_len) return STATUS_INVALID_PARAMETER; - - // return BCryptGenerateSymmetricKey( algorithm, key, object, object_len, (UCHAR *)&header[1], len, 0 ); - // } - // else if (!wcscmp( type, BCRYPT_OPAQUE_KEY_BLOB )) - // { - // if (input_len < sizeof(len)) return STATUS_BUFFER_TOO_SMALL; - // len = *(ULONG *)input; - // if (len + sizeof(len) > input_len) return STATUS_INVALID_PARAMETER; - - // return BCryptGenerateSymmetricKey( algorithm, key, object, object_len, input + sizeof(len), len, 0 ); - // } - - // FIXME( "unsupported key type %s\n", debugstr_w(type) ); - // return STATUS_NOT_IMPLEMENTED; -// } - -// static NTSTATUS key_export( struct key *key, const WCHAR *type, UCHAR *output, ULONG output_len, ULONG *size ) -// { - // if (!wcscmp( type, BCRYPT_KEY_DATA_BLOB )) - // { - // BCRYPT_KEY_DATA_BLOB_HEADER *header = (BCRYPT_KEY_DATA_BLOB_HEADER *)output; - // ULONG req_size = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + key->u.s.secret_len; - - // *size = req_size; - // if (output_len < req_size) return STATUS_BUFFER_TOO_SMALL; - // if (output) - // { - // header->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC; - // header->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1; - // header->cbKeyData = key->u.s.secret_len; - // memcpy( &header[1], key->u.s.secret, key->u.s.secret_len ); - // } - // return STATUS_SUCCESS; - // } - // else if (!wcscmp( type, BCRYPT_OPAQUE_KEY_BLOB )) - // { - // ULONG len, req_size = sizeof(len) + key->u.s.secret_len; - - // *size = req_size; - // if (output_len < req_size) return STATUS_BUFFER_TOO_SMALL; - // if (output) - // { - // *(ULONG *)output = key->u.s.secret_len; - // memcpy( output + sizeof(len), key->u.s.secret, key->u.s.secret_len ); - // } - // return STATUS_SUCCESS; - // } - // else if (!wcscmp( type, BCRYPT_RSAPUBLIC_BLOB ) || !wcscmp( type, BCRYPT_DSA_PUBLIC_BLOB ) || - // !wcscmp( type, BCRYPT_ECCPUBLIC_BLOB ) || !wcscmp( type, LEGACY_DSA_V2_PUBLIC_BLOB )) - // { - // *size = key->u.a.pubkey_len; - // if (output_len < key->u.a.pubkey_len) return STATUS_SUCCESS; - // if (output) memcpy( output, key->u.a.pubkey, key->u.a.pubkey_len ); - // return STATUS_SUCCESS; - // } - // else if (!wcscmp( type, BCRYPT_ECCPRIVATE_BLOB )) - // { - // return key_funcs->key_export_ecc( key, output, output_len, size ); - // } - // else if (!wcscmp( type, LEGACY_DSA_V2_PRIVATE_BLOB )) - // { - // return key_funcs->key_export_dsa_capi( key, output, output_len, size ); - // } - - // FIXME( "unsupported key type %s\n", debugstr_w(type) ); - // return STATUS_NOT_IMPLEMENTED; -// } - -// static NTSTATUS key_symmetric_encrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv, - // ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags ) -// { - // ULONG bytes_left = input_len; - // UCHAR *buf, *src, *dst; - // NTSTATUS status; - - // if (key->u.s.mode == MODE_ID_GCM) - // { - // BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO *auth_info = padding; - - // if (!auth_info) return STATUS_INVALID_PARAMETER; - // if (!auth_info->pbNonce) return STATUS_INVALID_PARAMETER; - // if (!auth_info->pbTag) return STATUS_INVALID_PARAMETER; - // if (auth_info->cbTag < 12 || auth_info->cbTag > 16) return STATUS_INVALID_PARAMETER; - // if (auth_info->dwFlags & BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG) - // FIXME( "call chaining not implemented\n" ); - - // if ((status = key_symmetric_set_vector( key, auth_info->pbNonce, auth_info->cbNonce ))) - // return status; - - // *ret_len = input_len; - // if (flags & BCRYPT_BLOCK_PADDING) return STATUS_INVALID_PARAMETER; - // if (input && !output) return STATUS_SUCCESS; - // if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL; - - // if ((status = key_funcs->key_symmetric_set_auth_data( key, auth_info->pbAuthData, auth_info->cbAuthData ))) - // return status; - // if ((status = key_funcs->key_symmetric_encrypt( key, input, input_len, output, output_len ))) return status; - - // return key_funcs->key_symmetric_get_tag( key, auth_info->pbTag, auth_info->cbTag ); - // } - - // *ret_len = input_len; - - // if (flags & BCRYPT_BLOCK_PADDING) - // *ret_len = (input_len + key->u.s.block_size) & ~(key->u.s.block_size - 1); - // else if (input_len & (key->u.s.block_size - 1)) - // return STATUS_INVALID_BUFFER_SIZE; - - // if (!output) return STATUS_SUCCESS; - // if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL; - // if (key->u.s.mode == MODE_ID_ECB && iv) return STATUS_INVALID_PARAMETER; - // if ((status = key_symmetric_set_vector( key, iv, iv_len ))) return status; - - // src = input; - // dst = output; - // while (bytes_left >= key->u.s.block_size) - // { - // if ((status = key_funcs->key_symmetric_encrypt( key, src, key->u.s.block_size, dst, key->u.s.block_size ))) - // return status; - // if (key->u.s.mode == MODE_ID_ECB && (status = key_symmetric_set_vector( key, NULL, 0 ))) - // return status; - // bytes_left -= key->u.s.block_size; - // src += key->u.s.block_size; - // dst += key->u.s.block_size; - // } - - // if (flags & BCRYPT_BLOCK_PADDING) - // { - // if (!(buf = heap_alloc( key->u.s.block_size ))) return STATUS_NO_MEMORY; - // memcpy( buf, src, bytes_left ); - // memset( buf + bytes_left, key->u.s.block_size - bytes_left, key->u.s.block_size - bytes_left ); - // status = key_funcs->key_symmetric_encrypt( key, buf, key->u.s.block_size, dst, key->u.s.block_size ); - // heap_free( buf ); - // } - - // return status; -// } - -// static NTSTATUS key_symmetric_decrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv, - // ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags ) -// { - // ULONG bytes_left = input_len; - // UCHAR *buf, *src, *dst; - // NTSTATUS status; - - // if (key->u.s.mode == MODE_ID_GCM) - // { - // BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO *auth_info = padding; - // UCHAR tag[16]; - - // if (!auth_info) return STATUS_INVALID_PARAMETER; - // if (!auth_info->pbNonce) return STATUS_INVALID_PARAMETER; - // if (!auth_info->pbTag) return STATUS_INVALID_PARAMETER; - // if (auth_info->cbTag < 12 || auth_info->cbTag > 16) return STATUS_INVALID_PARAMETER; - - // if ((status = key_symmetric_set_vector( key, auth_info->pbNonce, auth_info->cbNonce ))) - // return status; - - // *ret_len = input_len; - // if (flags & BCRYPT_BLOCK_PADDING) return STATUS_INVALID_PARAMETER; - // if (!output) return STATUS_SUCCESS; - // if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL; - - // if ((status = key_funcs->key_symmetric_set_auth_data( key, auth_info->pbAuthData, auth_info->cbAuthData ))) - // return status; - // if ((status = key_funcs->key_symmetric_decrypt( key, input, input_len, output, output_len ))) return status; - - // if ((status = key_funcs->key_symmetric_get_tag( key, tag, sizeof(tag) ))) return status; - // if (memcmp( tag, auth_info->pbTag, auth_info->cbTag )) return STATUS_AUTH_TAG_MISMATCH; - - // return STATUS_SUCCESS; - // } - - // *ret_len = input_len; - - // if (input_len & (key->u.s.block_size - 1)) return STATUS_INVALID_BUFFER_SIZE; - // if (!output) return STATUS_SUCCESS; - // if (flags & BCRYPT_BLOCK_PADDING) - // { - // if (output_len + key->u.s.block_size < *ret_len) return STATUS_BUFFER_TOO_SMALL; - // if (input_len < key->u.s.block_size) return STATUS_BUFFER_TOO_SMALL; - // bytes_left -= key->u.s.block_size; - // } - // else if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL; - - // if (key->u.s.mode == MODE_ID_ECB && iv) return STATUS_INVALID_PARAMETER; - // if ((status = key_symmetric_set_vector( key, iv, iv_len ))) return status; - - // src = input; - // dst = output; - // while (bytes_left >= key->u.s.block_size) - // { - // if ((status = key_funcs->key_symmetric_decrypt( key, src, key->u.s.block_size, dst, key->u.s.block_size ))) - // return status; - // if (key->u.s.mode == MODE_ID_ECB && (status = key_symmetric_set_vector( key, NULL, 0 ))) - // return status; - // bytes_left -= key->u.s.block_size; - // src += key->u.s.block_size; - // dst += key->u.s.block_size; - // } +#define SIZE_MAX 0xFFFFFFFF +#define kMaxHashLength 512/8 - // if (flags & BCRYPT_BLOCK_PADDING) - // { - // if (!(buf = heap_alloc( key->u.s.block_size ))) return STATUS_NO_MEMORY; - // status = key_funcs->key_symmetric_decrypt( key, src, key->u.s.block_size, buf, key->u.s.block_size ); - // if (!status && buf[ key->u.s.block_size - 1 ] <= key->u.s.block_size) - // { - // *ret_len -= buf[ key->u.s.block_size - 1 ]; - // if (output_len < *ret_len) status = STATUS_BUFFER_TOO_SMALL; - // else memcpy( dst, buf, key->u.s.block_size - buf[ key->u.s.block_size - 1 ] ); - // } - // else status = STATUS_UNSUCCESSFUL; /* FIXME: invalid padding */ - // heap_free( buf ); - // } - - // return status; -// } - -// static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input, - // ULONG input_len ) -// { - // struct key *key; - // NTSTATUS status; - - // if (!wcscmp( type, BCRYPT_ECCPUBLIC_BLOB )) - // { - // BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)input; - // DWORD key_size, magic, size; - - // if (input_len < sizeof(*ecc_blob)) return STATUS_INVALID_PARAMETER; - - // switch (alg->id) - // { - // case ALG_ID_ECDH_P256: - // key_size = 32; - // magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC; - // break; - - // case ALG_ID_ECDSA_P256: - // key_size = 32; - // magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC; - // break; - - // case ALG_ID_ECDSA_P384: - // key_size = 48; - // magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC; - // break; - - // default: - // FIXME( "algorithm %u does not yet support importing blob of type %s\n", alg->id, debugstr_w(type) ); - // return STATUS_NOT_SUPPORTED; - // } - - // if (ecc_blob->dwMagic != magic) return STATUS_INVALID_PARAMETER; - // if (ecc_blob->cbKey != key_size || input_len < sizeof(*ecc_blob) + ecc_blob->cbKey * 2) - // return STATUS_INVALID_PARAMETER; - - // size = sizeof(*ecc_blob) + ecc_blob->cbKey * 2; - // return key_asymmetric_create( (struct key **)ret_key, alg, key_size * 8, (BYTE *)ecc_blob, size ); - // } - // else if (!wcscmp( type, BCRYPT_ECCPRIVATE_BLOB )) - // { - // BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)input; - // DWORD key_size, magic; - - // if (input_len < sizeof(*ecc_blob)) return STATUS_INVALID_PARAMETER; - - // switch (alg->id) - // { - // case ALG_ID_ECDH_P256: - // key_size = 32; - // magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC; - // break; - // case ALG_ID_ECDSA_P256: - // key_size = 32; - // magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC; - // break; - - // default: - // FIXME( "algorithm %u does not yet support importing blob of type %s\n", alg->id, debugstr_w(type) ); - // return STATUS_NOT_SUPPORTED; - // } - - // if (ecc_blob->dwMagic != magic) return STATUS_INVALID_PARAMETER; - // if (ecc_blob->cbKey != key_size || input_len < sizeof(*ecc_blob) + ecc_blob->cbKey * 3) - // return STATUS_INVALID_PARAMETER; - - // if ((status = key_asymmetric_create( &key, alg, key_size * 8, NULL, 0 ))) return status; - // if ((status = key_funcs->key_import_ecc( key, input, input_len ))) - // { - // BCryptDestroyKey( key ); - // return status; - // } - - // *ret_key = key; - // return STATUS_SUCCESS; - // } - // else if (!wcscmp( type, BCRYPT_RSAPUBLIC_BLOB )) - // { - // BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input; - // ULONG size; - - // if (input_len < sizeof(*rsa_blob)) return STATUS_INVALID_PARAMETER; - // if ((alg->id != ALG_ID_RSA && alg->id != ALG_ID_RSA_SIGN) || rsa_blob->Magic != BCRYPT_RSAPUBLIC_MAGIC) - // return STATUS_NOT_SUPPORTED; - - // size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus; - // return key_asymmetric_create( (struct key **)ret_key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size ); - // } - // else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB )) - // { - // BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input; - // ULONG size; - - // if (input_len < sizeof(*rsa_blob)) return STATUS_INVALID_PARAMETER; - // if (alg->id != ALG_ID_RSA || rsa_blob->Magic != BCRYPT_RSAPRIVATE_MAGIC) - // return STATUS_NOT_SUPPORTED; - - // size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus; - // if ((status = key_asymmetric_create( &key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size ))) - // return status; - // if ((status = key_funcs->key_import_rsa( key, input, input_len ))) - // { - // BCryptDestroyKey( key ); - // return status; - // } - - // *ret_key = key; - // return STATUS_SUCCESS; - // } - // else if (!wcscmp( type, BCRYPT_DSA_PUBLIC_BLOB )) - // { - // BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)input; - // ULONG size; - - // if (input_len < sizeof(*dsa_blob)) return STATUS_INVALID_PARAMETER; - // if ((alg->id != ALG_ID_DSA) || dsa_blob->dwMagic != BCRYPT_DSA_PUBLIC_MAGIC) - // return STATUS_NOT_SUPPORTED; - - // size = sizeof(*dsa_blob) + dsa_blob->cbKey * 3; - // return key_asymmetric_create( (struct key **)ret_key, alg, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size ); - // } - // else if (!wcscmp( type, LEGACY_DSA_V2_PRIVATE_BLOB )) - // { - // BLOBHEADER *hdr = (BLOBHEADER *)input; - // DSSPUBKEY *pubkey; - - // if (input_len < sizeof(*hdr)) return STATUS_INVALID_PARAMETER; - - // if (hdr->bType != PRIVATEKEYBLOB && hdr->bVersion != 2 && hdr->aiKeyAlg != CALG_DSS_SIGN) - // { - // FIXME( "blob type %u version %u alg id %u not supported\n", hdr->bType, hdr->bVersion, hdr->aiKeyAlg ); - // return STATUS_NOT_SUPPORTED; - // } - // if (alg->id != ALG_ID_DSA) - // { - // FIXME( "algorithm %u does not support importing blob of type %s\n", alg->id, debugstr_w(type) ); - // return STATUS_NOT_SUPPORTED; - // } - - // if (input_len < sizeof(*hdr) + sizeof(*pubkey)) return STATUS_INVALID_PARAMETER; - // pubkey = (DSSPUBKEY *)(hdr + 1); - // if (pubkey->magic != MAGIC_DSS2) return STATUS_NOT_SUPPORTED; - - // if (input_len < sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 2 + 40 + sizeof(DSSSEED)) - // return STATUS_INVALID_PARAMETER; - - // if ((status = key_asymmetric_create( &key, alg, pubkey->bitlen, NULL, 0 ))) return status; - // if ((status = key_funcs->key_import_dsa_capi( key, input, input_len ))) - // { - // BCryptDestroyKey( key ); - // return status; - // } - - // *ret_key = key; - // return STATUS_SUCCESS; - // } - // else if (!wcscmp( type, LEGACY_DSA_V2_PUBLIC_BLOB )) /* not supported on native */ - // { - // BLOBHEADER *hdr = (BLOBHEADER *)input; - // DSSPUBKEY *pubkey; - // ULONG size; - - // if (alg->id != ALG_ID_DSA) return STATUS_NOT_SUPPORTED; - // if (input_len < sizeof(*hdr)) return STATUS_INVALID_PARAMETER; - - // if (hdr->bType != PUBLICKEYBLOB && hdr->bVersion != 2 && hdr->aiKeyAlg != CALG_DSS_SIGN) - // { - // FIXME( "blob type %u version %u alg id %u not supported\n", hdr->bType, hdr->bVersion, hdr->aiKeyAlg ); - // return STATUS_NOT_SUPPORTED; - // } - - // if (input_len < sizeof(*hdr) + sizeof(*pubkey)) return STATUS_INVALID_PARAMETER; - // pubkey = (DSSPUBKEY *)(hdr + 1); - // if (pubkey->magic != MAGIC_DSS1) return STATUS_NOT_SUPPORTED; - - // size = sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 3 + 20 + sizeof(DSSSEED); - // if (input_len < size) return STATUS_INVALID_PARAMETER; - - // if ((status = key_asymmetric_create( &key, alg, pubkey->bitlen, (BYTE *)hdr, size ))) return status; - // key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2; - - // *ret_key = key; - // return STATUS_SUCCESS; - // } - - // FIXME( "unsupported key type %s\n", debugstr_w(type) ); - // return STATUS_NOT_SUPPORTED; -// } - -// static ULONG get_block_size( struct algorithm *alg ) -// { - // ULONG ret = 0, size = sizeof(ret); - // get_alg_property( alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&ret, sizeof(ret), &size ); - // return ret; -// } - -// NTSTATUS WINAPI BCryptGenerateSymmetricKey( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_HANDLE *handle, - // UCHAR *object, ULONG object_len, UCHAR *secret, ULONG secret_len, - // ULONG flags ) -// { - // struct algorithm *alg = algorithm; - // struct key *key; - // ULONG block_size; - // NTSTATUS status; - - // TRACE( "%p, %p, %p, %u, %p, %u, %08x\n", algorithm, handle, object, object_len, secret, secret_len, flags ); - - // if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE; - // if (object) FIXME( "ignoring object buffer\n" ); - - // if (!key_funcs) - // { - // ERR( "no encryption support\n" ); - // return STATUS_NOT_IMPLEMENTED; - // } - - // if (!(block_size = get_block_size( alg ))) return STATUS_INVALID_PARAMETER; - - // if (!(key = heap_alloc_zero( sizeof(*key) ))) return STATUS_NO_MEMORY; - // InitializeCriticalSection( &key->u.s.cs ); - // key->hdr.magic = MAGIC_KEY; - // key->alg_id = alg->id; - // key->u.s.mode = alg->mode; - // key->u.s.block_size = block_size; - - // if (!(key->u.s.secret = heap_alloc( secret_len ))) - // { - // heap_free( key ); - // return STATUS_NO_MEMORY; - // } - // memcpy( key->u.s.secret, secret, secret_len ); - // key->u.s.secret_len = secret_len; - - // if ((status = key_funcs->key_symmetric_init( key ))) - // { - // heap_free( key->u.s.secret ); - // heap_free( key ); - // return status; - // } - - // *handle = key; - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptGenerateKeyPair( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_HANDLE *handle, ULONG key_len, - // ULONG flags ) -// { - // struct algorithm *alg = algorithm; - // struct key *key; - // NTSTATUS status; - - // TRACE( "%p, %p, %u, %08x\n", algorithm, handle, key_len, flags ); - - // if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE; - // if (!handle) return STATUS_INVALID_PARAMETER; - - // if (!(status = key_asymmetric_create( &key, alg, key_len, NULL, 0 ))) *handle = key; - // return status; -// } - -// NTSTATUS WINAPI BCryptFinalizeKeyPair( BCRYPT_KEY_HANDLE handle, ULONG flags ) -// { - // struct key *key = handle; - - // TRACE( "%p, %08x\n", key, flags ); - // if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; - - // return key_funcs->key_asymmetric_generate( key ); -// } - -// NTSTATUS WINAPI BCryptImportKey( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_HANDLE decrypt_key, LPCWSTR type, - // BCRYPT_KEY_HANDLE *key, PUCHAR object, ULONG object_len, PUCHAR input, - // ULONG input_len, ULONG flags ) -// { - // struct algorithm *alg = algorithm; - - // TRACE("%p, %p, %s, %p, %p, %u, %p, %u, %u\n", algorithm, decrypt_key, debugstr_w(type), key, object, - // object_len, input, input_len, flags); - - // if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE; - // if (!key || !type || !input) return STATUS_INVALID_PARAMETER; - - // if (decrypt_key) - // { - // FIXME( "decryption of key not yet supported\n" ); - // return STATUS_NOT_IMPLEMENTED; - // } - - // return key_import( algorithm, type, key, object, object_len, input, input_len ); -// } - -// NTSTATUS WINAPI BCryptExportKey( BCRYPT_KEY_HANDLE export_key, BCRYPT_KEY_HANDLE encrypt_key, LPCWSTR type, - // PUCHAR output, ULONG output_len, ULONG *size, ULONG flags ) -// { - // struct key *key = export_key; - - // TRACE("%p, %p, %s, %p, %u, %p, %u\n", key, encrypt_key, debugstr_w(type), output, output_len, size, flags); - - // if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; - // if (!type || !size) return STATUS_INVALID_PARAMETER; - - // if (encrypt_key) - // { - // FIXME( "encryption of key not yet supported\n" ); - // return STATUS_NOT_IMPLEMENTED; - // } - - // return key_export( key, type, output, output_len, size ); -// } - -// static NTSTATUS key_duplicate( struct key *key_orig, struct key *key_copy ) -// { - // UCHAR *buffer; - // NTSTATUS status; - - // memset( key_copy, 0, sizeof(*key_copy) ); - // key_copy->hdr = key_orig->hdr; - // key_copy->alg_id = key_orig->alg_id; - - // if (key_is_symmetric( key_orig )) - // { - // if (!(buffer = heap_alloc( key_orig->u.s.secret_len ))) return STATUS_NO_MEMORY; - // memcpy( buffer, key_orig->u.s.secret, key_orig->u.s.secret_len ); - - // key_copy->u.s.mode = key_orig->u.s.mode; - // key_copy->u.s.block_size = key_orig->u.s.block_size; - // key_copy->u.s.secret = buffer; - // key_copy->u.s.secret_len = key_orig->u.s.secret_len; - // InitializeCriticalSection( &key_copy->u.s.cs ); - // } - // else - // { - // if (!(buffer = heap_alloc( key_orig->u.a.pubkey_len ))) return STATUS_NO_MEMORY; - // memcpy( buffer, key_orig->u.a.pubkey, key_orig->u.a.pubkey_len ); - - // key_copy->u.a.bitlen = key_orig->u.a.bitlen; - // key_copy->u.a.flags = key_orig->u.a.flags; - // key_copy->u.a.pubkey = buffer; - // key_copy->u.a.pubkey_len = key_orig->u.a.pubkey_len; - // key_copy->u.a.dss_seed = key_orig->u.a.dss_seed; - - // if ((status = key_funcs->key_asymmetric_duplicate( key_orig, key_copy ))) return status; - // } - - // return STATUS_SUCCESS; -// } - -// static void key_destroy( struct key *key ) -// { - // if (key_is_symmetric( key )) - // { - // key_funcs->key_symmetric_destroy( key ); - // heap_free( key->u.s.vector ); - // heap_free( key->u.s.secret ); - // DeleteCriticalSection( &key->u.s.cs ); - // } - // else - // { - // key_funcs->key_asymmetric_destroy( key ); - // heap_free( key->u.a.pubkey ); - // } - // key->hdr.magic = 0; - // heap_free( key ); -// } - -// NTSTATUS WINAPI BCryptDuplicateKey( BCRYPT_KEY_HANDLE handle, BCRYPT_KEY_HANDLE *handle_copy, - // UCHAR *object, ULONG object_len, ULONG flags ) -// { - // struct key *key_orig = handle; - // struct key *key_copy; - // NTSTATUS status; - - // TRACE( "%p, %p, %p, %u, %08x\n", handle, handle_copy, object, object_len, flags ); - // if (object) FIXME( "ignoring object buffer\n" ); - - // if (!key_orig || key_orig->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; - // if (!handle_copy) return STATUS_INVALID_PARAMETER; - // if (!(key_copy = heap_alloc( sizeof(*key_copy) ))) return STATUS_NO_MEMORY; - - // if ((status = key_duplicate( key_orig, key_copy ))) - // { - // key_destroy( key_copy ); - // return status; - // } - - // *handle_copy = key_copy; - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptImportKeyPair( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_HANDLE decrypt_key, const WCHAR *type, - // BCRYPT_KEY_HANDLE *ret_key, UCHAR *input, ULONG input_len, ULONG flags ) -// { - // struct algorithm *alg = algorithm; - - // TRACE( "%p, %p, %s, %p, %p, %u, %08x\n", algorithm, decrypt_key, debugstr_w(type), ret_key, input, - // input_len, flags ); - - // if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE; - // if (!ret_key || !type || !input) return STATUS_INVALID_PARAMETER; - // if (decrypt_key) - // { - // FIXME( "decryption of key not yet supported\n" ); - // return STATUS_NOT_IMPLEMENTED; - // } - - // return key_import_pair( alg, type, ret_key, input, input_len ); -// } - -// NTSTATUS WINAPI BCryptSignHash( BCRYPT_KEY_HANDLE handle, void *padding, UCHAR *input, ULONG input_len, - // UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags ) -// { - // struct key *key = handle; - - // TRACE( "%p, %p, %p, %u, %p, %u, %p, %08x\n", handle, padding, input, input_len, output, output_len, - // ret_len, flags ); - - // if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; - // if (key_is_symmetric( key )) - // { - // FIXME( "signing with symmetric keys not yet supported\n" ); - // return STATUS_NOT_IMPLEMENTED; - // } - - // return key_funcs->key_asymmetric_sign( key, padding, input, input_len, output, output_len, ret_len, flags ); -// } - -// NTSTATUS WINAPI BCryptVerifySignature( BCRYPT_KEY_HANDLE handle, void *padding, UCHAR *hash, ULONG hash_len, - // UCHAR *signature, ULONG signature_len, ULONG flags ) -// { - // struct key *key = handle; - - // TRACE( "%p, %p, %p, %u, %p, %u, %08x\n", handle, padding, hash, hash_len, signature, signature_len, flags ); - - // if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; - // if (!hash || !hash_len || !signature || !signature_len) return STATUS_INVALID_PARAMETER; - // if (key_is_symmetric( key )) return STATUS_NOT_SUPPORTED; - - // return key_funcs->key_asymmetric_verify( key, padding, hash, hash_len, signature, signature_len, flags ); -// } - -// NTSTATUS WINAPI BCryptDestroyKey( BCRYPT_KEY_HANDLE handle ) -// { - // struct key *key = handle; - - // TRACE( "%p\n", handle ); - - // if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; - - // key_destroy( key ); - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv, - // ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags ) -// { - // struct key *key = handle; - // NTSTATUS ret; - - // TRACE( "%p, %p, %u, %p, %p, %u, %p, %u, %p, %08x\n", handle, input, input_len, padding, iv, iv_len, output, - // output_len, ret_len, flags ); - - // if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; - // if (!key_is_symmetric( key )) - // { - // FIXME( "encryption with asymmetric keys not yet supported\n" ); - // return STATUS_NOT_IMPLEMENTED; - // } - // if (flags & ~BCRYPT_BLOCK_PADDING) - // { - // FIXME( "flags %08x not implemented\n", flags ); - // return STATUS_NOT_IMPLEMENTED; - // } - - // EnterCriticalSection( &key->u.s.cs ); - // ret = key_symmetric_encrypt( key, input, input_len, padding, iv, iv_len, output, output_len, ret_len, flags ); - // LeaveCriticalSection( &key->u.s.cs ); - // return ret; -// } - -// NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv, - // ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags ) -// { - // struct key *key = handle; - - // TRACE( "%p, %p, %u, %p, %p, %u, %p, %u, %p, %08x\n", handle, input, input_len, padding, iv, iv_len, output, - // output_len, ret_len, flags ); - - // if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; - // if (flags & ~BCRYPT_BLOCK_PADDING) - // { - // FIXME( "flags %08x not supported\n", flags ); - // return STATUS_NOT_IMPLEMENTED; - // } - - // if (key_is_symmetric( key )) - // { - // NTSTATUS ret; - // EnterCriticalSection( &key->u.s.cs ); - // ret = key_symmetric_decrypt( key, input, input_len, padding, iv, iv_len, output, output_len, ret_len, flags ); - // LeaveCriticalSection( &key->u.s.cs ); - // return ret; - // } - - // return key_funcs->key_asymmetric_decrypt( key, input, input_len, output, output_len, ret_len ); -// } - -// NTSTATUS WINAPI BCryptSetProperty( BCRYPT_HANDLE handle, const WCHAR *prop, UCHAR *value, ULONG size, ULONG flags ) -// { - // struct object *object = handle; - - // TRACE( "%p, %s, %p, %u, %08x\n", handle, debugstr_w(prop), value, size, flags ); - - // if (!object) return STATUS_INVALID_HANDLE; - - // switch (object->magic) - // { - // case MAGIC_ALG: - // { - // struct algorithm *alg = (struct algorithm *)object; - // return set_alg_property( alg, prop, value, size, flags ); - // } - // case MAGIC_KEY: - // { - // struct key *key = (struct key *)object; - // return key_funcs->key_set_property( key, prop, value, size, flags ); - // } - // default: - // WARN( "unknown magic %08x\n", object->magic ); - // return STATUS_INVALID_HANDLE; - // } -// } - -// #define HMAC_PAD_LEN 64 -// NTSTATUS WINAPI BCryptDeriveKeyCapi( BCRYPT_HASH_HANDLE handle, BCRYPT_ALG_HANDLE halg, UCHAR *key, ULONG keylen, ULONG flags ) -// { - // struct hash *hash = handle; - // UCHAR buf[MAX_HASH_OUTPUT_BYTES * 2]; - // NTSTATUS status; - // ULONG len; - - // TRACE( "%p, %p, %p, %u, %08x\n", handle, halg, key, keylen, flags ); - - // if (!key || !keylen) return STATUS_INVALID_PARAMETER; - // if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE; - // if (keylen > builtin_algorithms[hash->alg_id].hash_length * 2) return STATUS_INVALID_PARAMETER; - - // if (halg) - // { - // FIXME( "algorithm handle not supported\n" ); - // return STATUS_NOT_IMPLEMENTED; - // } - - // len = builtin_algorithms[hash->alg_id].hash_length; - // if ((status = hash_finalize( hash, buf, len ))) return status; - - // if (len < keylen) - // { - // UCHAR pad1[HMAC_PAD_LEN], pad2[HMAC_PAD_LEN]; - // ULONG i; - - // for (i = 0; i < sizeof(pad1); i++) - // { - // pad1[i] = 0x36 ^ (i < len ? buf[i] : 0); - // pad2[i] = 0x5c ^ (i < len ? buf[i] : 0); - // } - - // if ((status = hash_prepare( hash )) || - // (status = hash_update( &hash->inner, hash->alg_id, pad1, sizeof(pad1) )) || - // (status = hash_finalize( hash, buf, len ))) return status; - - // if ((status = hash_prepare( hash )) || - // (status = hash_update( &hash->inner, hash->alg_id, pad2, sizeof(pad2) )) || - // (status = hash_finalize( hash, buf + len, len ))) return status; - // } - - // memcpy( key, buf, keylen ); - // return STATUS_SUCCESS; -// } - -// static NTSTATUS pbkdf2( struct hash *hash, UCHAR *pwd, ULONG pwd_len, UCHAR *salt, ULONG salt_len, - // ULONGLONG iterations, ULONG i, UCHAR *dst, ULONG hash_len ) -// { - // NTSTATUS status = STATUS_INVALID_PARAMETER; - // UCHAR bytes[4], *buf; - // ULONG j, k; - - // if (!(buf = heap_alloc( hash_len ))) return STATUS_NO_MEMORY; - - // for (j = 0; j < iterations; j++) - // { - // if (j == 0) - // { - // /* use salt || INT(i) */ - // if ((status = hash_update( &hash->inner, hash->alg_id, salt, salt_len ))) - // { - // heap_free( buf ); - // return status; - // } - // bytes[0] = (i >> 24) & 0xff; - // bytes[1] = (i >> 16) & 0xff; - // bytes[2] = (i >> 8) & 0xff; - // bytes[3] = i & 0xff; - // status = hash_update( &hash->inner, hash->alg_id, bytes, 4 ); - // } - // else status = hash_update( &hash->inner, hash->alg_id, buf, hash_len ); /* use U_j */ - - // if (status) - // { - // heap_free( buf ); - // return status; - // } - - // if ((status = hash_finalize( hash, buf, hash_len ))) - // { - // heap_free( buf ); - // return status; - // } - - // if (j == 0) memcpy( dst, buf, hash_len ); - // else for (k = 0; k < hash_len; k++) dst[k] ^= buf[k]; - // } - - // heap_free( buf ); - // return status; -// } - -// NTSTATUS WINAPI BCryptDeriveKeyPBKDF2( BCRYPT_ALG_HANDLE handle, UCHAR *pwd, ULONG pwd_len, UCHAR *salt, ULONG salt_len, - // ULONGLONG iterations, UCHAR *dk, ULONG dk_len, ULONG flags ) -// { - // struct algorithm *alg = handle; - // ULONG hash_len, block_count, bytes_left, i; - // struct hash *hash; - // UCHAR *partial; - // NTSTATUS status; - - // TRACE( "%p, %p, %u, %p, %u, %s, %p, %u, %08x\n", handle, pwd, pwd_len, salt, salt_len, - // wine_dbgstr_longlong(iterations), dk, dk_len, flags ); - - // if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE; - - // hash_len = builtin_algorithms[alg->id].hash_length; - // if (dk_len <= 0 || dk_len > ((((ULONGLONG)1) << 32) - 1) * hash_len) return STATUS_INVALID_PARAMETER; - - // block_count = 1 + ((dk_len - 1) / hash_len); /* ceil(dk_len / hash_len) */ - // bytes_left = dk_len - (block_count - 1) * hash_len; - - // if ((status = hash_create( alg, pwd, pwd_len, BCRYPT_HASH_REUSABLE_FLAG, &hash ))) return status; - - // /* full blocks */ - // for (i = 1; i < block_count; i++) - // { - // if ((status = pbkdf2( hash, pwd, pwd_len, salt, salt_len, iterations, i, dk + ((i - 1) * hash_len), hash_len ))) - // { - // hash_destroy( hash ); - // return status; - // } - // } - - // /* final partial block */ - // if (!(partial = heap_alloc( hash_len ))) - // { - // hash_destroy( hash ); - // return STATUS_NO_MEMORY; - // } - - // if ((status = pbkdf2( hash, pwd, pwd_len, salt, salt_len, iterations, block_count, partial, hash_len ))) - // { - // hash_destroy( hash ); - // heap_free( partial ); - // return status; - // } - // memcpy( dk + ((block_count - 1) * hash_len), partial, bytes_left ); - - // hash_destroy( hash ); - // heap_free( partial ); - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptSecretAgreement(BCRYPT_KEY_HANDLE privatekey, BCRYPT_KEY_HANDLE publickey, BCRYPT_SECRET_HANDLE *handle, ULONG flags) -// { - // struct key *privkey = privatekey; - // struct key *pubkey = publickey; - // struct secret *secret; - - // FIXME( "%p, %p, %p, %08x\n", privatekey, publickey, handle, flags ); - - // if (!privkey || privkey->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; - // if (!pubkey || pubkey->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; - // if (!handle) return STATUS_INVALID_PARAMETER; - - // if (!(secret = heap_alloc_zero( sizeof(*secret) ))) return STATUS_NO_MEMORY; - // secret->hdr.magic = MAGIC_SECRET; - - // *handle = secret; - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptDestroySecret(BCRYPT_SECRET_HANDLE handle) -// { - // struct secret *secret = handle; - - // FIXME( "%p\n", handle ); - - // if (!secret || secret->hdr.magic != MAGIC_SECRET) return STATUS_INVALID_HANDLE; - // secret->hdr.magic = 0; - // heap_free( secret ); - // return STATUS_SUCCESS; -// } - -// NTSTATUS WINAPI BCryptDeriveKey(BCRYPT_SECRET_HANDLE handle, LPCWSTR kdf, BCryptBufferDesc *parameter, - // PUCHAR derived, ULONG derived_size, ULONG *result, ULONG flags) -// { - // struct secret *secret = handle; - - // FIXME( "%p, %s, %p, %p, %d, %p, %08x\n", secret, debugstr_w(kdf), parameter, derived, derived_size, result, flags ); - - // if (!secret || secret->hdr.magic != MAGIC_SECRET) return STATUS_INVALID_HANDLE; - // if (!kdf) return STATUS_INVALID_PARAMETER; +WINE_DEFAULT_DEBUG_CHANNEL(bcrypt); - // return STATUS_INTERNAL_ERROR; -// } +NTSTATUS +WINAPI +BCryptCreateHashNative( + BCRYPT_ALG_HANDLE algorithm, + BCRYPT_HASH_HANDLE *handle, + UCHAR *object, + ULONG objectlen, + UCHAR *secret, + ULONG secretlen, + ULONG flags +); + +static int StringCompareIgnoreCaseByAscii(const char* string1, const char* string2, size_t count) +{ + wchar_t f, l; + int result = 0; + + if (count) + { + /* validation section */ + do { + f = towlower(*string1); + l = towlower(*string2); + string1++; + string2++; + } while ((--count) && f && (f == l)); + + result = (int)(f - l); + } + + return result; +} -// BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) -// { - // switch (reason) - // { - // case DLL_PROCESS_ATTACH: - // instance = hinst; - // DisableThreadLibraryCalls( hinst ); -// #if defined(HAVE_GNUTLS_CIPHER_INIT) && !defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) - // __wine_init_unix_lib( hinst, reason, NULL, &key_funcs ); -// #endif - // break; - // case DLL_PROCESS_DETACH: - // if (reserved) break; -// #if defined(HAVE_GNUTLS_CIPHER_INIT) && !defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) - // __wine_init_unix_lib( hinst, reason, NULL, NULL ); -// #endif - // break; - // } - // return TRUE; -// } +VOID +WINAPI +BCryptFree( + _In_ PVOID pvBuffer) +{ + RtlFreeHeap(NtCurrentTeb()->Peb->ProcessHeap, 0, pvBuffer); +} -NTSTATUS BCryptHash(BCRYPT_ALG_HANDLE hAlgorithm, PUCHAR pbSecret, ULONG cbSecret, PUCHAR pbInput, +NTSTATUS WINAPI BCryptHash(BCRYPT_ALG_HANDLE hAlgorithm, PUCHAR pbSecret, ULONG cbSecret, PUCHAR pbInput, ULONG cbInput, PUCHAR pbOutput, ULONG cbOutput) { BCRYPT_HASH_HANDLE hHash; @@ -2029,215 +122,249 @@ NTSTATUS BCryptHash(BCRYPT_ALG_HANDLE hAlgorithm, PUCHAR pbSecret, ULONG cbSecre ReturnAndDeallocate: RtlFreeHeap(NtCurrentTeb()->Peb->ProcessHeap, 0, pbHashObject); return Status; - } - #define SIZE_MAX 0xFFFFFFFF - - -// NTSTATUS BCryptDeriveKeyPBKDF2(BCRYPT_ALG_HANDLE hPrf, const char *pbPassword, size_t cbPassword, const uint8_t *pbSalt, - // size_t cbSalt, uint8_t *pbDerivedKey, size_t cbDerivedKey, ULONGLONG cIterations) -// { - // UCHAR* aSalt, *obuf; // Update this, use variable digest length obtained from BCryptGetProperty call - // UCHAR* d1, *d2; - // ULONG i, j; - // ULONG count, ResultLength; - // size_t r; - // DWORD DigestLength; - // BCRYPT_HASH_HANDLE hHash; - // NTSTATUS Status = STATUS_SUCCESS; +NTSTATUS +WINAPI +BCryptCreateHashInternal( + BCRYPT_ALG_HANDLE hAlgorithm, + BCRYPT_HASH_HANDLE *phHash, + UCHAR *pbHashObject, + ULONG cbHashObject, + UCHAR *pbSecret, + ULONG cbSecret, + ULONG dwFlags +) +{ + ULONG Unused; + NTSTATUS Status; + if (pbHashObject == NULL && cbHashObject == 0) { + // FIX: BCryptCreateHash of Windows Vista does not support this parameter. .NET Core 6 relies on it. + Status = BCryptGetProperty(hAlgorithm, L"ObjectLength", (PUCHAR)&cbHashObject, 4, &Unused, 0); + if (Status != 0) + return Status; + // Try allocating required memory. + // FIXME: Memory leak occours when this memory management feature is used (matches Vista extended kernel). On a future One-Core-API version bcrypt.dll will be replaced with Windows 8 by making modern ksecdd.sys run side-by-side with 5456.5's ksecdd.sys. + pbHashObject = (PUCHAR)RtlAllocateHeap(NtCurrentTeb()->Peb->ProcessHeap, 0, cbHashObject); + } + return BCryptCreateHashNative(hAlgorithm, phHash, pbHashObject, cbHashObject, pbSecret, cbSecret, dwFlags); +} - // if (cIterations < 1 || cbDerivedKey == 0 || !hPrf) - // return STATUS_INVALID_PARAMETER; - // if (cbSalt == 0 || cbSalt > SIZE_MAX - 4) - // return STATUS_INVALID_PARAMETER; +NTSTATUS +WINAPI +BCryptDeriveKeyPBKDF2( + _In_ BCRYPT_ALG_HANDLE hPrf, + _In_reads_bytes_opt_( cbPassword ) PUCHAR pbPassword, + _In_ ULONG cbPassword, + _In_reads_bytes_opt_( cbSalt ) PUCHAR pbSalt, + _In_ ULONG cbSalt, + _In_ ULONGLONG cIterations, + _Out_writes_bytes_( cbDerivedKey ) PUCHAR pbDerivedKey, + _In_ ULONG cbDerivedKey, + _In_ ULONG dwFlags +) +{ + UCHAR* aSalt, *obuf; // Update this, use variable digest length obtained from BCryptGetProperty call + UCHAR* d1, *d2; + ULONG i, j; + ULONG count, ResultLength; + size_t r; + DWORD DigestLength; + //BCRYPT_HASH_HANDLE hHash; + NTSTATUS Status = STATUS_SUCCESS; + + if (cIterations < 1 || cbDerivedKey == 0 || !hPrf) + return STATUS_INVALID_PARAMETER; + if (cbSalt == 0 || cbSalt > SIZE_MAX - 4) + return STATUS_INVALID_PARAMETER; - // Status = BCryptGetProperty(hPrf, L"HashDigestLength", (PUCHAR)&DigestLength, sizeof(DWORD), &ResultLength, 0); - // if(Status < STATUS_SUCCESS) - // return Status; + Status = BCryptGetProperty(hPrf, L"HashDigestLength", (PUCHAR)&DigestLength, sizeof(DWORD), &ResultLength, 0); + if(Status < STATUS_SUCCESS) + return Status; - // if ((aSalt = (PUCHAR)RtlAllocateHeap(NtCurrentTeb()->Peb->ProcessHeap, 0, cbSalt + 4)) == NULL) - // return STATUS_NO_MEMORY; + if ((aSalt = (PUCHAR)RtlAllocateHeap(NtCurrentTeb()->Peb->ProcessHeap, 0, cbSalt + 4)) == NULL) + return STATUS_NO_MEMORY; - // if ((obuf = (PUCHAR)RtlAllocateHeap(NtCurrentTeb()->Peb->ProcessHeap, 0, DigestLength)) == NULL) - // { - // BCryptFree(aSalt); // undocumented function exported from BCrypt - basically a wrapper for RtlFreeHeap with flags = 0 and PEB heap - // return STATUS_NO_MEMORY; - // } + if ((obuf = (PUCHAR)RtlAllocateHeap(NtCurrentTeb()->Peb->ProcessHeap, 0, DigestLength)) == NULL) + { + BCryptFree(aSalt); // undocumented function exported from BCrypt - basically a wrapper for RtlFreeHeap with flags = 0 and PEB heap + return STATUS_NO_MEMORY; + } - // if ((d1 = (PUCHAR)RtlAllocateHeap(NtCurrentTeb()->Peb->ProcessHeap, 0, DigestLength)) == NULL) - // { - // BCryptFree(aSalt); - // BCryptFree(obuf); - // return STATUS_NO_MEMORY; - // } - - // if ((d2 = (PUCHAR)RtlAllocateHeap(NtCurrentTeb()->Peb->ProcessHeap, 0, DigestLength)) == NULL) - // { - // BCryptFree(aSalt); - // BCryptFree(obuf); - // BCryptFree(d1); - // return STATUS_NO_MEMORY; - // } - - // memcpy(aSalt, pbSalt, cbSalt); - - // for (count = 1; cbDerivedKey > 0; count++) { - // aSalt[cbSalt + 0] = (count >> 24) & 0xff; - // aSalt[cbSalt + 1] = (count >> 16) & 0xff; - // aSalt[cbSalt + 2] = (count >> 8) & 0xff; - // aSalt[cbSalt + 3] = count & 0xff; - // Status = BCryptHash(hPrf, (PUCHAR)pbPassword, cbPassword, aSalt, cbSalt + 4, d1, DigestLength); - // if (Status < STATUS_SUCCESS) - // goto FreeMemory; - // memcpy(obuf, d1, DigestLength); - - // for (i = 1; i < cIterations; i++) { - // Status = BCryptHash(hPrf, (PUCHAR)pbPassword, cbPassword, d1, DigestLength, d2, DigestLength); - // if (Status < STATUS_SUCCESS) - // goto FreeMemory; - // memcpy(d1, d2, DigestLength); - // for (j = 0; j < DigestLength; j++) - // obuf[j] ^= d1[j]; - // } - - // r = min(cbDerivedKey, DigestLength); - // memcpy(pbDerivedKey, obuf, r); - // pbDerivedKey += r; - // cbDerivedKey -= r; - // }; + if ((d1 = (PUCHAR)RtlAllocateHeap(NtCurrentTeb()->Peb->ProcessHeap, 0, DigestLength)) == NULL) + { + BCryptFree(aSalt); + BCryptFree(obuf); + return STATUS_NO_MEMORY; + } + + if ((d2 = (PUCHAR)RtlAllocateHeap(NtCurrentTeb()->Peb->ProcessHeap, 0, DigestLength)) == NULL) + { + BCryptFree(aSalt); + BCryptFree(obuf); + BCryptFree(d1); + return STATUS_NO_MEMORY; + } + + memcpy(aSalt, pbSalt, cbSalt); + + for (count = 1; cbDerivedKey > 0; count++) { + aSalt[cbSalt + 0] = (count >> 24) & 0xff; + aSalt[cbSalt + 1] = (count >> 16) & 0xff; + aSalt[cbSalt + 2] = (count >> 8) & 0xff; + aSalt[cbSalt + 3] = count & 0xff; + Status = BCryptHash(hPrf, (PUCHAR)pbPassword, cbPassword, aSalt, cbSalt + 4, d1, DigestLength); + if (Status < STATUS_SUCCESS) + goto FreeMemory; + memcpy(obuf, d1, DigestLength); + + for (i = 1; i < cIterations; i++) { + Status = BCryptHash(hPrf, (PUCHAR)pbPassword, cbPassword, d1, DigestLength, d2, DigestLength); + if (Status < STATUS_SUCCESS) + goto FreeMemory; + memcpy(d1, d2, DigestLength); + for (j = 0; j < DigestLength; j++) + obuf[j] ^= d1[j]; + } + + r = min(cbDerivedKey, DigestLength); + memcpy(pbDerivedKey, obuf, r); + pbDerivedKey += r; + cbDerivedKey -= r; + }; -// FreeMemory: - // memset(aSalt, 0, cbSalt + 4); - // BCryptFree(aSalt); - // memset(d1, 0, DigestLength); - // BCryptFree(d1); - // memset(d2, 0, DigestLength); - // BCryptFree(d2); - // memset(obuf, 0, DigestLength); - // BCryptFree(obuf); +FreeMemory: + memset(aSalt, 0, cbSalt + 4); + BCryptFree(aSalt); + memset(d1, 0, DigestLength); + BCryptFree(d1); + memset(d2, 0, DigestLength); + BCryptFree(d2); + memset(obuf, 0, DigestLength); + BCryptFree(obuf); - // return Status; -// } - - // NTSTATUS, - // WINAPI, - // BCryptDeriveKeyCapi, - // _In_ BCRYPT_HASH_HANDLE hHash, - // _In_opt_ BCRYPT_ALG_HANDLE hTargetAlg, - // _Out_writes_bytes_( cbDerivedKey ) PUCHAR pbDerivedKey, - // _In_ ULONG cbDerivedKey, - // _In_ ULONG dwFlags - // ) - // { - // if (const auto _pfnBCryptDeriveKeyCapi = try_get_BCryptDeriveKeyCapi()) - // { - // return _pfnBCryptDeriveKeyCapi(hHash, hTargetAlg, pbDerivedKey, cbDerivedKey, dwFlags); - // } - - // if (dwFlags != 0 || (pbDerivedKey == nullptr && cbDerivedKey)) - // { - // return STATUS_INVALID_PARAMETER; - // } - - // ULONG _cbResult = 0; - // DWORD _uHashLength = 0; - // int _Status = ::BCryptGetProperty(hHash, BCRYPT_HASH_LENGTH, (PUCHAR)&_uHashLength, sizeof(_uHashLength), &_cbResult, 0); - // if (_Status < 0) - // return _Status; - - // constexpr auto kMaxHashLength = 512 / 8; - // if (kMaxHashLength < _uHashLength || _uHashLength * 2 < cbDerivedKey) - // { - // return STATUS_INVALID_PARAMETER; - // } - - // UCHAR _Hash[kMaxHashLength * 2]; - // _Status = BCryptFinishHash(hHash, _Hash, _uHashLength, 0); - // if (_Status < 0) - // return _Status; - - // auto v19 = _uHashLength < cbDerivedKey; - - // wchar_t szAlgorithmNameBuffer[4]; - // if (hTargetAlg && cbDerivedKey == 16 && _uHashLength < 32 - // && BCryptGetProperty(hTargetAlg, BCRYPT_ALGORITHM_NAME, (PUCHAR)szAlgorithmNameBuffer, sizeof(szAlgorithmNameBuffer), &_cbResult, 0) >= 0 - // && StringCompareIgnoreCaseByAscii(szAlgorithmNameBuffer, L"AES", -1) == 0) - // { - // v19 = true; - // } - - // if (!v19) - // { - // memcpy(pbDerivedKey, _Hash, cbDerivedKey); - // return STATUS_SUCCESS; - // } - - // UCHAR _FirstHash[kMaxHashLength]; - // UCHAR _SecondHash[kMaxHashLength]; - - // memset(_FirstHash, 0x36, sizeof(_FirstHash)); - // memset(_SecondHash, 0x5C, sizeof(_SecondHash)); - - // for (DWORD i = 0; i != _uHashLength; ++i) - // { - // _FirstHash[i] ^= _Hash[i]; - // _SecondHash[i] ^= _Hash[i]; - // } - - // BCRYPT_ALG_HANDLE hProvider; - // _Status = BCryptGetProperty(hHash, BCRYPT_PROVIDER_HANDLE, (PUCHAR)&hProvider, sizeof(hProvider), &_cbResult, 0); - // if (_Status < 0) - // return _Status; - - // DWORD _cbHashObjectLength = 0; - // _Status = BCryptGetProperty(hProvider, BCRYPT_OBJECT_LENGTH, (PUCHAR)&_cbHashObjectLength, sizeof(_cbHashObjectLength), &_cbResult, 0); - // if (_Status < 0) - // return _Status; - - // auto _pHashObjectBuffer = (PUCHAR)_malloca(_cbHashObjectLength); - // if (!_pHashObjectBuffer) - // return STATUS_NO_MEMORY; - - // BCRYPT_HASH_HANDLE hHash2 = NULL; - // do - // { - // _Status = BCryptCreateHash(hProvider, &hHash2, _pHashObjectBuffer, _cbHashObjectLength, nullptr, 0, 0); - // if (_Status < 0) - // break; - - // _Status = BCryptHashData(hHash2, _FirstHash, sizeof(_FirstHash), 0); - // if (_Status < 0) - // break; - - // _Status = BCryptFinishHash(hHash2, _Hash, _uHashLength, 0); - // if (_Status < 0) - // break; - // BCryptDestroyHash(hHash2); - // hHash2 = NULL; - - // _Status = BCryptCreateHash(hProvider, &hHash2, _pHashObjectBuffer, _cbHashObjectLength, nullptr, 0, 0); - // if (_Status < 0) - // break; - - // _Status = BCryptHashData(hHash2, _SecondHash, sizeof(_SecondHash), 0); - // if (_Status < 0) - // break; - - // _Status = BCryptFinishHash(hHash2, _Hash + _uHashLength, _uHashLength, 0); - // if (_Status < 0) - // break; - - // memcpy(pbDerivedKey, _Hash, cbDerivedKey); - // _Status = STATUS_SUCCESS; - - // } while (false); - - // if (hHash2) - // BCryptDestroyHash(hHash2); + return Status; +} - // if (_pHashObjectBuffer) - // _freea(_pHashObjectBuffer); - // return _Status; - // } +NTSTATUS +WINAPI +BCryptDeriveKeyCapi( + _In_ BCRYPT_HASH_HANDLE hHash, + _In_opt_ BCRYPT_ALG_HANDLE hTargetAlg, + _Out_writes_bytes_( cbDerivedKey ) PUCHAR pbDerivedKey, + _In_ ULONG cbDerivedKey, + _In_ ULONG dwFlags +) +{ + ULONG _cbResult = 0; + DWORD _uHashLength = 0; + UCHAR _Hash[kMaxHashLength * 2]; + int _Status; + BOOLEAN checkHashLength; + wchar_t szAlgorithmNameBuffer[4]; + UCHAR _FirstHash[kMaxHashLength]; + UCHAR _SecondHash[kMaxHashLength]; + BCRYPT_ALG_HANDLE hProvider; + DWORD i; + DWORD _cbHashObjectLength = 0; + BCRYPT_HASH_HANDLE hHash2 = NULL; + PUCHAR _pHashObjectBuffer; + + if (dwFlags != 0 || (pbDerivedKey == NULL && cbDerivedKey)) + { + return STATUS_INVALID_PARAMETER; + } + + + _Status = BCryptGetProperty(hHash, BCRYPT_HASH_LENGTH, (PUCHAR)&_uHashLength, sizeof(_uHashLength), &_cbResult, 0); + if (_Status < 0) + return _Status; + + if (kMaxHashLength < _uHashLength || _uHashLength * 2 < cbDerivedKey) + { + return STATUS_INVALID_PARAMETER; + } + + + _Status = BCryptFinishHash(hHash, _Hash, _uHashLength, 0); + if (_Status < 0) + return _Status; + + checkHashLength = _uHashLength < cbDerivedKey; + + if (hTargetAlg && cbDerivedKey == 16 && _uHashLength < 32 + && BCryptGetProperty(hTargetAlg, BCRYPT_ALGORITHM_NAME, (PUCHAR)szAlgorithmNameBuffer, sizeof(szAlgorithmNameBuffer), &_cbResult, 0) >= 0 + && StringCompareIgnoreCaseByAscii((const char* )szAlgorithmNameBuffer, (const char* )L"AES", -1) == 0) + { + checkHashLength = TRUE; + } + + if (!checkHashLength) + { + memcpy(pbDerivedKey, _Hash, cbDerivedKey); + return STATUS_SUCCESS; + } + + memset(_FirstHash, 0x36, sizeof(_FirstHash)); + memset(_SecondHash, 0x5C, sizeof(_SecondHash)); + + for (i = 0; i != _uHashLength; ++i) + { + _FirstHash[i] ^= _Hash[i]; + _SecondHash[i] ^= _Hash[i]; + } + + _Status = BCryptGetProperty(hHash, BCRYPT_PROVIDER_HANDLE, (PUCHAR)&hProvider, sizeof(hProvider), &_cbResult, 0); + if (_Status < 0) + return _Status; + + _Status = BCryptGetProperty(hProvider, BCRYPT_OBJECT_LENGTH, (PUCHAR)&_cbHashObjectLength, sizeof(_cbHashObjectLength), &_cbResult, 0); + if (_Status < 0) + return _Status; + + _pHashObjectBuffer = (PUCHAR)RtlAllocateHeap(NtCurrentTeb()->Peb->ProcessHeap, 0, _cbHashObjectLength); + if (!_pHashObjectBuffer) + return STATUS_NO_MEMORY; + + do + { + _Status = BCryptCreateHash(hProvider, &hHash2, _pHashObjectBuffer, _cbHashObjectLength, NULL, 0, 0); + if (_Status < 0) + break; + + _Status = BCryptHashData(hHash2, _FirstHash, sizeof(_FirstHash), 0); + if (_Status < 0) + break; + + _Status = BCryptFinishHash(hHash2, _Hash, _uHashLength, 0); + if (_Status < 0) + break; + BCryptDestroyHash(hHash2); + hHash2 = NULL; + + _Status = BCryptCreateHash(hProvider, &hHash2, _pHashObjectBuffer, _cbHashObjectLength, NULL, 0, 0); + if (_Status < 0) + break; + + _Status = BCryptHashData(hHash2, _SecondHash, sizeof(_SecondHash), 0); + if (_Status < 0) + break; + + _Status = BCryptFinishHash(hHash2, _Hash + _uHashLength, _uHashLength, 0); + if (_Status < 0) + break; + + memcpy(pbDerivedKey, _Hash, cbDerivedKey); + _Status = STATUS_SUCCESS; + + } while (FALSE); + + if (hHash2) + BCryptDestroyHash(hHash2); + + if (_pHashObjectBuffer) + RtlFreeHeap(NtCurrentTeb()->Peb->ProcessHeap, 0, _pHashObjectBuffer); + + return _Status; +} \ No newline at end of file diff --git a/wrappers/extensions/comdlgex/CMakeLists.txt b/wrappers/extensions/comdlgex/CMakeLists.txt deleted file mode 100644 index af0b865ff7..0000000000 --- a/wrappers/extensions/comdlgex/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ - -spec2def(comdlgex.dll comdlgex.spec) - -list(APPEND SOURCE - cdlg32.c - filedlg.c - filedlg31.c - filedlgbrowser.c - itemdlg.c - main.c - comdlg32.rc - ${CMAKE_CURRENT_BINARY_DIR}/comdlgex_stubs.c - ${CMAKE_CURRENT_BINARY_DIR}/comdlgex.def) - -set(baseaddress_comdlgex 0x7f550000) - -add_library(comdlgex SHARED ${SOURCE}) -set_module_type(comdlgex win32dll ENTRYPOINT DllMain) -add_importlibs(comdlgex comdlg32 user32 gdi32 advapi32 comctl32 shell32 shlwapi ole32 msvcrt kernel32 ntdll) -target_link_libraries(comdlgex uuid wine) -add_cd_file(TARGET comdlgex DESTINATION reactos/system32 FOR all) - -spec2def(comdlgex.dll comdlgex.spec) - - diff --git a/wrappers/extensions/comdlgex/cdlg.h b/wrappers/extensions/comdlgex/cdlg.h deleted file mode 100644 index 1ddd157b88..0000000000 --- a/wrappers/extensions/comdlgex/cdlg.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Common Dialog Boxes interface (32 bit) - * - * Copyright 1998 Bertho A. Stultiens - * - * 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 - */ - -#ifndef _WINE_DLL_CDLG_H -#define _WINE_DLL_CDLG_H - -#include "dlgs.h" - -/* Common dialogs implementation globals */ -#define COMDLG32_Atom MAKEINTATOM(0xa000) /* MS uses this one to identify props */ - -extern HINSTANCE COMDLG32_hInstance DECLSPEC_HIDDEN; - -void COMDLG32_SetCommDlgExtendedError(DWORD err) DECLSPEC_HIDDEN; -LPVOID COMDLG32_AllocMem(int size) __WINE_ALLOC_SIZE(1) DECLSPEC_HIDDEN; - -/* Find/Replace local definitions */ - -#define FR_WINE_UNICODE 0x80000000 -#define FR_WINE_REPLACE 0x40000000 - -typedef struct { - FINDREPLACEA fr; /* Internally used structure */ - union { - FINDREPLACEA *fra; /* Reference to the user supplied structure */ - FINDREPLACEW *frw; - } user_fr; -} COMDLG32_FR_Data; - -#define PD32_PRINT_TITLE 7000 - -#define PD32_VALUE_UREADABLE 1104 -#define PD32_INVALID_PAGE_RANGE 1105 -#define PD32_FROM_NOT_ABOVE_TO 1106 -#define PD32_MARGINS_OVERLAP 1107 -#define PD32_NR_OF_COPIES_EMPTY 1108 -#define PD32_TOO_LARGE_COPIES 1109 -#define PD32_PRINT_ERROR 1110 -#define PD32_NO_DEFAULT_PRINTER 1111 -#define PD32_CANT_FIND_PRINTER 1112 -#define PD32_OUT_OF_MEMORY 1113 -#define PD32_GENERIC_ERROR 1114 -#define PD32_DRIVER_UNKNOWN 1115 -#define PD32_NO_DEVICES 1121 - -#define PD32_PRINTER_STATUS_READY 1536 -#define PD32_PRINTER_STATUS_PAUSED 1537 -#define PD32_PRINTER_STATUS_ERROR 1538 -#define PD32_PRINTER_STATUS_PENDING_DELETION 1539 -#define PD32_PRINTER_STATUS_PAPER_JAM 1540 -#define PD32_PRINTER_STATUS_PAPER_OUT 1541 -#define PD32_PRINTER_STATUS_MANUAL_FEED 1542 -#define PD32_PRINTER_STATUS_PAPER_PROBLEM 1543 -#define PD32_PRINTER_STATUS_OFFLINE 1544 -#define PD32_PRINTER_STATUS_IO_ACTIVE 1545 -#define PD32_PRINTER_STATUS_BUSY 1546 -#define PD32_PRINTER_STATUS_PRINTING 1547 -#define PD32_PRINTER_STATUS_OUTPUT_BIN_FULL 1548 -#define PD32_PRINTER_STATUS_NOT_AVAILABLE 1549 -#define PD32_PRINTER_STATUS_WAITING 1550 -#define PD32_PRINTER_STATUS_PROCESSING 1551 -#define PD32_PRINTER_STATUS_INITIALIZING 1552 -#define PD32_PRINTER_STATUS_WARMING_UP 1553 -#define PD32_PRINTER_STATUS_TONER_LOW 1554 -#define PD32_PRINTER_STATUS_NO_TONER 1555 -#define PD32_PRINTER_STATUS_PAGE_PUNT 1556 -#define PD32_PRINTER_STATUS_USER_INTERVENTION 1557 -#define PD32_PRINTER_STATUS_OUT_OF_MEMORY 1558 -#define PD32_PRINTER_STATUS_DOOR_OPEN 1559 -#define PD32_PRINTER_STATUS_SERVER_UNKNOWN 1560 -#define PD32_PRINTER_STATUS_POWER_SAVE 1561 - -#define PD32_DEFAULT_PRINTER 1582 -#define PD32_NR_OF_DOCUMENTS_IN_QUEUE 1583 - -#define PD32_MARGINS_IN_INCHES 1585 -#define PD32_MARGINS_IN_MILLIMETERS 1586 -#define PD32_MILLIMETERS 1587 - -/* Charset names string IDs */ - -#define IDS_CHARSET_ANSI 200 -#define IDS_CHARSET_SYMBOL 201 -#define IDS_CHARSET_JIS 202 -#define IDS_CHARSET_HANGUL 203 -#define IDS_CHARSET_GB2312 204 -#define IDS_CHARSET_BIG5 205 -#define IDS_CHARSET_GREEK 206 -#define IDS_CHARSET_TURKISH 207 -#define IDS_CHARSET_HEBREW 208 -#define IDS_CHARSET_ARABIC 209 -#define IDS_CHARSET_BALTIC 210 -#define IDS_CHARSET_VIETNAMESE 211 -#define IDS_CHARSET_RUSSIAN 212 -#define IDS_CHARSET_EE 213 -#define IDS_CHARSET_THAI 214 -#define IDS_CHARSET_JOHAB 215 -#define IDS_CHARSET_MAC 216 -#define IDS_CHARSET_OEM 217 -#define IDS_CHARSET_VISCII 218 -#define IDS_CHARSET_TCVN 219 -#define IDS_CHARSET_KOI8 220 -#define IDS_CHARSET_ISO3 221 -#define IDS_CHARSET_ISO4 222 -#define IDS_CHARSET_ISO10 223 -#define IDS_CHARSET_CELTIC 224 - -/* Font styles */ - -#define IDS_FONT_REGULAR 256 -#define IDS_FONT_BOLD 257 -#define IDS_FONT_ITALIC 258 -#define IDS_FONT_BOLD_ITALIC 259 - -/* Color names string IDs */ - -#define IDS_COLOR_BLACK 1040 -#define IDS_COLOR_MAROON 1041 -#define IDS_COLOR_GREEN 1042 -#define IDS_COLOR_OLIVE 1043 -#define IDS_COLOR_NAVY 1044 -#define IDS_COLOR_PURPLE 1045 -#define IDS_COLOR_TEAL 1046 -#define IDS_COLOR_GRAY 1047 -#define IDS_COLOR_SILVER 1048 -#define IDS_COLOR_RED 1049 -#define IDS_COLOR_LIME 1050 -#define IDS_COLOR_YELLOW 1051 -#define IDS_COLOR_BLUE 1052 -#define IDS_COLOR_FUCHSIA 1053 -#define IDS_COLOR_AQUA 1054 -#define IDS_COLOR_WHITE 1055 - -#define IDS_FONT_SIZE 1200 -#define IDS_SAVE_BUTTON 1201 -#define IDS_SAVE_IN 1202 -#define IDS_SAVE 1203 -#define IDS_SAVE_AS 1204 -#define IDS_OPEN_FILE 1205 -#define IDS_SELECT_FOLDER 1206 -#define IDS_FONT_SIZE_INPUT 1207 - -#define IDS_FAKEDOCTEXT 1300 - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "winnls.h" -#include "commctrl.h" -#include "shlobj.h" -#include "shellapi.h" - -/* Constructors */ -HRESULT FileOpenDialog_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv) DECLSPEC_HIDDEN; -HRESULT FileSaveDialog_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv) DECLSPEC_HIDDEN; - -/* Shared helper functions */ -void COMDLG32_GetCanonicalPath(PCIDLIST_ABSOLUTE pidlAbsCurrent, LPWSTR lpstrFile, LPWSTR lpstrPathAndFile) DECLSPEC_HIDDEN; -int FILEDLG95_ValidatePathAction(LPWSTR lpstrPathAndFile, IShellFolder **ppsf, - HWND hwnd, DWORD flags, BOOL isSaveDlg, int defAction) DECLSPEC_HIDDEN; -int COMDLG32_SplitFileNames(LPWSTR lpstrEdit, UINT nStrLen, LPWSTR *lpstrFileList, UINT *sizeUsed) DECLSPEC_HIDDEN; -void FILEDLG95_OnOpenMessage(HWND hwnd, int idCaption, int idText) DECLSPEC_HIDDEN; - -extern BOOL GetFileName31A( OPENFILENAMEA *lpofn, UINT dlgType ) DECLSPEC_HIDDEN; -extern BOOL GetFileName31W( OPENFILENAMEW *lpofn, UINT dlgType ) DECLSPEC_HIDDEN; - -/* SHELL */ -extern LPITEMIDLIST (WINAPI *COMDLG32_SHSimpleIDListFromPathAW)(LPCVOID); - -#define ONOPEN_BROWSE 1 -#define ONOPEN_OPEN 2 -#define ONOPEN_SEARCH 3 - -#endif /* _WINE_DLL_CDLG_H */ diff --git a/wrappers/extensions/comdlgex/cdlg32.c b/wrappers/extensions/comdlgex/cdlg32.c deleted file mode 100644 index 815078aab3..0000000000 --- a/wrappers/extensions/comdlgex/cdlg32.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Common Dialog Boxes interface (32 bit) - * Find/Replace - * - * Copyright 1999 Bertho A. Stultiens - * - * 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 - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "objbase.h" -#include "rpcproxy.h" -#include "commdlg.h" -#include "cderr.h" -#include "wine/debug.h" -#include "wine/heap.h" - -#define NDEBUG -#include - -WINE_DEFAULT_DEBUG_CHANNEL(commdlg); - -#include "cdlg.h" - - -DECLSPEC_HIDDEN HINSTANCE COMDLG32_hInstance = 0; - -static DWORD COMDLG32_TlsIndex = TLS_OUT_OF_INDEXES; - -static HINSTANCE SHELL32_hInstance; - -HANDLE COMDLG32_hActCtx = INVALID_HANDLE_VALUE; - -/* SHELL */ -LPITEMIDLIST (WINAPI *COMDLG32_SHSimpleIDListFromPathAW)(LPCVOID) DECLSPEC_HIDDEN; - -/*********************************************************************** - * DllMain (COMDLG32.init) - * - * Initialization code for the COMDLG32 DLL - * - * RETURNS: - * FALSE if sibling could not be loaded or instantiated twice, TRUE - * otherwise. - */ -static const char GPA_string[] = "Failed to get entry point %s for hinst = %p\n"; -#define GPA(dest, hinst, name) \ - if(!(dest = (void*)GetProcAddress(hinst,name)))\ - { \ - ERR(GPA_string, debugstr_a(name), hinst); \ - return FALSE; \ - } - -BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved) -{ - ACTCTXW actctx = {0}; - TRACE("(%p, %ld, %p)\n", hInstance, Reason, Reserved); - - switch(Reason) - { - case DLL_PROCESS_ATTACH: - - COMDLG32_hInstance = hInstance; - DisableThreadLibraryCalls(hInstance); - - SHELL32_hInstance = GetModuleHandleA("SHELL32.DLL"); - actctx.cbSize = sizeof(actctx); - actctx.hModule = COMDLG32_hInstance; - actctx.lpResourceName = MAKEINTRESOURCEW(123); - actctx.dwFlags = ACTCTX_FLAG_HMODULE_VALID | ACTCTX_FLAG_RESOURCE_NAME_VALID; - // COMDLG32_hActCtx = CreateActCtxW(&actctx); - // if (COMDLG32_hActCtx == INVALID_HANDLE_VALUE) - // ERR("failed to create activation context, last error %lu\n", GetLastError()); - - - - /* SHELL */ - GPA(COMDLG32_SHSimpleIDListFromPathAW, SHELL32_hInstance, (LPCSTR)162); - break; - - case DLL_PROCESS_DETACH: - if (Reserved) break; - if (Reserved) break; - if (COMDLG32_TlsIndex != TLS_OUT_OF_INDEXES) TlsFree(COMDLG32_TlsIndex); - if (COMDLG32_hActCtx != INVALID_HANDLE_VALUE) ReleaseActCtx(COMDLG32_hActCtx); - - break; - } - return TRUE; -} -#undef GPA - -/*********************************************************************** - * COMDLG32_AllocMem (internal) - * Get memory for internal datastructure plus stringspace etc. - * RETURNS - * Success: Pointer to a heap block - * Failure: null - */ -void *COMDLG32_AllocMem(int size) -{ - void *ptr = heap_alloc_zero(size); - - if (!ptr) - { - COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE); - return NULL; - } - - return ptr; -} - - -/*********************************************************************** - * COMDLG32_SetCommDlgExtendedError (internal) - * - * Used to set the thread's local error value if a comdlg32 function fails. - */ -void COMDLG32_SetCommDlgExtendedError(DWORD err) -{ - TRACE("(%08lx)\n", err); - if (COMDLG32_TlsIndex == TLS_OUT_OF_INDEXES) - COMDLG32_TlsIndex = TlsAlloc(); - if (COMDLG32_TlsIndex != TLS_OUT_OF_INDEXES) - TlsSetValue(COMDLG32_TlsIndex, (LPVOID)(DWORD_PTR)err); - else - FIXME("No Tls Space\n"); -} - -/************************************************************************* - * Implement the CommDlg32 class factory - * - * (Taken from shdocvw/factory.c; based on implementation in - * ddraw/main.c) - */ -typedef struct -{ - IClassFactory IClassFactory_iface; - HRESULT (*cf)(IUnknown*, REFIID, void**); -} IClassFactoryImpl; - -static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) -{ - return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); -} - -/************************************************************************* - * CDLGCF_QueryInterface (IUnknown) - */ -static HRESULT WINAPI CDLGCF_QueryInterface(IClassFactory* iface, - REFIID riid, void **ppobj) -{ - TRACE("%p (%s %p)\n", iface, debugstr_guid(riid), ppobj); - - if(!ppobj) - return E_POINTER; - - if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) - { - *ppobj = iface; - IClassFactory_AddRef(iface); - return S_OK; - } - - WARN("Interface not supported.\n"); - - *ppobj = NULL; - return E_NOINTERFACE; -} - -/************************************************************************* - * CDLGCF_AddRef (IUnknown) - */ -static ULONG WINAPI CDLGCF_AddRef(IClassFactory *iface) -{ - return 2; /* non-heap based object */ -} - -/************************************************************************* - * CDLGCF_Release (IUnknown) - */ -static ULONG WINAPI CDLGCF_Release(IClassFactory *iface) -{ - return 1; /* non-heap based object */ -} - -/************************************************************************* - * CDLGCF_CreateInstance (IClassFactory) - */ -static HRESULT WINAPI CDLGCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, - REFIID riid, void **ppobj) -{ - IClassFactoryImpl *This = impl_from_IClassFactory(iface); - return This->cf(pOuter, riid, ppobj); -} - -/************************************************************************* - * CDLGCF_LockServer (IClassFactory) - */ -static HRESULT WINAPI CDLGCF_LockServer(IClassFactory *iface, BOOL dolock) -{ - TRACE("%p (%d)\n", iface, dolock); - return S_OK; -} - -static const IClassFactoryVtbl CDLGCF_Vtbl = -{ - CDLGCF_QueryInterface, - CDLGCF_AddRef, - CDLGCF_Release, - CDLGCF_CreateInstance, - CDLGCF_LockServer -}; - -/************************************************************************* - * DllGetClassObject (COMMDLG32.@) - */ -HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) -{ - static IClassFactoryImpl FileOpenDlgClassFactory = {{&CDLGCF_Vtbl}, FileOpenDialog_Constructor}; - static IClassFactoryImpl FileSaveDlgClassFactory = {{&CDLGCF_Vtbl}, FileSaveDialog_Constructor}; - - DbgPrint("DllGetClassObject:: %s, %s, %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); - - if(IsEqualGUID(&CLSID_FileOpenDialog, rclsid)) - return IClassFactory_QueryInterface(&FileOpenDlgClassFactory.IClassFactory_iface, riid, ppv); - - if(IsEqualGUID(&CLSID_FileSaveDialog, rclsid)) - return IClassFactory_QueryInterface(&FileSaveDlgClassFactory.IClassFactory_iface, riid, ppv); - - DbgPrint("Comdlg32::DllGetClassObject:: Interface not found\n"); - - return CLASS_E_CLASSNOTAVAILABLE; -} diff --git a/wrappers/extensions/comdlgex/cdrom.ico b/wrappers/extensions/comdlgex/cdrom.ico deleted file mode 100644 index 5673c9c2f1..0000000000 Binary files a/wrappers/extensions/comdlgex/cdrom.ico and /dev/null differ diff --git a/wrappers/extensions/comdlgex/comdlg32.manifest b/wrappers/extensions/comdlgex/comdlg32.manifest deleted file mode 100644 index f9e7b7cc11..0000000000 --- a/wrappers/extensions/comdlgex/comdlg32.manifest +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - diff --git a/wrappers/extensions/comdlgex/comdlg32.rc b/wrappers/extensions/comdlgex/comdlg32.rc deleted file mode 100644 index a42527f544..0000000000 --- a/wrappers/extensions/comdlgex/comdlg32.rc +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Resources for Common Dialogs - * - * Copyright 1999 Bertho Stultiens - * Copyright 1999 Klaas van Gend - * - * 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 "cdlg.h" -#include "colordlg.h" -#include "filedlgbrowser.h" - -#pragma makedep po - -LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT - -STRINGTABLE -{ - IDS_FILENOTFOUND "File not found" - IDS_VERIFYFILE "Please verify that the correct file name was given" - IDS_CREATEFILE "File does not exist.\nDo you want to create file?" - IDS_OVERWRITEFILE "File already exists.\nDo you want to replace it?" - IDS_INVALID_FILENAME_TITLE "Invalid character(s) in path" - IDS_INVALID_FILENAME "A filename cannot contain any of the following characters:\n / : < > |" - IDS_PATHNOTEXISTING "Path does not exist" - IDS_FILENOTEXISTING "File does not exist" - IDS_INVALID_FOLDERNAME "The selection contains a non-folder object" -} - -STRINGTABLE -{ - IDS_UPFOLDER "Up One Level" - IDS_NEWFOLDER "Create New Folder" - IDS_LISTVIEW "List" - IDS_REPORTVIEW "Details" - IDS_TODESKTOP "Browse to Desktop" -} - -STRINGTABLE -{ - PD32_PRINT_TITLE "Print" - - PD32_VALUE_UREADABLE "Unreadable Entry" - PD32_INVALID_PAGE_RANGE "This value does not lie within the page range.\n\ -Please enter a value between %1!d! and %2!d!." - PD32_FROM_NOT_ABOVE_TO "The 'from' entry cannot exceed the \ -'to' entry." - PD32_MARGINS_OVERLAP "Margins overlap or fall outside \ -Paper boundaries.\nPlease reenter margins." - PD32_NR_OF_COPIES_EMPTY "The 'Number of copies' field \ -cannot be empty." - PD32_TOO_LARGE_COPIES "This large number of copies is not \ -supported by your printer.\nPlease enter a value between 1 and %d." - PD32_PRINT_ERROR "A printer error occurred." - PD32_NO_DEFAULT_PRINTER "No default printer defined." - PD32_CANT_FIND_PRINTER "Cannot find the printer." - PD32_OUT_OF_MEMORY "Out of memory." - PD32_GENERIC_ERROR "An error occurred." - PD32_DRIVER_UNKNOWN "Unknown printer driver." - PD32_NO_DEVICES "Before you can perform printer-related tasks \ -such as page setup or printing a document, you need to install a printer. \ -Please install one and retry." - - PD32_DEFAULT_PRINTER "Default Printer; " - PD32_NR_OF_DOCUMENTS_IN_QUEUE "There are %d documents in the queue" - PD32_MARGINS_IN_INCHES "Margins [inches]" - PD32_MARGINS_IN_MILLIMETERS "Margins [mm]" - PD32_MILLIMETERS "#msgctxt#unit: millimeters#mm" - - PD32_PRINTER_STATUS_READY "Ready" - PD32_PRINTER_STATUS_PAUSED "Paused; " - PD32_PRINTER_STATUS_ERROR "Error; " - PD32_PRINTER_STATUS_PENDING_DELETION "Pending deletion; " - PD32_PRINTER_STATUS_PAPER_JAM "Paper jam; " - PD32_PRINTER_STATUS_PAPER_OUT "Out of paper; " - PD32_PRINTER_STATUS_MANUAL_FEED "Feed paper manual; " - PD32_PRINTER_STATUS_PAPER_PROBLEM "Paper problem; " - PD32_PRINTER_STATUS_OFFLINE "Printer offline; " - PD32_PRINTER_STATUS_IO_ACTIVE "I/O Active; " - PD32_PRINTER_STATUS_BUSY "Busy; " - PD32_PRINTER_STATUS_PRINTING "Printing; " - PD32_PRINTER_STATUS_OUTPUT_BIN_FULL "Output tray is full; " - PD32_PRINTER_STATUS_NOT_AVAILABLE "Not available; " - PD32_PRINTER_STATUS_WAITING "Waiting; " - PD32_PRINTER_STATUS_PROCESSING "Processing; " - PD32_PRINTER_STATUS_INITIALIZING "Initializing; " - PD32_PRINTER_STATUS_WARMING_UP "Warming up; " - PD32_PRINTER_STATUS_TONER_LOW "Toner low; " - PD32_PRINTER_STATUS_NO_TONER "No toner; " - PD32_PRINTER_STATUS_PAGE_PUNT "Page punt; " - PD32_PRINTER_STATUS_USER_INTERVENTION "Interrupted by user; " - PD32_PRINTER_STATUS_OUT_OF_MEMORY "Out of memory; " - PD32_PRINTER_STATUS_DOOR_OPEN "The printer door is open; " - PD32_PRINTER_STATUS_SERVER_UNKNOWN "Print server unknown; " - PD32_PRINTER_STATUS_POWER_SAVE "Power save mode; " -} - -STRINGTABLE /* Font styles */ -{ - IDS_FONT_REGULAR "Regular" - IDS_FONT_BOLD "Bold" - IDS_FONT_ITALIC "Italic" - IDS_FONT_BOLD_ITALIC "Bold Italic" -} - -STRINGTABLE /* Color names */ -{ - IDS_COLOR_BLACK "Black" - IDS_COLOR_MAROON "Maroon" - IDS_COLOR_GREEN "Green" - IDS_COLOR_OLIVE "Olive" - IDS_COLOR_NAVY "Navy" - IDS_COLOR_PURPLE "Purple" - IDS_COLOR_TEAL "Teal" - IDS_COLOR_GRAY "Gray" - IDS_COLOR_SILVER "Silver" - IDS_COLOR_RED "Red" - IDS_COLOR_LIME "Lime" - IDS_COLOR_YELLOW "Yellow" - IDS_COLOR_BLUE "Blue" - IDS_COLOR_FUCHSIA "Fuchsia" - IDS_COLOR_AQUA "Aqua" - IDS_COLOR_WHITE "White" -} - -STRINGTABLE -{ - IDS_FONT_SIZE "Select a font size between %1!d! and %2!d! points." - IDS_SAVE_BUTTON "&Save" - IDS_SAVE_IN "Save &in:" - IDS_SAVE "Save" - IDS_SAVE_AS "Save As" - IDS_OPEN_FILE "Open File" - IDS_SELECT_FOLDER "Select Folder" - IDS_FONT_SIZE_INPUT "Font size has to be a number." -} - -/* - * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. - */ - -OPEN_FILE DIALOG 36, 24, 275, 134 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Open" -FONT 8, "MS Shell Dlg" -{ - LTEXT "File &Name:", stc3, 6, 6, 76, 9 - EDITTEXT edt1, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP - LISTBOX lst1, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "&Directories:", -1, 110, 6, 92, 9 - LTEXT "", stc1, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP - LISTBOX lst2, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "List Files of &Type:", stc2, 6, 104, 90, 9 - COMBOBOX cmb1, 6, 114, 90, 60, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP - LTEXT "Dri&ves:", stc4, 110, 104, 92, 9 - COMBOBOX cmb2, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Open", IDOK, 208, 6, 60, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL, 208, 24, 60, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Help", pshHelp, 208, 46, 60, 14, WS_GROUP | WS_TABSTOP - CHECKBOX "&Read Only", chx1, 208, 68, 65, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP -} - - -SAVE_FILE DIALOG 36, 24, 275, 134 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Save As..." -FONT 8, "MS Shell Dlg" -{ - LTEXT "File &Name:", stc3, 6, 6, 76, 9 - EDITTEXT edt1, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP - LISTBOX lst1, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "&Directories:", -1, 110, 6, 92, 9 - LTEXT "", stc1, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP - LISTBOX lst2, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "List Files of &Type:", stc2, 6, 104, 90, 9 - COMBOBOX cmb1, 6, 114, 90, 60, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP - LTEXT "Dri&ves:", stc4, 110, 104, 92, 9 - COMBOBOX cmb2, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Save As", IDOK, 208, 6, 60, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL, 208, 24, 60, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Help", pshHelp, 208, 46, 60, 14, WS_GROUP | WS_TABSTOP - CHECKBOX "&Read Only", chx1, 208, 68, 65, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP -} - - -PRINT DIALOG 36, 24, 264, 134 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Print" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Printer:", stc1, 6, 6, 40, 9 - LTEXT "", stc2, 60, 6, 150, 9 - GROUPBOX "Print range", grp1, 6, 30, 160, 65, BS_GROUPBOX - RADIOBUTTON "&All", rad1, 16, 45, 60, 12 - RADIOBUTTON "S&election", rad2, 16, 60, 60, 12 - RADIOBUTTON "&Pages", rad3, 16, 75, 60, 12 - DEFPUSHBUTTON "Print", IDOK, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Setup", psh1, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP - LTEXT "&From:", stc3, 60, 80, 30, 9 - LTEXT "&To:", stc4, 120, 80, 30, 9 - LTEXT "Print &Quality:", stc5, 6, 100, 76, 9 - COMBOBOX cmb1, 80, 100, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP - CHECKBOX "Print to Fi&le", chx1, 20, 120, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Condensed", chx2, 160, 120, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP -} - - -PRINT_SETUP DIALOG 36, 24, 264, 134 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Print Setup" -FONT 8, "MS Shell Dlg" -{ - GROUPBOX "Printer", grp1, 6, 6, 180, 72, BS_GROUPBOX - RADIOBUTTON "&Default Printer", rad1, 16, 16, 150, 12 - LTEXT "[none]", stc1, 35, 30, 120, 9 - RADIOBUTTON "Specific &Printer", rad2, 16, 44, 150, 12 - COMBOBOX cmb1, 35, 58, 145, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "OK", IDOK, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Setup", psh1, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP - GROUPBOX "Orientation", grp2, 6, 82, 100, 50, BS_GROUPBOX - RADIOBUTTON "Po&rtrait", rad3, 50, 95, 50, 12 - RADIOBUTTON "&Landscape", rad4, 50, 110, 50, 12 - ICON "LANDSCAP", stc10, 10, 95, 32, 32 - ICON "PORTRAIT", stc11, 10, 95, 32, 32 - GROUPBOX "Paper", grp3, 116, 82, 178, 50, BS_GROUPBOX - LTEXT "Si&ze", stc2, 126, 95, 35, 9 - LTEXT "&Source", stc3, 126, 110, 35, 9 - COMBOBOX cmb2, 155, 95, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP - COMBOBOX cmb3, 155, 110, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP -} - - -CHOOSE_FONT DIALOG 13, 54, 274, 169 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Font" -FONT 8, "MS Shell Dlg" -{ - LTEXT "&Font:",stc1 ,6,3,90,9 - COMBOBOX cmb1, 6,13,94,76, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | - CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE - LTEXT "Font St&yle:",stc2 ,108,3,60,9 - COMBOBOX cmb2,108,13,64,76, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | - WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE - LTEXT "&Size:",stc3,179,3,32,9 - COMBOBOX cmb3,179,13,32,76, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | - WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE | CBS_SORT - DEFPUSHBUTTON "OK",IDOK,218,6,50,14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Cancel",IDCANCEL,218,23,50,14,WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Apply", psh3,218,40,50,14,WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Help" , pshHelp,218,57,50,14,WS_GROUP | WS_TABSTOP - GROUPBOX "Effects",grp1,6,92,84,36,WS_GROUP - CHECKBOX "Stri&keout", chx1, 10,102,78,10, BS_AUTOCHECKBOX | WS_TABSTOP - CHECKBOX "&Underline", chx2, 10,114,78,10, BS_AUTOCHECKBOX - LTEXT "&Color:", stc4 ,6,134,80,9 - COMBOBOX cmb4,6,144,84,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | - CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Sample",grp2,98,92,120,36,WS_GROUP - CTEXT "",stc5,103,101,109,24,SS_NOPREFIX | NOT WS_VISIBLE - LTEXT "Scr&ipt:",stc7 ,98,134,40,9 - COMBOBOX cmb5,98,144,120,90,CBS_DROPDOWNLIST | CBS_HASSTRINGS | - CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP -} - - -CHOOSE_COLOR DIALOG 36, 24, 300, 185 -STYLE WS_BORDER| DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Color" -FONT 8, "MS Shell Dlg" -{ - LTEXT "&Basic Colors:", stc1, 4, 4, 140, 10 - LTEXT "&Custom Colors:", stc2, 4, 106, 140, 10 - RTEXT "Color", COLOR_SOLID_LEFT, 150, 151, 20, 10 - LTEXT "|S&olid", COLOR_SOLID_RIGHT, 170, 151, 20, 10 - LTEXT "&Red:", COLOR_REDACCEL, 247,126,27,10 - EDITTEXT COLOR_RED, 275,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "&Green:", COLOR_GREENACCEL, 247,140,27,10 - EDITTEXT COLOR_GREEN, 275,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "&Blue:", COLOR_BLUEACCEL, 247,154,27,10 - EDITTEXT COLOR_BLUE, 275,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "&Hue:" , COLOR_HUEACCEL, 200,126,24,10 - EDITTEXT COLOR_HUE, 224,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "#msgctxt#Saturation#&Sat:", COLOR_SATACCEL, 200,140,24,10 - EDITTEXT COLOR_SAT, 224,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "#msgctxt#Luminance#&Lum:", COLOR_LUMACCEL, 200,154,24,10 - EDITTEXT COLOR_LUM, 224,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - CONTROL "" , COLOR_BOX1, "STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,14,140,86 - CONTROL "" , COLOR_CUSTOM1, "STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,116,140,28 - CONTROL "" , COLOR_RAINBOW, "STATIC",WS_BORDER|SS_SUNKEN|SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,4,118,116 - CONTROL "" , COLOR_LUMSCROLL, "STATIC",SS_SUNKEN|SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116 - CONTROL "" , COLOR_CURRENT, "STATIC",SS_SUNKEN|SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,124,40,26 - DEFPUSHBUTTON "OK", IDOK, 4, 167, 50, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL, 58, 167, 50, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Help", pshHelp,100,166, 44, 14 - PUSHBUTTON "&Add to Custom Colors", COLOR_ADD, 152, 167, 144, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Define Custom Colors >>", COLOR_MIX, 4, 149, 142, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "#msgctxt#Solid#&o", COLOR_SOLID, 300,200,4,14, WS_GROUP -} - - -FINDDLGORD DIALOG 36, 24, 276, 62 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Find" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Fi&nd What:", -1, 4, 8, 52, 8 - EDITTEXT edt1, 57, 7, 148, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP - CHECKBOX "Match &Whole Word Only", chx1, 4, 26, 140, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Match &Case", chx2, 4, 42, 140, 12, BS_AUTOCHECKBOX | WS_TABSTOP - GROUPBOX "Direction", grp1, 147, 21, 58, 38 - CONTROL "&Up", rad1, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 151, 30, 48, 12 - CONTROL "&Down", rad2, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 151, 44, 48, 12 - - DEFPUSHBUTTON "&Find Next", IDOK, 212, 6, 60, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Cancel", IDCANCEL , 212, 24, 60, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Help", pshHelp , 212, 42, 60, 14, WS_GROUP | WS_TABSTOP -} - - -REPLACEDLGORD DIALOG 36, 24, 276, 94 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Replace" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Fi&nd What:", -1, 4, 8, 52, 8 - EDITTEXT edt1, 57, 7, 148, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "Re&place With:", -1, 4, 26, 52, 8 - EDITTEXT edt2, 57, 24, 148, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP - CHECKBOX "Match &Whole Word Only", chx1, 5, 46, 120, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Match &Case", chx2, 5, 62, 120, 12, BS_AUTOCHECKBOX | WS_TABSTOP - - DEFPUSHBUTTON "&Find Next", IDOK, 212, 6, 60, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "&Replace", psh1 , 212, 24, 60, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Replace &All", psh2 , 212, 42, 60, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL , 212, 60, 60, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Help", pshHelp , 212, 78, 60, 14, WS_GROUP | WS_TABSTOP -} - - -PRINT32 DIALOG 32, 32, 288, 186 -STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | - DS_CONTEXTHELP | DS_3DLOOK -CAPTION "Print" -FONT 8, "MS Shell Dlg" -{ - GROUPBOX "Printer", grp4, 8, 4, 272,84, WS_GROUP - COMBOBOX cmb4, 52, 18, 152,152,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Properties", psh2, 212, 17, 60,14, WS_GROUP - CONTROL "Print to fi&le", chx1, "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,185,36,90,16 - LTEXT "&Name:", stc6, 16, 20, 36,8 - LTEXT "Status:", stc8, 16, 36, 47,10, SS_NOPREFIX - LTEXT "", stc12, 65, 36, 120,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Type:", stc7, 16, 48, 47,10, SS_NOPREFIX - LTEXT "", stc11, 65, 48, 212,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Where:", stc10, 16, 60, 47,10, SS_NOPREFIX - LTEXT "", stc14, 65, 60, 212,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Comment:", stc9, 16, 72, 47,10, SS_NOPREFIX - LTEXT "", stc13, 65, 72, 212,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - - GROUPBOX "Print range", grp1, 8,92, 144,64, WS_GROUP - CONTROL "&All", rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,106,64,12 - CONTROL "Pa&ges", rad3,"Button",BS_AUTORADIOBUTTON,16,122,36,12 - CONTROL "&Selection", rad2,"Button",BS_AUTORADIOBUTTON,16,138,64,12 - EDITTEXT edt1, 73,122, 26,12, WS_GROUP | ES_NUMBER - EDITTEXT edt2, 120,122, 26,12, WS_GROUP | ES_NUMBER - RTEXT "&from:", stc2, 52,124, 20,8 - RTEXT "&to:", stc3, 99,124, 20,8 - - GROUPBOX "Copies", grp2, 160, 92, 120,64, WS_GROUP - LTEXT "Number of &copies:",stc5,168,105,68,8 - ICON "", ico3, 170,131, 76,24, WS_GROUP | SS_CENTERIMAGE - CONTROL "C&ollate", chx2,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,168,118,100,12 - EDITTEXT edt3, 240,103, 32,12, WS_GROUP | ES_NUMBER - - DEFPUSHBUTTON "OK", IDOK, 176,164, 50,14, WS_GROUP | BS_DEFPUSHBUTTON - PUSHBUTTON "Cancel", IDCANCEL, 230,164, 50,14, WS_GROUP - PUSHBUTTON "&Help", pshHelp, 50, 164, 50,14, WS_GROUP -} - -PRINT32_SETUP DIALOG 32, 32, 288, 178 -STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP | DS_3DLOOK -CAPTION "Print Setup" -FONT 8, "MS Shell Dlg" -BEGIN - GROUPBOX "Printer", grp4, 8, 4, 272,84, WS_GROUP - LTEXT "&Name:", stc6, 16, 20, 36,8 - COMBOBOX cmb1, 60, 18, 152,152,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Properties", psh2, 212, 17, 60,14, WS_GROUP - LTEXT "Status:", stc8, 16, 36, 47,10, SS_NOPREFIX - LTEXT "", stc12, 60, 36, 212,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Type:", stc7, 16, 48, 47,10, SS_NOPREFIX - LTEXT "", stc11, 60, 48, 212,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Where:", stc10, 16, 60, 47,10, SS_NOPREFIX - LTEXT "", stc14, 60, 60, 212,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Comment:", stc9, 16, 72, 47,10, SS_NOPREFIX - LTEXT "", stc13, 60, 72, 212,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - - GROUPBOX "Paper", grp2, 8, 92, 164,56, WS_GROUP - LTEXT "Si&ze:", stc2, 16,108, 36, 8 - COMBOBOX cmb2, 52,106, 112,112,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP - LTEXT "&Source:", stc3, 16,128, 36, 8 - COMBOBOX cmb3, 52,126, 112,112,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP - - GROUPBOX "Orientation", grp1, 180, 92, 100,56, WS_GROUP - ICON "", ico1, 195,112, 18,20, WS_GROUP - CONTROL "P&ortrait", rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP |WS_TABSTOP,224,106,52,12 - CONTROL "L&andscape", rad2,"Button",BS_AUTORADIOBUTTON,224,126,52,12 - - DEFPUSHBUTTON "OK",IDOK,176,156,50,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,230,156,50,14 - PUSHBUTTON "&Help",pshHelp,8,156,50,14, WS_TABSTOP -/* PUSHBUTTON "Network...", psh5, 65,156,50,14, WS_TABSTOP */ -END - -PAGESETUPDLGORD DIALOG 32, 32, 240, 240 -STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Setup Page" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "", rct1, "Static", SS_WHITERECT, 80, 8, 80, 80 - CONTROL "", rct2, "Static", SS_GRAYRECT, 160, 12, 4, 80 - CONTROL "", rct3, "Static", SS_GRAYRECT, 84, 88, 80, 4 - GROUPBOX "Paper", grp2, 8, 96, 224, 56, BS_GROUPBOX - LTEXT "&Size:", stc2, 16, 112, 36, 8 - COMBOBOX cmb2, 64, 110, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL - LTEXT "&Tray:", stc3, 16, 132, 36, 8 - COMBOBOX cmb3, 64, 130, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL - GROUPBOX "Orientation", grp1, 8, 156, 64, 56, BS_GROUPBOX - AUTORADIOBUTTON "&Portrait", rad1, 16, 170, 52, 12, BS_AUTORADIOBUTTON - AUTORADIOBUTTON "&Landscape", rad2, 16, 190, 52, 12, BS_AUTORADIOBUTTON - GROUPBOX "", grp4, 80, 156, 152, 56, BS_GROUPBOX - LTEXT "L&eft:", stc15, 88, 172, 30, 8 - EDITTEXT edt4, 119, 170, 36, 12, WS_TABSTOP|WS_GROUP|WS_BORDER - LTEXT "&Right:", stc16, 159, 172, 30, 8 - EDITTEXT edt6, 190, 170, 36, 12, WS_TABSTOP|WS_GROUP|WS_BORDER - LTEXT "T&op:", stc17, 88, 192, 30, 8 - EDITTEXT edt5, 119, 190, 36, 12, WS_TABSTOP|WS_GROUP|WS_BORDER - LTEXT "&Bottom:", stc18, 159, 192, 30, 8 - EDITTEXT edt7, 190, 190, 36, 12, WS_TABSTOP|WS_GROUP|WS_BORDER - DEFPUSHBUTTON "OK", IDOK, 70, 220, 50, 14, BS_PUSHBUTTON - PUSHBUTTON "Cancel", IDCANCEL, 126, 220, 50, 14 - PUSHBUTTON "P&rinter...", psh3, 182, 220, 50, 14 -END - -NEWFILEOPENORD DIALOG 0, 0, 280, 164 -STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN -CAPTION "Open" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Look &in:",IDC_LOOKINSTATIC,4,6,43,8, SS_NOTIFY - COMBOBOX IDC_LOOKIN,49,3,132,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - - LTEXT "" , IDC_TOOLBARSTATIC, 181, 2, 102, 17, NOT WS_GROUP | NOT WS_VISIBLE - LISTBOX IDC_SHELLSTATIC,4,20,272,85, LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | WS_HSCROLL | NOT WS_VISIBLE - - LTEXT "File &name:",IDC_FILENAMESTATIC,5,112,56,16, SS_NOTIFY - EDITTEXT IDC_FILENAME,63,110,150,12,ES_AUTOHSCROLL - CONTROL "", cmb13, "ComboBoxEx32", CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP, 63,110,150,150 - - LTEXT "Files of &type:",IDC_FILETYPESTATIC,5,130,56,16, SS_NOTIFY - COMBOBOX IDC_FILETYPE,63,128,150,53,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - CONTROL "Open as &read-only",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,63,148,150,10 - - DEFPUSHBUTTON "&Open", IDOK,222,110,54,14 - PUSHBUTTON "Cancel", IDCANCEL,222,128,54,14 - PUSHBUTTON "&Help", pshHelp,222,145,54,14 -} - -NEWFILEOPENV2ORD DIALOG 0, 0, 370, 237 -STYLE DS_MODALFRAME | WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN -CAPTION "Open" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Look &in:", IDC_LOOKINSTATIC, 28, 6, 43, 8, SS_NOTIFY - COMBOBOX IDC_LOOKIN, 64, 3, 150, 100, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - - LTEXT "" , IDC_TOOLBARSTATIC, 209, 2, 102, 17, NOT WS_GROUP | NOT WS_VISIBLE - CONTROL "", IDC_TOOLBARPLACES, "ToolbarWindow32", 0x800 | CCS_NORESIZE | CCS_TOP | CCS_NOPARENTALIGN | CCS_NODIVIDER, 4, 20, 56, 192 - LISTBOX IDC_SHELLSTATIC, 64, 20, 300, 155, LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | WS_HSCROLL | NOT WS_VISIBLE - - LTEXT "File &name:", IDC_FILENAMESTATIC, 65, 182, 56, 16, SS_NOTIFY - EDITTEXT IDC_FILENAME, 123, 180, 180, 12, ES_AUTOHSCROLL - CONTROL "", cmb13, "ComboBoxEx32", CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP, 123, 180, 180, 150 - - LTEXT "Files of &type:", IDC_FILETYPESTATIC, 65, 200, 56, 16, SS_NOTIFY - COMBOBOX IDC_FILETYPE, 123, 198, 180, 53, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - CONTROL "Open as &read-only", IDC_OPENREADONLY, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 123, 218, 150, 10 - - DEFPUSHBUTTON "&Open", IDOK, 310, 180, 54, 14 - PUSHBUTTON "Cancel", IDCANCEL, 310, 198, 54, 14 - PUSHBUTTON "&Help", pshHelp, 310, 215, 54, 14 -} - -NEWFILEOPENV3ORD DIALOG 0, 0, 440, 300 -STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN | - WS_THICKFRAME -CAPTION "Open" -FONT 8, "MS Shell Dlg" -{ - LTEXT "File name:", IDC_FILENAMESTATIC, 160, 240, 60, 9, SS_RIGHT | WS_CLIPSIBLINGS - EDITTEXT IDC_FILENAME, 226, 240, 100, 12, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS | ES_AUTOHSCROLL - - LTEXT "Files of type:", IDC_FILETYPESTATIC, 160, 256, 60, 9, SS_RIGHT | WS_CLIPSIBLINGS - COMBOBOX IDC_FILETYPE, 226, 256, 100, 60, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | - WS_CLIPSIBLINGS | CBS_HASSTRINGS | CBS_DROPDOWNLIST - - DEFPUSHBUTTON "&Open", IDOK, 350, 240, 32, 14, WS_GROUP | WS_CLIPSIBLINGS - - /* drop-down menu for open button */ - CONTROL "#msgctxt#do not translate#6", psh1, "Button", WS_CHILD | WS_CLIPSIBLINGS | WS_GROUP | WS_TABSTOP | - BS_CHECKBOX | BS_PUSHLIKE, 342, 240, 8, 14 - - PUSHBUTTON "Cancel", IDCANCEL, 395, 240, 40, 14, WS_CLIPSIBLINGS - PUSHBUTTON "&Help", pshHelp, 350, 272, 40, 14, WS_CLIPSIBLINGS -} - -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL - -#define WINE_FILEDESCRIPTION_STR "Common Dialog Boxes for One-Core-API" -#define WINE_FILENAME_STR "comdlg32.dll" - -#include "common_wrappers_ver.rc" - -/* Translators do not need to translate this text, unless the language uses a - * different character set or if the distribution of characters looks wrong. - * It is rendered illegibly small and is used to make a mock-up of a document. - */ -STRINGTABLE -{ - IDS_FAKEDOCTEXT - "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. \ - Nulla a tortor. Etiam aliquet libero venenatis nunc.\n\ -\n\ - Sed augue ante, fermentum sit amet, imperdiet et, gravida eu, enim. \ - Donec nibh quam, sodales in, commodo vel, facilisis id, neque.\n\ -\n\ - Nunc eleifend bibendum nibh. Phasellus in lorem. Ut vel odio quis \ - libero adipiscing consequat. Donec consectetuer laoreet mauris.\n\ -\n\ - Maecenas tempor, ligula sed congue nonummy, arcu dolor ornare erat, \ - egestas iaculis magna purus sed turpis.\n\ -\n\ - Morbi ultricies est non ipsum. Cum sociis natoque penatibus et magnis \ - dis parturient montes, nascetur ridiculus mus.\n\ -\n\ - Duis sit amet nibh quis purus sollicitudin blandit. Curabitur justo. \ - Phasellus varius, erat eu luctus pharetra, odio elit fringilla leo, \ - non vulputate turpis elit id neque. Vestibulum sit amet tellus sed \ - tortor fermentum consectetuer." -} - - -/* @makedep: pd32_collate.ico */ -PD32_COLLATE ICON pd32_collate.ico - -/* @makedep: pd32_nocollate.ico */ -PD32_NOCOLLATE ICON pd32_nocollate.ico - -/* @makedep: pd32_portrait.ico */ -PD32_PORTRAIT ICON pd32_portrait.ico - -/* @makedep: pd32_landscape.ico */ -PD32_LANDSCAPE ICON pd32_landscape.ico - -/* @makedep: folder.ico */ -FOLDER ICON folder.ico - -/* @makedep: folder2.ico */ -FOLDER2 ICON folder2.ico - -/* @makedep: floppy.ico */ -FLOPPY ICON floppy.ico - -/* @makedep: cdrom.ico */ -CDROM ICON cdrom.ico - -/* @makedep: hdisk.ico */ -HDISK ICON hdisk.ico - -/* @makedep: network.ico */ -NETWORK ICON network.ico - -/* @makedep: fontpics.bmp */ -38 BITMAP fontpics.bmp - -/* @makedep: comdlg32.manifest */ -123 RT_MANIFEST comdlg32.manifest diff --git a/wrappers/extensions/comdlgex/comdlgex.spec b/wrappers/extensions/comdlgex/comdlgex.spec deleted file mode 100644 index 14cea9eec4..0000000000 --- a/wrappers/extensions/comdlgex/comdlgex.spec +++ /dev/null @@ -1,26 +0,0 @@ -@ stdcall ChooseColorA(ptr) -@ stdcall ChooseColorW(ptr) -@ stdcall ChooseFontA(ptr) -@ stdcall ChooseFontW(ptr) -@ stdcall CommDlgExtendedError() -@ stdcall DllGetClassObject(ptr ptr ptr) -@ stdcall FindTextA(ptr) -@ stdcall FindTextW(ptr) -@ stdcall GetFileTitleA(str ptr long) -@ stdcall GetFileTitleW(wstr ptr long) -@ stdcall GetOpenFileNameA(ptr) -@ stdcall GetOpenFileNameW(ptr) -@ stdcall GetSaveFileNameA(ptr) -@ stdcall GetSaveFileNameW(ptr) -@ stdcall LoadAlterBitmap(long long long) -@ stdcall PageSetupDlgA(ptr) -@ stdcall PageSetupDlgW(ptr) -@ stdcall PrintDlgA(ptr) -@ stdcall PrintDlgExA(ptr) -@ stdcall PrintDlgExW(ptr) -@ stdcall PrintDlgW(ptr) -@ stdcall ReplaceTextA(ptr) -@ stdcall ReplaceTextW(ptr) -@ stdcall WantArrows(long long ptr ptr) -@ stdcall dwLBSubclass(long long ptr ptr) -@ stdcall dwOKSubclass(long long ptr ptr) \ No newline at end of file diff --git a/wrappers/extensions/comdlgex/filedlg.c b/wrappers/extensions/comdlgex/filedlg.c deleted file mode 100644 index 985f094ae1..0000000000 --- a/wrappers/extensions/comdlgex/filedlg.c +++ /dev/null @@ -1,4356 +0,0 @@ -/* - * COMMDLG - File Open Dialogs Win95 look and feel - * - * Copyright 1999 Francois Boisvert - * Copyright 1999, 2000 Juergen Schmied - * - * 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 - * - * FIXME: The whole concept of handling unicode is badly broken. - * many hook-messages expect a pointer to a - * OPENFILENAMEA or W structure. With the current architecture - * we would have to convert the beast at every call to a hook. - * we have to find a better solution but it would likely cause - * a complete rewrite after which we should handle the - * OPENFILENAME structure without any converting (jsch). - * - * FIXME: any hook gets a OPENFILENAMEA structure - * - * FIXME: CDN_FILEOK is wrong implemented, other CDN_ messages likely too - * - * FIXME: old style hook messages are not implemented (except FILEOKSTRING) - * - * FIXME: algorithm for selecting the initial directory is too simple - * - * FIXME: add to recent docs - * - * FIXME: flags not implemented: OFN_DONTADDTORECENT, - * OFN_NODEREFERENCELINKS, OFN_NOREADONLYRETURN, - * OFN_NOTESTFILECREATE, OFN_USEMONIKERS - * - * FIXME: lCustData for lpfnHook (WM_INITDIALOG) - * - * - */ - -#include -#include -#include -#include -#include - -#define COBJMACROS -#define NONAMELESSUNION - -#include "windef.h" -#include "winbase.h" -#include "wine/winternl.h" -#include "winnls.h" -#include "wingdi.h" -#include "winreg.h" -#include "winuser.h" -#include "commdlg.h" -#include "dlgs.h" -#include "cdlg.h" -#include "cderr.h" -#include "shellapi.h" -#include "shlobj.h" -#include "filedlgbrowser.h" -#include "shlwapi.h" - -#include "wine/debug.h" -#include "wine/heap.h" - -#include "main.h" - -WINE_DEFAULT_DEBUG_CHANNEL(commdlg); - -#define UNIMPLEMENTED_FLAGS \ -(OFN_DONTADDTORECENT |\ -OFN_NODEREFERENCELINKS | OFN_NOREADONLYRETURN |\ -OFN_NOTESTFILECREATE /*| OFN_USEMONIKERS*/) - -/*********************************************************************** - * Data structure and global variables - */ -typedef struct SFolder -{ - int m_iImageIndex; /* Index of picture in image list */ - HIMAGELIST hImgList; - int m_iIndent; /* Indentation index */ - LPITEMIDLIST pidlItem; /* absolute pidl of the item */ - -} SFOLDER,*LPSFOLDER; - -typedef struct tagLookInInfo -{ - int iMaxIndentation; - UINT uSelectedItem; -} LookInInfos; - - -/*********************************************************************** - * Defines and global variables - */ - -/* Draw item constant */ -#define XTEXTOFFSET 3 - -/* AddItem flags*/ -#define LISTEND -1 - -/* SearchItem methods */ -#define SEARCH_PIDL 1 -#define SEARCH_EXP 2 -#define ITEM_NOTFOUND -1 - -/* Undefined windows message sent by CreateViewObject*/ -#define WM_GETISHELLBROWSER WM_USER+7 - -#define TBPLACES_CMDID_PLACE0 0xa064 -#define TBPLACES_CMDID_PLACE1 0xa065 -#define TBPLACES_CMDID_PLACE2 0xa066 -#define TBPLACES_CMDID_PLACE3 0xa067 -#define TBPLACES_CMDID_PLACE4 0xa068 - -/* NOTE - * Those macros exist in windowsx.h. However, you can't really use them since - * they rely on the UNICODE defines and can't be used inside Wine itself. - */ - -/* Combo box macros */ -#define CBGetItemDataPtr(hwnd,iItemId) \ - SendMessageW(hwnd, CB_GETITEMDATA, (WPARAM)(iItemId), 0) - -static const char LookInInfosStr[] = "LookInInfos"; /* LOOKIN combo box property */ -static SIZE MemDialogSize = { 0, 0}; /* keep size of the (resizable) dialog */ - -FileOpenDlgInfos *get_filedlg_infoptr(HWND hwnd) -{ - return GetPropW(hwnd, L"FileOpenDlgInfos"); -} - -static BOOL is_dialog_hooked(const FileOpenDlgInfos *info) -{ - return (info->ofnInfos->Flags & OFN_ENABLEHOOK) && info->ofnInfos->lpfnHook; -} - -static BOOL filedialog_is_readonly_hidden(const FileOpenDlgInfos *info) -{ - return (info->ofnInfos->Flags & OFN_HIDEREADONLY) || (info->DlgInfos.dwDlgProp & FODPROP_SAVEDLG); -} - -/*********************************************************************** - * Prototypes - */ - -/* Internal functions used by the dialog */ -static LRESULT FILEDLG95_ResizeControls(HWND hwnd, WPARAM wParam, LPARAM lParam); -static LRESULT FILEDLG95_FillControls(HWND hwnd, WPARAM wParam, LPARAM lParam); -static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam); -static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd); -static BOOL FILEDLG95_OnOpen(HWND hwnd); -static LRESULT FILEDLG95_InitControls(HWND hwnd); -static void FILEDLG95_Clean(HWND hwnd); - -/* Functions used by the shell navigation */ -static LRESULT FILEDLG95_SHELL_Init(HWND hwnd); -static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd); -static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb); -static void FILEDLG95_SHELL_Clean(HWND hwnd); - -/* Functions used by the EDIT box */ -static int FILEDLG95_FILENAME_GetFileNames (HWND hwnd, LPWSTR * lpstrFileList, UINT * sizeUsed); - -/* Functions used by the filetype combo box */ -static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd); -static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode); -static int FILEDLG95_FILETYPE_SearchExt(HWND hwnd,LPCWSTR lpstrExt); -static void FILEDLG95_FILETYPE_Clean(HWND hwnd); - -/* Functions used by the Look In combo box */ -static void FILEDLG95_LOOKIN_Init(HWND hwndCombo); -static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct); -static BOOL FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode); -static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId); -static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMethod); -static int FILEDLG95_LOOKIN_InsertItemAfterParent(HWND hwnd,LPITEMIDLIST pidl); -static int FILEDLG95_LOOKIN_RemoveMostExpandedItem(HWND hwnd); - int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl); -static void FILEDLG95_LOOKIN_Clean(HWND hwnd); - -/* Functions for dealing with the most-recently-used registry keys */ -static void FILEDLG95_MRU_load_filename(LPWSTR stored_path); -static WCHAR FILEDLG95_MRU_get_slot(LPCWSTR module_name, LPWSTR stored_path, PHKEY hkey_ret); -static void FILEDLG95_MRU_save_filename(LPCWSTR filename); - -/* Miscellaneous tool functions */ -static HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPWSTR lpstrFileName); -IShellFolder* GetShellFolderFromPidl(LPITEMIDLIST pidlAbs); -LPITEMIDLIST GetParentPidl(LPITEMIDLIST pidl); -static LPITEMIDLIST GetPidlFromName(IShellFolder *psf,LPWSTR lpcstrFileName); -static BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl); -static UINT GetNumSelected( IDataObject *doSelected ); -static void COMCTL32_ReleaseStgMedium(STGMEDIUM medium); - -static INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -static INT_PTR FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -static BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCount, UINT sizeUsed); -static BOOL BrowseSelectedFolder(HWND hwnd); - -static BOOL get_config_key_as_dword(HKEY hkey, const WCHAR *name, DWORD *value) -{ - DWORD type, data, size; - - size = sizeof(data); - if (hkey && !RegQueryValueExW(hkey, name, 0, &type, (BYTE *)&data, &size)) - { - *value = data; - return TRUE; - } - - return FALSE; -} - -static BOOL get_config_key_dword(HKEY hkey, const WCHAR *name, DWORD *value) -{ - DWORD type, data, size; - - size = sizeof(data); - if (hkey && !RegQueryValueExW(hkey, name, 0, &type, (BYTE *)&data, &size) && type == REG_DWORD) - { - *value = data; - return TRUE; - } - - return FALSE; -} - -static BOOL get_config_key_string(HKEY hkey, const WCHAR *name, WCHAR **value) -{ - DWORD type, size; - WCHAR *str; - - if (RegQueryValueExW(hkey, name, 0, &type, NULL, &size)) - return FALSE; - if (type != REG_SZ && type != REG_EXPAND_SZ) - return FALSE; - - str = heap_alloc(size); - if (RegQueryValueExW(hkey, name, 0, &type, (BYTE *)str, &size)) - { - heap_free(str); - return FALSE; - } - - *value = str; - return TRUE; -} - -static BOOL is_places_bar_enabled(const FileOpenDlgInfos *fodInfos) -{ - DWORD value; - HKEY hkey; - - if (fodInfos->ofnInfos->lStructSize != sizeof(*fodInfos->ofnInfos) || - (fodInfos->ofnInfos->FlagsEx & OFN_EX_NOPLACESBAR) || - !(fodInfos->ofnInfos->Flags & OFN_EXPLORER)) - { - return FALSE; - } - - if (RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Comdlg32", &hkey)) - return TRUE; - - value = 0; - get_config_key_as_dword(hkey, L"NoPlacesBar", &value); - RegCloseKey(hkey); - return value == 0; -} - -static void filedlg_collect_places_pidls(FileOpenDlgInfos *fodInfos) -{ - static const int default_places[] = - { - CSIDL_DESKTOP, - CSIDL_MYDOCUMENTS, - CSIDL_DRIVES, - }; - unsigned int i; - HKEY hkey; - - if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Comdlg32\\Placesbar", - &hkey)) - { - for (i = 0; i < ARRAY_SIZE(fodInfos->places); i++) - { - WCHAR nameW[8]; - DWORD value; - HRESULT hr; - WCHAR *str; - - swprintf(nameW, L"Place%d", i); - if (get_config_key_dword(hkey, nameW, &value)) - { - hr = SHGetSpecialFolderLocation(NULL, value, &fodInfos->places[i]); - if (FAILED(hr)) - WARN("Unrecognized special folder %lu.\n", value); - } - else if (get_config_key_string(hkey, nameW, &str)) - { - hr = SHParseDisplayName(str, NULL, &fodInfos->places[i], 0, NULL); - if (FAILED(hr)) - WARN("Failed to parse custom places location, %s.\n", debugstr_w(str)); - heap_free(str); - } - } - - /* FIXME: eliminate duplicates. */ - - RegCloseKey(hkey); - return; - } - - for (i = 0; i < ARRAY_SIZE(default_places); i++) - SHGetSpecialFolderLocation(NULL, default_places[i], &fodInfos->places[i]); -} - -/*********************************************************************** - * GetFileName95 - * - * Creates an Open common dialog box that lets the user select - * the drive, directory, and the name of a file or set of files to open. - * - * IN : The FileOpenDlgInfos structure associated with the dialog - * OUT : TRUE on success - * FALSE on cancel, error, close or filename-does-not-fit-in-buffer. - */ -static BOOL GetFileName95(FileOpenDlgInfos *fodInfos) -{ - LRESULT lRes; - void *template; - HRSRC hRes; - HANDLE hDlgTmpl = 0; - WORD templateid; - - /* test for missing functionality */ - if (fodInfos->ofnInfos->Flags & UNIMPLEMENTED_FLAGS) - { - FIXME("Flags 0x%08lx not yet implemented\n", - fodInfos->ofnInfos->Flags & UNIMPLEMENTED_FLAGS); - } - - /* Create the dialog from a template */ - - if (is_places_bar_enabled(fodInfos)) - templateid = NEWFILEOPENV2ORD; - else - templateid = NEWFILEOPENORD; - - if (!(hRes = FindResourceW(COMDLG32_hInstance, MAKEINTRESOURCEW(templateid), (LPCWSTR)RT_DIALOG))) - { - COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); - return FALSE; - } - if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hRes )) || - !(template = LockResource( hDlgTmpl ))) - { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return FALSE; - } - - /* msdn: explorer style dialogs permit sizing by default. - * The OFN_ENABLESIZING flag is only needed when a hook or - * custom template is provided */ - if( (fodInfos->ofnInfos->Flags & OFN_EXPLORER) && - !(fodInfos->ofnInfos->Flags & ( OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE))) - fodInfos->ofnInfos->Flags |= OFN_ENABLESIZING; - - if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING) - { - fodInfos->sizedlg.cx = fodInfos->sizedlg.cy = 0; - fodInfos->initial_size.x = fodInfos->initial_size.y = 0; - } - - /* old style hook messages */ - if (is_dialog_hooked(fodInfos)) - { - fodInfos->HookMsg.fileokstring = RegisterWindowMessageW(FILEOKSTRINGW); - fodInfos->HookMsg.lbselchstring = RegisterWindowMessageW(LBSELCHSTRINGW); - fodInfos->HookMsg.helpmsgstring = RegisterWindowMessageW(HELPMSGSTRINGW); - fodInfos->HookMsg.sharevistring = RegisterWindowMessageW(SHAREVISTRINGW); - } - - if (fodInfos->unicode) - lRes = DialogBoxIndirectParamW(COMDLG32_hInstance, - template, - fodInfos->ofnInfos->hwndOwner, - FileOpenDlgProc95, - (LPARAM) fodInfos); - else - lRes = DialogBoxIndirectParamA(COMDLG32_hInstance, - template, - fodInfos->ofnInfos->hwndOwner, - FileOpenDlgProc95, - (LPARAM) fodInfos); - if (fodInfos->ole_initialized) - OleUninitialize(); - - /* Unable to create the dialog */ - if( lRes == -1) - return FALSE; - - return lRes; -} - -static WCHAR *heap_strdupAtoW(const char *str) -{ - WCHAR *ret; - INT len; - - if (!str) - return NULL; - - len = MultiByteToWideChar(CP_ACP, 0, str, -1, 0, 0); - ret = heap_alloc(len * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); - - return ret; -} - -static void init_filedlg_infoW(OPENFILENAMEW *ofn, FileOpenDlgInfos *info) -{ - INITCOMMONCONTROLSEX icc; - - /* Initialize ComboBoxEx32 */ - icc.dwSize = sizeof(icc); - icc.dwICC = ICC_USEREX_CLASSES; - InitCommonControlsEx(&icc); - - /* Initialize CommDlgExtendedError() */ - COMDLG32_SetCommDlgExtendedError(0); - - memset(info, 0, sizeof(*info)); - - /* Pass in the original ofn */ - info->ofnInfos = ofn; - - info->title = ofn->lpstrTitle; - info->defext = ofn->lpstrDefExt; - info->filter = ofn->lpstrFilter; - info->customfilter = ofn->lpstrCustomFilter; - - if (ofn->lpstrFile) - { - info->filename = heap_alloc(ofn->nMaxFile * sizeof(WCHAR)); - lstrcpynW(info->filename, ofn->lpstrFile, ofn->nMaxFile); - } - - if (ofn->lpstrInitialDir) - { - DWORD len = ExpandEnvironmentStringsW(ofn->lpstrInitialDir, NULL, 0); - if (len) - { - info->initdir = heap_alloc(len * sizeof(WCHAR)); - ExpandEnvironmentStringsW(ofn->lpstrInitialDir, info->initdir, len); - } - } - - info->unicode = TRUE; -} - -static void init_filedlg_infoA(OPENFILENAMEA *ofn, FileOpenDlgInfos *info) -{ - OPENFILENAMEW ofnW; - int len; - - ofnW = *(OPENFILENAMEW *)ofn; - - ofnW.lpstrInitialDir = heap_strdupAtoW(ofn->lpstrInitialDir); - ofnW.lpstrDefExt = heap_strdupAtoW(ofn->lpstrDefExt); - ofnW.lpstrTitle = heap_strdupAtoW(ofn->lpstrTitle); - - if (ofn->lpstrFile) - { - len = MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFile, ofn->nMaxFile, NULL, 0); - ofnW.lpstrFile = heap_alloc(len * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFile, ofn->nMaxFile, ofnW.lpstrFile, len); - ofnW.nMaxFile = len; - } - - if (ofn->lpstrFilter) - { - LPCSTR s; - int n; - - /* filter is a list... title\0ext\0......\0\0 */ - s = ofn->lpstrFilter; - while (*s) s = s+strlen(s)+1; - s++; - n = s - ofn->lpstrFilter; - len = MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFilter, n, NULL, 0); - ofnW.lpstrFilter = heap_alloc(len * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFilter, n, (WCHAR *)ofnW.lpstrFilter, len); - } - - /* convert lpstrCustomFilter */ - if (ofn->lpstrCustomFilter) - { - int n, len; - LPCSTR s; - - /* customfilter contains a pair of strings... title\0ext\0 */ - s = ofn->lpstrCustomFilter; - if (*s) s = s+strlen(s)+1; - if (*s) s = s+strlen(s)+1; - n = s - ofn->lpstrCustomFilter; - len = MultiByteToWideChar(CP_ACP, 0, ofn->lpstrCustomFilter, n, NULL, 0); - ofnW.lpstrCustomFilter = heap_alloc(len * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, ofn->lpstrCustomFilter, n, ofnW.lpstrCustomFilter, len); - } - - init_filedlg_infoW(&ofnW, info); - - /* fixup A-specific fields */ - info->ofnInfos = (OPENFILENAMEW *)ofn; - info->unicode = FALSE; - - /* free what was duplicated */ - heap_free((void *)ofnW.lpstrInitialDir); - heap_free(ofnW.lpstrFile); -} - -/*********************************************************************** - * GetFileDialog95 - * - * Call GetFileName95 with this structure and clean the memory. - */ -static BOOL GetFileDialog95(FileOpenDlgInfos *info, UINT dlg_type) -{ - WCHAR *current_dir = NULL; - unsigned int i; - BOOL ret; - - /* save current directory */ - if (info->ofnInfos->Flags & OFN_NOCHANGEDIR) - { - current_dir = heap_alloc(MAX_PATH * sizeof(WCHAR)); - GetCurrentDirectoryW(MAX_PATH, current_dir); - } - - switch (dlg_type) - { - case OPEN_DIALOG: - ret = GetFileName95(info); - break; - case SAVE_DIALOG: - info->DlgInfos.dwDlgProp |= FODPROP_SAVEDLG; - ret = GetFileName95(info); - break; - default: - ret = FALSE; - } - - if (current_dir) - { - SetCurrentDirectoryW(current_dir); - heap_free(current_dir); - } - - if (!info->unicode) - { - heap_free((void *)info->defext); - heap_free((void *)info->title); - heap_free((void *)info->filter); - heap_free((void *)info->customfilter); - } - - heap_free(info->filename); - heap_free(info->initdir); - - for (i = 0; i < ARRAY_SIZE(info->places); i++) - ILFree(info->places[i]); - - return ret; -} - -/****************************************************************************** - * COMDLG32_GetDisplayNameOf [internal] - * - * Helper function to get the display name for a pidl. - */ -static BOOL COMDLG32_GetDisplayNameOf(LPCITEMIDLIST pidl, LPWSTR pwszPath) { - LPSHELLFOLDER psfDesktop; - STRRET strret; - - if (FAILED(SHGetDesktopFolder(&psfDesktop))) - return FALSE; - - if (FAILED(IShellFolder_GetDisplayNameOf(psfDesktop, pidl, SHGDN_FORPARSING, &strret))) { - IShellFolder_Release(psfDesktop); - return FALSE; - } - - IShellFolder_Release(psfDesktop); - return SUCCEEDED(StrRetToBufW(&strret, pidl, pwszPath, MAX_PATH)); -} - -/****************************************************************************** - * COMDLG32_GetCanonicalPath [internal] - * - * Helper function to get the canonical path. - */ -void COMDLG32_GetCanonicalPath(PCIDLIST_ABSOLUTE pidlAbsCurrent, - LPWSTR lpstrFile, LPWSTR lpstrPathAndFile) -{ - WCHAR lpstrTemp[MAX_PATH]; - - /* Get the current directory name */ - if (!COMDLG32_GetDisplayNameOf(pidlAbsCurrent, lpstrPathAndFile)) - { - /* last fallback */ - GetCurrentDirectoryW(MAX_PATH, lpstrPathAndFile); - } - PathAddBackslashW(lpstrPathAndFile); - - TRACE("current directory=%s, file=%s\n", debugstr_w(lpstrPathAndFile), debugstr_w(lpstrFile)); - - /* if the user specified a fully qualified path use it */ - if(PathIsRelativeW(lpstrFile)) - { - lstrcatW(lpstrPathAndFile, lpstrFile); - } - else - { - /* does the path have a drive letter? */ - if (PathGetDriveNumberW(lpstrFile) == -1) - lstrcpyW(lpstrPathAndFile+2, lpstrFile); - else - lstrcpyW(lpstrPathAndFile, lpstrFile); - } - - /* resolve "." and ".." */ - PathCanonicalizeW(lpstrTemp, lpstrPathAndFile ); - lstrcpyW(lpstrPathAndFile, lpstrTemp); - TRACE("canon=%s\n", debugstr_w(lpstrPathAndFile)); -} - -/*********************************************************************** - * COMDLG32_SplitFileNames [internal] - * - * Creates a delimited list of filenames. - */ -int COMDLG32_SplitFileNames(LPWSTR lpstrEdit, UINT nStrLen, LPWSTR *lpstrFileList, UINT *sizeUsed) -{ - UINT nStrCharCount = 0; /* index in src buffer */ - UINT nFileIndex = 0; /* index in dest buffer */ - UINT nFileCount = 0; /* number of files */ - - /* we might get single filename without any '"', - * so we need nStrLen + terminating \0 + end-of-list \0 */ - *lpstrFileList = heap_alloc((nStrLen + 2) * sizeof(WCHAR)); - *sizeUsed = 0; - - /* build delimited file list from filenames */ - while ( nStrCharCount <= nStrLen ) - { - if ( lpstrEdit[nStrCharCount]=='"' ) - { - nStrCharCount++; - while ((nStrCharCount <= nStrLen) && (lpstrEdit[nStrCharCount]!='"')) - { - (*lpstrFileList)[nFileIndex++] = lpstrEdit[nStrCharCount]; - nStrCharCount++; - } - (*lpstrFileList)[nFileIndex++] = 0; - nFileCount++; - } - nStrCharCount++; - } - - /* single, unquoted string */ - if ((nStrLen > 0) && (nFileIndex == 0) ) - { - lstrcpyW(*lpstrFileList, lpstrEdit); - nFileIndex = lstrlenW(lpstrEdit) + 1; - nFileCount = 1; - } - - /* trailing \0 */ - (*lpstrFileList)[nFileIndex++] = '\0'; - - *sizeUsed = nFileIndex; - return nFileCount; -} - -/*********************************************************************** - * ArrangeCtrlPositions [internal] - * - * NOTE: Make sure to add testcases for any changes made here. - */ -static void ArrangeCtrlPositions(HWND hwndChildDlg, HWND hwndParentDlg, BOOL hide_help) -{ - HWND hwndChild, hwndStc32; - RECT rectParent, rectChild, rectStc32; - INT help_fixup = 0; - int chgx, chgy; - - /* Take into account if open as read only checkbox and help button - * are hidden - */ - if (hide_help) - { - RECT rectHelp, rectCancel; - GetWindowRect(GetDlgItem(hwndParentDlg, pshHelp), &rectHelp); - GetWindowRect(GetDlgItem(hwndParentDlg, IDCANCEL), &rectCancel); - /* subtract the height of the help button plus the space between - * the help button and the cancel button to the height of the dialog - */ - help_fixup = rectHelp.bottom - rectCancel.bottom; - } - - /* - There are two possibilities to add components to the default file dialog box. - - By default, all the new components are added below the standard dialog box (the else case). - - However, if there is a static text component with the stc32 id, a special case happens. - The x and y coordinates of stc32 indicate the top left corner where to place the standard file dialog box - in the window and the cx and cy indicate how to size the window. - Moreover, if the new component's coordinates are on the left of the stc32 , it is placed on the left - of the standard file dialog box. If they are above the stc32 component, it is placed above and so on.... - - */ - - GetClientRect(hwndParentDlg, &rectParent); - - /* when arranging controls we have to use fixed parent size */ - rectParent.bottom -= help_fixup; - - hwndStc32 = GetDlgItem(hwndChildDlg, stc32); - if (hwndStc32) - { - GetWindowRect(hwndStc32, &rectStc32); - MapWindowPoints(0, hwndChildDlg, (LPPOINT)&rectStc32, 2); - - /* set the size of the stc32 control according to the size of - * client area of the parent dialog - */ - SetWindowPos(hwndStc32, 0, - 0, 0, - rectParent.right, rectParent.bottom, - SWP_NOMOVE | SWP_NOZORDER); - } - else - SetRectEmpty(&rectStc32); - - /* this part moves controls of the child dialog */ - hwndChild = GetWindow(hwndChildDlg, GW_CHILD); - while (hwndChild) - { - if (hwndChild != hwndStc32) - { - GetWindowRect(hwndChild, &rectChild); - MapWindowPoints(0, hwndChildDlg, (LPPOINT)&rectChild, 2); - - /* move only if stc32 exist */ - if (hwndStc32 && rectChild.left > rectStc32.right) - { - /* move to the right of visible controls of the parent dialog */ - rectChild.left += rectParent.right; - rectChild.left -= rectStc32.right; - } - /* move even if stc32 doesn't exist */ - if (rectChild.top >= rectStc32.bottom) - { - /* move below visible controls of the parent dialog */ - rectChild.top += rectParent.bottom; - rectChild.top -= rectStc32.bottom - rectStc32.top; - } - - SetWindowPos(hwndChild, 0, rectChild.left, rectChild.top, - 0, 0, SWP_NOSIZE | SWP_NOZORDER); - } - hwndChild = GetWindow(hwndChild, GW_HWNDNEXT); - } - - /* this part moves controls of the parent dialog */ - hwndChild = GetWindow(hwndParentDlg, GW_CHILD); - while (hwndChild) - { - if (hwndChild != hwndChildDlg) - { - GetWindowRect(hwndChild, &rectChild); - MapWindowPoints(0, hwndParentDlg, (LPPOINT)&rectChild, 2); - - /* left,top of stc32 marks the position of controls - * from the parent dialog - */ - rectChild.left += rectStc32.left; - rectChild.top += rectStc32.top; - - SetWindowPos(hwndChild, 0, rectChild.left, rectChild.top, - 0, 0, SWP_NOSIZE | SWP_NOZORDER); - } - hwndChild = GetWindow(hwndChild, GW_HWNDNEXT); - } - - /* calculate the size of the resulting dialog */ - - /* here we have to use original parent size */ - GetClientRect(hwndParentDlg, &rectParent); - GetClientRect(hwndChildDlg, &rectChild); - TRACE( "parent %s child %s stc32 %s\n", wine_dbgstr_rect( &rectParent), - wine_dbgstr_rect( &rectChild), wine_dbgstr_rect( &rectStc32)); - - if (hwndStc32) - { - /* width */ - if (rectParent.right > rectStc32.right - rectStc32.left) - chgx = rectChild.right - ( rectStc32.right - rectStc32.left); - else - chgx = rectChild.right - rectParent.right; - /* height */ - if (rectParent.bottom > rectStc32.bottom - rectStc32.top) - chgy = rectChild.bottom - ( rectStc32.bottom - rectStc32.top) - help_fixup; - else - /* Unconditionally set new dialog - * height to that of the child - */ - chgy = rectChild.bottom - rectParent.bottom; - } - else - { - chgx = 0; - chgy = rectChild.bottom - help_fixup; - } - /* set the size of the parent dialog */ - GetWindowRect(hwndParentDlg, &rectParent); - SetWindowPos(hwndParentDlg, 0, - 0, 0, - rectParent.right - rectParent.left + chgx, - rectParent.bottom - rectParent.top + chgy, - SWP_NOMOVE | SWP_NOZORDER); -} - -static INT_PTR CALLBACK FileOpenDlgProcUserTemplate(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch(uMsg) { - case WM_INITDIALOG: - return TRUE; - } - return FALSE; -} - -static HWND CreateTemplateDialog(FileOpenDlgInfos *fodInfos, HWND hwnd) -{ - LPCVOID template; - HRSRC hRes; - HANDLE hDlgTmpl = 0; - HWND hChildDlg = 0; - - TRACE("%p, %p\n", fodInfos, hwnd); - - /* - * If OFN_ENABLETEMPLATEHANDLE is specified, the OPENFILENAME - * structure's hInstance parameter is not a HINSTANCE, but - * instead a pointer to a template resource to use. - */ - if (fodInfos->ofnInfos->Flags & (OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE)) - { - HINSTANCE hinst; - if (fodInfos->ofnInfos->Flags & OFN_ENABLETEMPLATEHANDLE) - { - hinst = COMDLG32_hInstance; - if( !(template = LockResource( fodInfos->ofnInfos->hInstance))) - { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return NULL; - } - } - else - { - hinst = fodInfos->ofnInfos->hInstance; - if(fodInfos->unicode) - { - LPOPENFILENAMEW ofn = fodInfos->ofnInfos; - hRes = FindResourceW( hinst, ofn->lpTemplateName, (LPWSTR)RT_DIALOG); - } - else - { - LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)fodInfos->ofnInfos; - hRes = FindResourceA( hinst, ofn->lpTemplateName, (LPSTR)RT_DIALOG); - } - if (!hRes) - { - COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); - return NULL; - } - if (!(hDlgTmpl = LoadResource( hinst, hRes )) || - !(template = LockResource( hDlgTmpl ))) - { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return NULL; - } - } - if (fodInfos->unicode) - hChildDlg = CreateDialogIndirectParamW(hinst, template, hwnd, - is_dialog_hooked(fodInfos) ? (DLGPROC)fodInfos->ofnInfos->lpfnHook : FileOpenDlgProcUserTemplate, - (LPARAM)fodInfos->ofnInfos); - else - hChildDlg = CreateDialogIndirectParamA(hinst, template, hwnd, - is_dialog_hooked(fodInfos) ? (DLGPROC)fodInfos->ofnInfos->lpfnHook : FileOpenDlgProcUserTemplate, - (LPARAM)fodInfos->ofnInfos); - return hChildDlg; - } - else if (is_dialog_hooked(fodInfos)) - { - RECT rectHwnd; - struct { - DLGTEMPLATE tmplate; - WORD menu,class,title; - } temp; - GetClientRect(hwnd,&rectHwnd); - temp.tmplate.style = WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | DS_CONTROL | DS_3DLOOK; - temp.tmplate.dwExtendedStyle = 0; - temp.tmplate.cdit = 0; - temp.tmplate.x = 0; - temp.tmplate.y = 0; - temp.tmplate.cx = 0; - temp.tmplate.cy = 0; - temp.menu = temp.class = temp.title = 0; - - hChildDlg = CreateDialogIndirectParamA(COMDLG32_hInstance, &temp.tmplate, - hwnd, (DLGPROC)fodInfos->ofnInfos->lpfnHook, (LPARAM)fodInfos->ofnInfos); - - return hChildDlg; - } - return NULL; -} - -/*********************************************************************** -* SendCustomDlgNotificationMessage -* -* Send CustomDialogNotification (CDN_FIRST -- CDN_LAST) message to the custom template dialog -*/ - -LRESULT SendCustomDlgNotificationMessage(HWND hwndParentDlg, UINT uCode) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwndParentDlg); - LRESULT hook_result; - OFNOTIFYW ofnNotify; - - TRACE("%p %d\n", hwndParentDlg, uCode); - - if (!fodInfos || !fodInfos->DlgInfos.hwndCustomDlg) - return 0; - - TRACE("CALL NOTIFY for %d\n", uCode); - - ofnNotify.hdr.hwndFrom = hwndParentDlg; - ofnNotify.hdr.idFrom = 0; - ofnNotify.hdr.code = uCode; - ofnNotify.lpOFN = fodInfos->ofnInfos; - ofnNotify.pszFile = NULL; - - if (fodInfos->unicode) - hook_result = SendMessageW(fodInfos->DlgInfos.hwndCustomDlg, WM_NOTIFY, 0, (LPARAM)&ofnNotify); - else - hook_result = SendMessageA(fodInfos->DlgInfos.hwndCustomDlg, WM_NOTIFY, 0, (LPARAM)&ofnNotify); - - TRACE("RET NOTIFY retval %#Ix\n", hook_result); - - return hook_result; -} - -static INT_PTR FILEDLG95_Handle_GetFilePath(HWND hwnd, DWORD size, LPVOID result) -{ - UINT len, total; - WCHAR *p, *buffer; - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - - TRACE("CDM_GETFILEPATH:\n"); - - if ( ! (fodInfos->ofnInfos->Flags & OFN_EXPLORER ) ) - return -1; - - /* get path and filenames */ - len = SendMessageW( fodInfos->DlgInfos.hwndFileName, WM_GETTEXTLENGTH, 0, 0 ); - buffer = heap_alloc( (len + 2 + MAX_PATH) * sizeof(WCHAR) ); - COMDLG32_GetDisplayNameOf( fodInfos->ShellInfos.pidlAbsCurrent, buffer ); - if (len) - { - p = buffer + lstrlenW(buffer); - *p++ = '\\'; - SendMessageW( fodInfos->DlgInfos.hwndFileName, WM_GETTEXT, len + 1, (LPARAM)p ); - } - if (fodInfos->unicode) - { - total = lstrlenW( buffer) + 1; - if (result) lstrcpynW( result, buffer, size ); - TRACE( "CDM_GETFILEPATH: returning %u %s\n", total, debugstr_w(result)); - } - else - { - total = WideCharToMultiByte( CP_ACP, 0, buffer, -1, NULL, 0, NULL, NULL ); - if (total <= size) WideCharToMultiByte( CP_ACP, 0, buffer, -1, result, size, NULL, NULL ); - TRACE( "CDM_GETFILEPATH: returning %u %s\n", total, debugstr_a(result)); - } - heap_free( buffer ); - return total; -} - -/*********************************************************************** -* FILEDLG95_HandleCustomDialogMessages -* -* Handle Custom Dialog Messages (CDM_FIRST -- CDM_LAST) messages -*/ -static INT_PTR FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - WCHAR lpstrPath[MAX_PATH]; - INT_PTR retval; - - if(!fodInfos) return FALSE; - - switch(uMsg) - { - case CDM_GETFILEPATH: - retval = FILEDLG95_Handle_GetFilePath(hwnd, (UINT)wParam, (LPVOID)lParam); - break; - - case CDM_GETFOLDERPATH: - TRACE("CDM_GETFOLDERPATH:\n"); - COMDLG32_GetDisplayNameOf(fodInfos->ShellInfos.pidlAbsCurrent, lpstrPath); - if (lParam) - { - if (fodInfos->unicode) - lstrcpynW((LPWSTR)lParam, lpstrPath, (int)wParam); - else - WideCharToMultiByte(CP_ACP, 0, lpstrPath, -1, - (LPSTR)lParam, (int)wParam, NULL, NULL); - } - retval = lstrlenW(lpstrPath) + 1; - break; - - case CDM_GETFOLDERIDLIST: - retval = ILGetSize(fodInfos->ShellInfos.pidlAbsCurrent); - if (retval <= wParam) - memcpy((void*)lParam, fodInfos->ShellInfos.pidlAbsCurrent, retval); - break; - - case CDM_GETSPEC: - TRACE("CDM_GETSPEC:\n"); - retval = SendMessageW(fodInfos->DlgInfos.hwndFileName, WM_GETTEXTLENGTH, 0, 0) + 1; - if (lParam) - { - if (fodInfos->unicode) - SendMessageW(fodInfos->DlgInfos.hwndFileName, WM_GETTEXT, wParam, lParam); - else - SendMessageA(fodInfos->DlgInfos.hwndFileName, WM_GETTEXT, wParam, lParam); - } - break; - - case CDM_SETCONTROLTEXT: - TRACE("CDM_SETCONTROLTEXT:\n"); - if ( lParam ) - { - if( fodInfos->unicode ) - SetDlgItemTextW( hwnd, (UINT) wParam, (LPWSTR) lParam ); - else - SetDlgItemTextA( hwnd, (UINT) wParam, (LPSTR) lParam ); - } - retval = TRUE; - break; - - case CDM_HIDECONTROL: - /* MSDN states that it should fail for not OFN_EXPLORER case */ - if (fodInfos->ofnInfos->Flags & OFN_EXPLORER) - { - HWND control = GetDlgItem( hwnd, wParam ); - if (control) ShowWindow( control, SW_HIDE ); - retval = TRUE; - } - else retval = FALSE; - break; - - default: - if (uMsg >= CDM_FIRST && uMsg <= CDM_LAST) - FIXME("message CDM_FIRST+%04x not implemented\n", uMsg - CDM_FIRST); - return FALSE; - } - SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, retval); - return TRUE; -} - -/*********************************************************************** - * FILEDLG95_OnWMGetMMI - * - * WM_GETMINMAXINFO message handler for resizable dialogs - */ -static LRESULT FILEDLG95_OnWMGetMMI( HWND hwnd, LPMINMAXINFO mmiptr) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - if( !(fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)) return FALSE; - if( fodInfos->initial_size.x || fodInfos->initial_size.y) - { - mmiptr->ptMinTrackSize = fodInfos->initial_size; - } - return TRUE; -} - -/*********************************************************************** - * FILEDLG95_OnWMSize - * - * WM_SIZE message handler, resize the dialog. Re-arrange controls. - * - * FIXME: this could be made more elaborate. Now use a simple scheme - * where the file view is enlarged and the controls are either moved - * vertically or horizontally to get out of the way. Only the "grip" - * is moved in both directions to stay in the corner. - */ -static LRESULT FILEDLG95_OnWMSize(HWND hwnd, WPARAM wParam) -{ - RECT rc, rcview; - int chgx, chgy; - HWND ctrl; - HDWP hdwp; - FileOpenDlgInfos *fodInfos; - - if( wParam != SIZE_RESTORED) return FALSE; - fodInfos = get_filedlg_infoptr(hwnd); - if( !(fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)) return FALSE; - /* get the new dialog rectangle */ - GetWindowRect( hwnd, &rc); - TRACE("%p, size from %ld,%ld to %ld,%ld\n", hwnd, fodInfos->sizedlg.cx, fodInfos->sizedlg.cy, - rc.right -rc.left, rc.bottom -rc.top); - /* not initialized yet */ - if( (fodInfos->sizedlg.cx == 0 && fodInfos->sizedlg.cy == 0) || - ((fodInfos->sizedlg.cx == rc.right -rc.left) && /* no change */ - (fodInfos->sizedlg.cy == rc.bottom -rc.top))) - return FALSE; - chgx = rc.right - rc.left - fodInfos->sizedlg.cx; - chgy = rc.bottom - rc.top - fodInfos->sizedlg.cy; - fodInfos->sizedlg.cx = rc.right - rc.left; - fodInfos->sizedlg.cy = rc.bottom - rc.top; - /* change the size of the view window */ - GetWindowRect( fodInfos->ShellInfos.hwndView, &rcview); - MapWindowPoints( NULL, hwnd, (LPPOINT) &rcview, 2); - hdwp = BeginDeferWindowPos( 10); - DeferWindowPos( hdwp, fodInfos->ShellInfos.hwndView, NULL, 0, 0, - rcview.right - rcview.left + chgx, - rcview.bottom - rcview.top + chgy, - SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); - /* change position and sizes of the controls */ - for( ctrl = GetWindow( hwnd, GW_CHILD); ctrl ; ctrl = GetWindow( ctrl, GW_HWNDNEXT)) - { - int ctrlid = GetDlgCtrlID( ctrl); - GetWindowRect( ctrl, &rc); - MapWindowPoints( NULL, hwnd, (LPPOINT) &rc, 2); - if( ctrl == fodInfos->DlgInfos.hwndGrip) - { - DeferWindowPos( hdwp, ctrl, NULL, rc.left + chgx, rc.top + chgy, - 0, 0, - SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); - } - else if( rc.top > rcview.bottom) - { - /* if it was below the shell view - * move to bottom */ - switch( ctrlid) - { - /* file name (edit or comboboxex) and file types combo change also width */ - case edt1: - case cmb13: - case cmb1: - DeferWindowPos( hdwp, ctrl, NULL, rc.left, rc.top + chgy, - rc.right - rc.left + chgx, rc.bottom - rc.top, - SWP_NOACTIVATE | SWP_NOZORDER); - break; - /* then these buttons must move out of the way */ - case IDOK: - case IDCANCEL: - case pshHelp: - DeferWindowPos( hdwp, ctrl, NULL, rc.left + chgx, rc.top + chgy, - 0, 0, - SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); - break; - default: - DeferWindowPos( hdwp, ctrl, NULL, rc.left, rc.top + chgy, - 0, 0, - SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); - } - } - else if( rc.left > rcview.right) - { - /* if it was to the right of the shell view - * move to right */ - DeferWindowPos( hdwp, ctrl, NULL, rc.left + chgx, rc.top, - 0, 0, - SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); - } - else - /* special cases */ - { - switch( ctrlid) - { -#if 0 /* this is Win2k, Win XP. Vista and Higher don't move/size these controls */ - case IDC_LOOKIN: - DeferWindowPos( hdwp, ctrl, NULL, 0, 0, - rc.right - rc.left + chgx, rc.bottom - rc.top, - SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); - break; - case IDC_TOOLBARSTATIC: - case IDC_TOOLBAR: - DeferWindowPos( hdwp, ctrl, NULL, rc.left + chgx, rc.top, - 0, 0, - SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); - break; -#endif - /* not resized in windows. Since wine uses this invisible control - * to size the browser view it needs to be resized */ - case IDC_SHELLSTATIC: - DeferWindowPos( hdwp, ctrl, NULL, 0, 0, - rc.right - rc.left + chgx, - rc.bottom - rc.top + chgy, - SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); - break; - case IDC_TOOLBARPLACES: - DeferWindowPos( hdwp, ctrl, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top + chgy, - SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); - break; - } - } - } - if(fodInfos->DlgInfos.hwndCustomDlg && - (fodInfos->ofnInfos->Flags & (OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE))) - { - for( ctrl = GetWindow( fodInfos->DlgInfos.hwndCustomDlg, GW_CHILD); - ctrl ; ctrl = GetWindow( ctrl, GW_HWNDNEXT)) - { - GetWindowRect( ctrl, &rc); - MapWindowPoints( NULL, hwnd, (LPPOINT) &rc, 2); - if( rc.top > rcview.bottom) - { - /* if it was below the shell view - * move to bottom */ - DeferWindowPos( hdwp, ctrl, NULL, rc.left, rc.top + chgy, - rc.right - rc.left, rc.bottom - rc.top, - SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); - } - else if( rc.left > rcview.right) - { - /* if it was to the right of the shell view - * move to right */ - DeferWindowPos( hdwp, ctrl, NULL, rc.left + chgx, rc.top, - rc.right - rc.left, rc.bottom - rc.top, - SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); - } - } - /* size the custom dialog at the end: some applications do some - * control re-arranging at this point */ - GetClientRect(hwnd, &rc); - DeferWindowPos( hdwp,fodInfos->DlgInfos.hwndCustomDlg, NULL, - 0, 0, rc.right, rc.bottom, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); - } - EndDeferWindowPos( hdwp); - /* should not be needed */ - RedrawWindow( hwnd, NULL, 0, RDW_ALLCHILDREN | RDW_INVALIDATE ); - return TRUE; -} - -/*********************************************************************** - * FileOpenDlgProc95 - * - * File open dialog procedure - */ -INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ -#if 0 - TRACE("%p 0x%04x\n", hwnd, uMsg); -#endif - - switch(uMsg) - { - case WM_INITDIALOG: - { - FileOpenDlgInfos * fodInfos = (FileOpenDlgInfos *)lParam; - RECT rc, rcstc; - int gripx = GetSystemMetrics( SM_CYHSCROLL); - int gripy = GetSystemMetrics( SM_CYVSCROLL); - - /* Some shell namespace extensions depend on COM being initialized. */ - if (SUCCEEDED(OleInitialize(NULL))) - fodInfos->ole_initialized = TRUE; - - SetPropW(hwnd, L"FileOpenDlgInfos", fodInfos); - - FILEDLG95_InitControls(hwnd); - - if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING) - { - DWORD style = GetWindowLongW(hwnd, GWL_STYLE); - DWORD ex_style = GetWindowLongW(hwnd, GWL_EXSTYLE); - RECT client, client_adjusted; - - if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING) - { - style |= WS_SIZEBOX; - ex_style |= WS_EX_WINDOWEDGE; - } - else - style &= ~WS_SIZEBOX; - SetWindowLongW(hwnd, GWL_STYLE, style); - SetWindowLongW(hwnd, GWL_EXSTYLE, ex_style); - - GetClientRect( hwnd, &client ); - GetClientRect( hwnd, &client_adjusted ); - AdjustWindowRectEx( &client_adjusted, style, FALSE, ex_style ); - - GetWindowRect( hwnd, &rc ); - rc.right += client_adjusted.right - client.right; - rc.bottom += client_adjusted.bottom - client.bottom; - SetWindowPos(hwnd, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_FRAMECHANGED | SWP_NOACTIVATE | - SWP_NOZORDER | SWP_NOMOVE); - - GetWindowRect( hwnd, &rc ); - fodInfos->DlgInfos.hwndGrip = - CreateWindowExA( 0, "SCROLLBAR", NULL, - WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | - SBS_SIZEGRIP | SBS_SIZEBOXBOTTOMRIGHTALIGN, - rc.right - gripx, rc.bottom - gripy, - gripx, gripy, hwnd, (HMENU) -1, COMDLG32_hInstance, NULL); - } - - fodInfos->DlgInfos.hwndCustomDlg = - CreateTemplateDialog((FileOpenDlgInfos *)lParam, hwnd); - - FILEDLG95_ResizeControls(hwnd, wParam, lParam); - FILEDLG95_FillControls(hwnd, wParam, lParam); - - if( fodInfos->DlgInfos.hwndCustomDlg) - ShowWindow( fodInfos->DlgInfos.hwndCustomDlg, SW_SHOW); - - if(fodInfos->ofnInfos->Flags & OFN_EXPLORER) { - SendCustomDlgNotificationMessage(hwnd,CDN_INITDONE); - SendCustomDlgNotificationMessage(hwnd,CDN_FOLDERCHANGE); - } - - /* if the app has changed the position of the invisible listbox, - * change that of the listview (browser) as well */ - GetWindowRect( fodInfos->ShellInfos.hwndView, &rc); - GetWindowRect( GetDlgItem( hwnd, IDC_SHELLSTATIC ), &rcstc); - if( !EqualRect( &rc, &rcstc)) - { - MapWindowPoints( NULL, hwnd, (LPPOINT) &rcstc, 2); - SetWindowPos( fodInfos->ShellInfos.hwndView, NULL, - rcstc.left, rcstc.top, rcstc.right - rcstc.left, rcstc.bottom - rcstc.top, - SWP_NOACTIVATE | SWP_NOZORDER); - } - - if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING) - { - GetWindowRect( hwnd, &rc); - fodInfos->sizedlg.cx = rc.right - rc.left; - fodInfos->sizedlg.cy = rc.bottom - rc.top; - fodInfos->initial_size.x = fodInfos->sizedlg.cx; - fodInfos->initial_size.y = fodInfos->sizedlg.cy; - GetClientRect( hwnd, &rc); - SetWindowPos( fodInfos->DlgInfos.hwndGrip, NULL, - rc.right - gripx, rc.bottom - gripy, - 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); - /* resize the dialog to the previous invocation */ - if( MemDialogSize.cx && MemDialogSize.cy) - SetWindowPos( hwnd, NULL, - 0, 0, MemDialogSize.cx, MemDialogSize.cy, - SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); - } - - if(fodInfos->ofnInfos->Flags & OFN_EXPLORER) - SendCustomDlgNotificationMessage(hwnd,CDN_SELCHANGE); - - return 0; - } - case WM_SIZE: - return FILEDLG95_OnWMSize(hwnd, wParam); - case WM_GETMINMAXINFO: - return FILEDLG95_OnWMGetMMI( hwnd, (LPMINMAXINFO)lParam); - case WM_COMMAND: - return FILEDLG95_OnWMCommand(hwnd, wParam); - case WM_DRAWITEM: - { - switch(((LPDRAWITEMSTRUCT)lParam)->CtlID) - { - case IDC_LOOKIN: - FILEDLG95_LOOKIN_DrawItem((LPDRAWITEMSTRUCT) lParam); - return TRUE; - } - } - return FALSE; - - case WM_GETISHELLBROWSER: - return FILEDLG95_OnWMGetIShellBrowser(hwnd); - - case WM_DESTROY: - { - FileOpenDlgInfos * fodInfos = get_filedlg_infoptr(hwnd); - HWND places_bar = GetDlgItem(hwnd, IDC_TOOLBARPLACES); - HIMAGELIST himl; - - if (fodInfos && fodInfos->ofnInfos->Flags & OFN_ENABLESIZING) - MemDialogSize = fodInfos->sizedlg; - - if (places_bar) - { - himl = (HIMAGELIST)SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_GETIMAGELIST, 0, 0); - SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETIMAGELIST, 0, 0); - ImageList_Destroy(himl); - } - return FALSE; - } - - case WM_NCDESTROY: - RemovePropW(hwnd, L"FileOpenDlgInfos"); - return 0; - - case WM_NOTIFY: - { - LPNMHDR lpnmh = (LPNMHDR)lParam; - UINT stringId = -1; - - /* set up the button tooltips strings */ - if(TTN_GETDISPINFOA == lpnmh->code ) - { - LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam; - switch(lpnmh->idFrom ) - { - /* Up folder button */ - case FCIDM_TB_UPFOLDER: - stringId = IDS_UPFOLDER; - break; - /* New folder button */ - case FCIDM_TB_NEWFOLDER: - stringId = IDS_NEWFOLDER; - break; - /* List option button */ - case FCIDM_TB_SMALLICON: - stringId = IDS_LISTVIEW; - break; - /* Details option button */ - case FCIDM_TB_REPORTVIEW: - stringId = IDS_REPORTVIEW; - break; - /* Desktop button */ - case FCIDM_TB_DESKTOP: - stringId = IDS_TODESKTOP; - break; - default: - stringId = 0; - } - lpdi->hinst = COMDLG32_hInstance; - lpdi->lpszText = MAKEINTRESOURCEA(stringId); - } - return FALSE; - } - default : - if(uMsg >= CDM_FIRST && uMsg <= CDM_LAST) - return FILEDLG95_HandleCustomDialogMessages(hwnd, uMsg, wParam, lParam); - return FALSE; - } -} - -static inline BOOL filename_is_edit( const FileOpenDlgInfos *info ) -{ - return (info->ofnInfos->lStructSize == OPENFILENAME_SIZE_VERSION_400W) && - (info->ofnInfos->Flags & (OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE)); -} - -/*********************************************************************** - * FILEDLG95_InitControls - * - * WM_INITDIALOG message handler (before hook notification) - */ -static LRESULT FILEDLG95_InitControls(HWND hwnd) -{ - BOOL win2000plus = FALSE; - BOOL win98plus = FALSE; - BOOL handledPath = FALSE; - OSVERSIONINFOW osVi; - - static const TBBUTTON tbb[] = - { - {0, 0, TBSTATE_ENABLED, BTNS_SEP, {0, 0}, 0, 0 }, - {VIEW_PARENTFOLDER, FCIDM_TB_UPFOLDER, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0 }, - {0, 0, TBSTATE_ENABLED, BTNS_SEP, {0, 0}, 0, 0 }, - {VIEW_NEWFOLDER+1, FCIDM_TB_DESKTOP, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0 }, - {0, 0, TBSTATE_ENABLED, BTNS_SEP, {0, 0}, 0, 0 }, - {VIEW_NEWFOLDER, FCIDM_TB_NEWFOLDER, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0 }, - {0, 0, TBSTATE_ENABLED, BTNS_SEP, {0, 0}, 0, 0 }, - {VIEW_LIST, FCIDM_TB_SMALLICON, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0 }, - {VIEW_DETAILS, FCIDM_TB_REPORTVIEW, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0 }, - }; - static const TBADDBITMAP tba = {HINST_COMMCTRL, IDB_VIEW_SMALL_COLOR}; - - RECT rectTB; - RECT rectlook; - - HIMAGELIST toolbarImageList; - ITEMIDLIST *desktopPidl; - SHFILEINFOW fileinfo; - - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - - TRACE("%p\n", fodInfos); - - /* Get windows version emulating */ - osVi.dwOSVersionInfoSize = sizeof(osVi); - GetVersionExW(&osVi); - if (osVi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { - win98plus = ((osVi.dwMajorVersion > 4) || ((osVi.dwMajorVersion == 4) && (osVi.dwMinorVersion > 0))); - } else if (osVi.dwPlatformId == VER_PLATFORM_WIN32_NT) { - win2000plus = (osVi.dwMajorVersion > 4); - if (win2000plus) win98plus = TRUE; - } - TRACE("Running on 2000+ %d, 98+ %d\n", win2000plus, win98plus); - - - /* Use either the edit or the comboboxex for the filename control */ - if (filename_is_edit( fodInfos )) - { - DestroyWindow( GetDlgItem( hwnd, cmb13 ) ); - fodInfos->DlgInfos.hwndFileName = GetDlgItem( hwnd, edt1 ); - } - else - { - DestroyWindow( GetDlgItem( hwnd, edt1 ) ); - fodInfos->DlgInfos.hwndFileName = GetDlgItem( hwnd, cmb13 ); - } - - /* Get the hwnd of the controls */ - fodInfos->DlgInfos.hwndFileTypeCB = GetDlgItem(hwnd,IDC_FILETYPE); - fodInfos->DlgInfos.hwndLookInCB = GetDlgItem(hwnd,IDC_LOOKIN); - - GetWindowRect( fodInfos->DlgInfos.hwndLookInCB,&rectlook); - MapWindowPoints( 0, hwnd,(LPPOINT)&rectlook,2); - - /* construct the toolbar */ - GetWindowRect(GetDlgItem(hwnd,IDC_TOOLBARSTATIC),&rectTB); - MapWindowPoints( 0, hwnd,(LPPOINT)&rectTB,2); - - rectTB.right = rectlook.right + rectTB.right - rectTB.left; - rectTB.bottom = rectlook.top - 1 + rectTB.bottom - rectTB.top; - rectTB.left = rectlook.right; - rectTB.top = rectlook.top-1; - - if (fodInfos->unicode) - fodInfos->DlgInfos.hwndTB = CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, - WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | CCS_NODIVIDER | CCS_NORESIZE, - rectTB.left, rectTB.top, - rectTB.right - rectTB.left, rectTB.bottom - rectTB.top, - hwnd, (HMENU)IDC_TOOLBAR, COMDLG32_hInstance, NULL); - else - fodInfos->DlgInfos.hwndTB = CreateWindowExA(0, TOOLBARCLASSNAMEA, NULL, - WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | CCS_NODIVIDER | CCS_NORESIZE, - rectTB.left, rectTB.top, - rectTB.right - rectTB.left, rectTB.bottom - rectTB.top, - hwnd, (HMENU)IDC_TOOLBAR, COMDLG32_hInstance, NULL); - - SendMessageW(fodInfos->DlgInfos.hwndTB, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); - -/* FIXME: use TB_LOADIMAGES when implemented */ -/* SendMessageW(fodInfos->DlgInfos.hwndTB, TB_LOADIMAGES, IDB_VIEW_SMALL_COLOR, HINST_COMMCTRL);*/ - SendMessageW(fodInfos->DlgInfos.hwndTB, TB_SETMAXTEXTROWS, 0, 0); - SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBITMAP, 12, (LPARAM) &tba); - - /* Retrieve and add desktop icon to the toolbar */ - toolbarImageList = (HIMAGELIST)SendMessageW(fodInfos->DlgInfos.hwndTB, TB_GETIMAGELIST, 0, 0L); - SHGetSpecialFolderLocation(hwnd, CSIDL_DESKTOP, &desktopPidl); - SHGetFileInfoW((const WCHAR *)desktopPidl, 0, &fileinfo, sizeof(fileinfo), - SHGFI_PIDL | SHGFI_ICON | SHGFI_SMALLICON); - ImageList_AddIcon(toolbarImageList, fileinfo.hIcon); - - DestroyIcon(fileinfo.hIcon); - CoTaskMemFree(desktopPidl); - - /* Finish Toolbar Construction */ - SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBUTTONSW, 9, (LPARAM) tbb); - SendMessageW(fodInfos->DlgInfos.hwndTB, TB_AUTOSIZE, 0, 0); - - if (is_places_bar_enabled(fodInfos)) - { - TBBUTTON tb = { 0 }; - HIMAGELIST himl; - RECT rect; - int i, cx; - - SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_BUTTONSTRUCTSIZE, 0, 0); - GetClientRect(GetDlgItem(hwnd, IDC_TOOLBARPLACES), &rect); - cx = rect.right - rect.left; - - SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETBUTTONWIDTH, 0, MAKELPARAM(cx, cx)); - himl = ImageList_Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), ILC_COLOR32, 4, 1); - - filedlg_collect_places_pidls(fodInfos); - for (i = 0; i < ARRAY_SIZE(fodInfos->places); i++) - { - int index; - - if (!fodInfos->places[i]) - continue; - - memset(&fileinfo, 0, sizeof(fileinfo)); - SHGetFileInfoW((const WCHAR *)fodInfos->places[i], 0, &fileinfo, sizeof(fileinfo), - SHGFI_PIDL | SHGFI_DISPLAYNAME | SHGFI_ICON); - index = ImageList_AddIcon(himl, fileinfo.hIcon); - - tb.iBitmap = index; - tb.iString = (INT_PTR)fileinfo.szDisplayName; - tb.fsState = TBSTATE_ENABLED | TBSTATE_WRAP; - tb.idCommand = TBPLACES_CMDID_PLACE0 + i; - SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_ADDBUTTONSW, 1, (LPARAM)&tb); - - DestroyIcon(fileinfo.hIcon); - } - - SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETIMAGELIST, 0, (LPARAM)himl); - SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETBUTTONSIZE, 0, MAKELPARAM(cx, cx * 3 / 4)); - } - - /* Set the window text with the text specified in the OPENFILENAME structure */ - if(fodInfos->title) - { - SetWindowTextW(hwnd,fodInfos->title); - } - else if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG) - { - WCHAR buf[64]; - LoadStringW(COMDLG32_hInstance, IDS_SAVE_AS, buf, ARRAY_SIZE(buf)); - SetWindowTextW(hwnd, buf); - } - - /* Initialise the file name edit control */ - handledPath = FALSE; - TRACE("Before manipulation, file = %s, dir = %s\n", debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir)); - - if(fodInfos->filename) - { - /* 1. If win2000 or higher and filename contains a path, use it - in preference over the lpstrInitialDir */ - if (win2000plus && *fodInfos->filename && wcspbrk(fodInfos->filename, L"\\")) { - WCHAR tmpBuf[MAX_PATH]; - WCHAR *nameBit; - DWORD result; - - result = GetFullPathNameW(fodInfos->filename, MAX_PATH, tmpBuf, &nameBit); - if (result) { - - /* nameBit is always shorter than the original filename. It may be NULL - * when the filename contains only a drive name instead of file name */ - if (nameBit) - { - lstrcpyW(fodInfos->filename,nameBit); - *nameBit = 0x00; - } - else - *fodInfos->filename = '\0'; - - heap_free(fodInfos->initdir); - fodInfos->initdir = heap_alloc((lstrlenW(tmpBuf) + 1)*sizeof(WCHAR)); - lstrcpyW(fodInfos->initdir, tmpBuf); - handledPath = TRUE; - TRACE("Value in Filename includes path, overriding InitialDir: %s, %s\n", - debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir)); - } - SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename ); - - } else { - SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename ); - } - } - - /* 2. (All platforms) If initdir is not null, then use it */ - if (!handledPath && fodInfos->initdir && *fodInfos->initdir) - { - /* Work out the proper path as supplied one might be relative */ - /* (Here because supplying '.' as dir browses to My Computer) */ - WCHAR tmpBuf[MAX_PATH]; - WCHAR tmpBuf2[MAX_PATH]; - WCHAR *nameBit; - DWORD result; - - lstrcpyW(tmpBuf, fodInfos->initdir); - if (PathFileExistsW(tmpBuf)) { - /* initdir does not have to be a directory. If a file is - * specified, the dir part is taken */ - if (PathIsDirectoryW(tmpBuf)) { - PathAddBackslashW(tmpBuf); - lstrcatW(tmpBuf, L"*"); - } - result = GetFullPathNameW(tmpBuf, MAX_PATH, tmpBuf2, &nameBit); - if (result) { - *nameBit = 0x00; - heap_free(fodInfos->initdir); - fodInfos->initdir = heap_alloc((lstrlenW(tmpBuf2) + 1) * sizeof(WCHAR)); - lstrcpyW(fodInfos->initdir, tmpBuf2); - handledPath = TRUE; - TRACE("Value in InitDir changed to %s\n", debugstr_w(fodInfos->initdir)); - } - } - else if (fodInfos->initdir) - { - heap_free(fodInfos->initdir); - fodInfos->initdir = NULL; - TRACE("Value in InitDir is not an existing path, changed to (nil)\n"); - } - } - - if (!handledPath && (!fodInfos->initdir || !*fodInfos->initdir)) - { - /* 3. All except w2k+: if filename contains a path use it */ - if (!win2000plus && fodInfos->filename && *fodInfos->filename && - wcspbrk(fodInfos->filename, L"\\")) { - WCHAR tmpBuf[MAX_PATH]; - WCHAR *nameBit; - DWORD result; - - result = GetFullPathNameW(fodInfos->filename, MAX_PATH, - tmpBuf, &nameBit); - if (result) { - int len; - - /* nameBit is always shorter than the original filename */ - lstrcpyW(fodInfos->filename, nameBit); - *nameBit = 0x00; - - len = lstrlenW(tmpBuf); - heap_free(fodInfos->initdir); - fodInfos->initdir = heap_alloc((len+1)*sizeof(WCHAR)); - lstrcpyW(fodInfos->initdir, tmpBuf); - - handledPath = TRUE; - TRACE("Value in Filename includes path, overriding initdir: %s, %s\n", - debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir)); - } - SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename ); - } - - /* 4. Win2000+: Recently used */ - if (!handledPath && win2000plus) { - fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR)); - fodInfos->initdir[0] = '\0'; - - FILEDLG95_MRU_load_filename(fodInfos->initdir); - - if (fodInfos->initdir[0] && PathFileExistsW(fodInfos->initdir)){ - handledPath = TRUE; - }else{ - heap_free(fodInfos->initdir); - fodInfos->initdir = NULL; - } - } - - /* 5. win98+ and win2000+ if any files of specified filter types in - current directory, use it */ - if (win98plus && !handledPath && fodInfos->filter && *fodInfos->filter) { - - LPCWSTR lpstrPos = fodInfos->filter; - WIN32_FIND_DATAW FindFileData; - HANDLE hFind; - - while (1) - { - /* filter is a list... title\0ext\0......\0\0 */ - - /* Skip the title */ - if(! *lpstrPos) break; /* end */ - lpstrPos += lstrlenW(lpstrPos) + 1; - - /* See if any files exist in the current dir with this extension */ - if(! *lpstrPos) break; /* end */ - - hFind = FindFirstFileW(lpstrPos, &FindFileData); - - if (hFind == INVALID_HANDLE_VALUE) { - /* None found - continue search */ - lpstrPos += lstrlenW(lpstrPos) + 1; - - } else { - - heap_free(fodInfos->initdir); - fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR)); - GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir); - - handledPath = TRUE; - TRACE("No initial dir specified, but files of type %s found in current, so using it\n", - debugstr_w(lpstrPos)); - FindClose(hFind); - break; - } - } - } - - /* 6. Win98+ and 2000+: Use personal files dir, others use current dir */ - if (!handledPath && (win2000plus || win98plus)) { - fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR)); - - if (SHGetFolderPathW(hwnd, CSIDL_PERSONAL, 0, 0, fodInfos->initdir) == S_OK) - { - if (SHGetFolderPathW(hwnd, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE, 0, 0, fodInfos->initdir) == S_OK) - { - /* last fallback */ - GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir); - TRACE("No personal or desktop dir, using cwd as failsafe: %s\n", debugstr_w(fodInfos->initdir)); - } - else - TRACE("No personal dir, using desktop instead: %s\n", debugstr_w(fodInfos->initdir)); - } - else - TRACE("No initial dir specified, using personal files dir of %s\n", debugstr_w(fodInfos->initdir)); - - handledPath = TRUE; - } else if (!handledPath) { - fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR)); - GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir); - handledPath = TRUE; - TRACE("No initial dir specified, using current dir of %s\n", debugstr_w(fodInfos->initdir)); - } - } - SetFocus( fodInfos->DlgInfos.hwndFileName ); - TRACE("After manipulation, file = %s, dir = %s\n", debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir)); - - /* Must the open as read only check box be checked ?*/ - if(fodInfos->ofnInfos->Flags & OFN_READONLY) - { - SendDlgItemMessageW(hwnd,IDC_OPENREADONLY,BM_SETCHECK,TRUE,0); - } - - /* Must the open as read only check box be hidden? */ - if (filedialog_is_readonly_hidden(fodInfos)) - { - ShowWindow(GetDlgItem(hwnd,IDC_OPENREADONLY),SW_HIDE); - EnableWindow(GetDlgItem(hwnd, IDC_OPENREADONLY), FALSE); - } - - /* Must the help button be hidden? */ - if (!(fodInfos->ofnInfos->Flags & OFN_SHOWHELP)) - { - ShowWindow(GetDlgItem(hwnd, pshHelp), SW_HIDE); - EnableWindow(GetDlgItem(hwnd, pshHelp), FALSE); - } - - /* change Open to Save */ - if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG) - { - WCHAR buf[16]; - LoadStringW(COMDLG32_hInstance, IDS_SAVE_BUTTON, buf, ARRAY_SIZE(buf)); - SetDlgItemTextW(hwnd, IDOK, buf); - LoadStringW(COMDLG32_hInstance, IDS_SAVE_IN, buf, ARRAY_SIZE(buf)); - SetDlgItemTextW(hwnd, IDC_LOOKINSTATIC, buf); - } - - /* Initialize the filter combo box */ - FILEDLG95_FILETYPE_Init(hwnd); - - return 0; -} - -/*********************************************************************** - * FILEDLG95_ResizeControls - * - * WM_INITDIALOG message handler (after hook notification) - */ -static LRESULT FILEDLG95_ResizeControls(HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) lParam; - - if (fodInfos->DlgInfos.hwndCustomDlg) - { - RECT rc; - UINT flags = SWP_NOACTIVATE; - - ArrangeCtrlPositions(fodInfos->DlgInfos.hwndCustomDlg, hwnd, - filedialog_is_readonly_hidden(fodInfos) && !(fodInfos->ofnInfos->Flags & OFN_SHOWHELP)); - - /* resize the custom dialog to the parent size */ - if (fodInfos->ofnInfos->Flags & (OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE)) - GetClientRect(hwnd, &rc); - else - { - /* our own fake template is zero sized and doesn't have children, so - * there is no need to resize it. Picasa depends on it. - */ - flags |= SWP_NOSIZE; - SetRectEmpty(&rc); - } - SetWindowPos(fodInfos->DlgInfos.hwndCustomDlg, HWND_BOTTOM, - 0, 0, rc.right, rc.bottom, flags); - } - else - { - /* Resize the height; if opened as read-only, checkbox and help button are - * hidden and we are not using a custom template nor a customDialog - */ - if (filedialog_is_readonly_hidden(fodInfos) && - (!(fodInfos->ofnInfos->Flags & - (OFN_SHOWHELP|OFN_ENABLETEMPLATE|OFN_ENABLETEMPLATEHANDLE)))) - { - RECT rectDlg, rectHelp, rectCancel; - GetWindowRect(hwnd, &rectDlg); - GetWindowRect(GetDlgItem(hwnd, pshHelp), &rectHelp); - GetWindowRect(GetDlgItem(hwnd, IDCANCEL), &rectCancel); - /* subtract the height of the help button plus the space between the help - * button and the cancel button to the height of the dialog - */ - SetWindowPos(hwnd, 0, 0, 0, rectDlg.right-rectDlg.left, - (rectDlg.bottom-rectDlg.top) - (rectHelp.bottom - rectCancel.bottom), - SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER); - } - } - return TRUE; -} - -/*********************************************************************** - * FILEDLG95_FillControls - * - * WM_INITDIALOG message handler (after hook notification) - */ -static LRESULT FILEDLG95_FillControls(HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - LPITEMIDLIST pidlItemId = NULL; - - FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) lParam; - - TRACE("dir=%s file=%s\n", - debugstr_w(fodInfos->initdir), debugstr_w(fodInfos->filename)); - - /* Get the initial directory pidl */ - - if(!(pidlItemId = GetPidlFromName(fodInfos->Shell.FOIShellFolder,fodInfos->initdir))) - { - WCHAR path[MAX_PATH]; - - GetCurrentDirectoryW(MAX_PATH,path); - pidlItemId = GetPidlFromName(fodInfos->Shell.FOIShellFolder, path); - } - - /* Initialise shell objects */ - FILEDLG95_SHELL_Init(hwnd); - - /* Initialize the Look In combo box */ - FILEDLG95_LOOKIN_Init(fodInfos->DlgInfos.hwndLookInCB); - - /* Browse to the initial directory */ - IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,pidlItemId, SBSP_ABSOLUTE); - - ILFree(pidlItemId); - - return TRUE; -} -/*********************************************************************** - * FILEDLG95_Clean - * - * Regroups all the cleaning functions of the filedlg - */ -void FILEDLG95_Clean(HWND hwnd) -{ - FILEDLG95_FILETYPE_Clean(hwnd); - FILEDLG95_LOOKIN_Clean(hwnd); - FILEDLG95_SHELL_Clean(hwnd); -} - - -/*********************************************************************** - * Browse to arbitrary pidl - */ -static void filedlg_browse_to_pidl(const FileOpenDlgInfos *info, LPITEMIDLIST pidl) -{ - TRACE("%p, %p\n", info->ShellInfos.hwndOwner, pidl); - - IShellBrowser_BrowseObject(info->Shell.FOIShellBrowser, pidl, SBSP_ABSOLUTE); - if (info->ofnInfos->Flags & OFN_EXPLORER) - SendCustomDlgNotificationMessage(info->ShellInfos.hwndOwner, CDN_FOLDERCHANGE); -} - -/*********************************************************************** - * FILEDLG95_OnWMCommand - * - * WM_COMMAND message handler - */ -static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - WORD wNotifyCode = HIWORD(wParam); /* notification code */ - WORD id = LOWORD(wParam); /* item, control, or accelerator identifier */ - - switch (id) - { - /* OK button */ - case IDOK: - FILEDLG95_OnOpen(hwnd); - break; - /* Cancel button */ - case IDCANCEL: - FILEDLG95_Clean(hwnd); - EndDialog(hwnd, FALSE); - break; - /* Filetype combo box */ - case IDC_FILETYPE: - FILEDLG95_FILETYPE_OnCommand(hwnd,wNotifyCode); - break; - /* LookIn combo box */ - case IDC_LOOKIN: - FILEDLG95_LOOKIN_OnCommand(hwnd,wNotifyCode); - break; - - /* --- toolbar --- */ - /* Up folder button */ - case FCIDM_TB_UPFOLDER: - FILEDLG95_SHELL_UpFolder(hwnd); - break; - /* New folder button */ - case FCIDM_TB_NEWFOLDER: - FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_NEWFOLDERA); - break; - /* List option button */ - case FCIDM_TB_SMALLICON: - FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWLISTA); - break; - /* Details option button */ - case FCIDM_TB_REPORTVIEW: - FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWDETAILSA); - break; - - case FCIDM_TB_DESKTOP: - { - LPITEMIDLIST pidl; - - SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, &pidl); - filedlg_browse_to_pidl(fodInfos, pidl); - ILFree(pidl); - break; - } - - /* Places bar */ - case TBPLACES_CMDID_PLACE0: - case TBPLACES_CMDID_PLACE1: - case TBPLACES_CMDID_PLACE2: - case TBPLACES_CMDID_PLACE3: - case TBPLACES_CMDID_PLACE4: - filedlg_browse_to_pidl(fodInfos, fodInfos->places[id - TBPLACES_CMDID_PLACE0]); - break; - - case edt1: - case cmb13: - break; - - } - /* Do not use the listview selection anymore */ - fodInfos->DlgInfos.dwDlgProp &= ~FODPROP_USEVIEW; - return 0; -} - -/*********************************************************************** - * FILEDLG95_OnWMGetIShellBrowser - * - * WM_GETISHELLBROWSER message handler - */ -static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - - TRACE("\n"); - - SetWindowLongPtrW(hwnd,DWLP_MSGRESULT,(LONG_PTR)fodInfos->Shell.FOIShellBrowser); - - return TRUE; -} - - -/*********************************************************************** - * FILEDLG95_SendFileOK - * - * Sends the CDN_FILEOK notification if required - * - * RETURNS - * TRUE if the dialog should close - * FALSE if the dialog should not be closed - */ -static BOOL FILEDLG95_SendFileOK( HWND hwnd, FileOpenDlgInfos *fodInfos ) -{ - /* ask the hook if we can close */ - if (is_dialog_hooked(fodInfos)) - { - LRESULT retval = 0; - - TRACE("---\n"); - /* First send CDN_FILEOK as MSDN doc says */ - if(fodInfos->ofnInfos->Flags & OFN_EXPLORER) - retval = SendCustomDlgNotificationMessage(hwnd,CDN_FILEOK); - if( retval) - { - TRACE("canceled\n"); - return FALSE; - } - - /* fodInfos->ofnInfos points to an ASCII or UNICODE structure as appropriate */ - retval = SendMessageW(fodInfos->DlgInfos.hwndCustomDlg, - fodInfos->HookMsg.fileokstring, 0, (LPARAM)fodInfos->ofnInfos); - if( retval) - { - TRACE("canceled\n"); - return FALSE; - } - } - return TRUE; -} - -/*********************************************************************** - * FILEDLG95_OnOpenMultipleFiles - * - * Handles the opening of multiple files. - * - * FIXME - * check destination buffer size - */ -BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCount, UINT sizeUsed) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - WCHAR lpstrPathSpec[MAX_PATH] = {0}; - UINT nCount, nSizePath; - - TRACE("\n"); - - if(fodInfos->unicode) - { - LPOPENFILENAMEW ofn = fodInfos->ofnInfos; - ofn->lpstrFile[0] = '\0'; - } - else - { - LPOPENFILENAMEA ofn = (LPOPENFILENAMEA) fodInfos->ofnInfos; - ofn->lpstrFile[0] = '\0'; - } - - COMDLG32_GetDisplayNameOf( fodInfos->ShellInfos.pidlAbsCurrent, lpstrPathSpec ); - - if ( !(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE) && - ( fodInfos->ofnInfos->Flags & OFN_FILEMUSTEXIST) && - ! ( fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG ) ) - { - LPWSTR lpstrTemp = lpstrFileList; - - for ( nCount = 0; nCount < nFileCount; nCount++ ) - { - LPITEMIDLIST pidl; - - pidl = GetPidlFromName(fodInfos->Shell.FOIShellFolder, lpstrTemp); - if (!pidl) - { - WCHAR lpstrNotFound[100]; - WCHAR lpstrMsg[100]; - WCHAR tmp[400]; - - LoadStringW(COMDLG32_hInstance, IDS_FILENOTFOUND, lpstrNotFound, 100); - LoadStringW(COMDLG32_hInstance, IDS_VERIFYFILE, lpstrMsg, 100); - - lstrcpyW(tmp, lpstrTemp); - lstrcatW(tmp, L"\n"); - lstrcatW(tmp, lpstrNotFound); - lstrcatW(tmp, L"\n"); - lstrcatW(tmp, lpstrMsg); - - MessageBoxW(hwnd, tmp, fodInfos->title, MB_OK | MB_ICONEXCLAMATION); - return FALSE; - } - - /* move to the next file in the list of files */ - lpstrTemp += lstrlenW(lpstrTemp) + 1; - ILFree(pidl); - } - } - - nSizePath = lstrlenW(lpstrPathSpec) + 1; - if ( !(fodInfos->ofnInfos->Flags & OFN_EXPLORER) ) - { - /* For "oldstyle" dialog the components have to - be separated by blanks (not '\0'!) and short - filenames have to be used! */ - FIXME("Components have to be separated by blanks\n"); - } - if(fodInfos->unicode) - { - LPOPENFILENAMEW ofn = fodInfos->ofnInfos; - lstrcpyW( ofn->lpstrFile, lpstrPathSpec); - memcpy( ofn->lpstrFile + nSizePath, lpstrFileList, sizeUsed*sizeof(WCHAR) ); - } - else - { - LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)fodInfos->ofnInfos; - - if (ofn->lpstrFile != NULL) - { - nSizePath = WideCharToMultiByte(CP_ACP, 0, lpstrPathSpec, -1, - ofn->lpstrFile, ofn->nMaxFile, NULL, NULL); - if (ofn->nMaxFile > nSizePath) - { - WideCharToMultiByte(CP_ACP, 0, lpstrFileList, sizeUsed, - ofn->lpstrFile + nSizePath, - ofn->nMaxFile - nSizePath, NULL, NULL); - } - } - } - - fodInfos->ofnInfos->nFileOffset = nSizePath; - fodInfos->ofnInfos->nFileExtension = 0; - - if ( !FILEDLG95_SendFileOK(hwnd, fodInfos) ) - return FALSE; - - /* clean and exit */ - FILEDLG95_Clean(hwnd); - return EndDialog(hwnd,TRUE); -} - -/* Returns the 'slot name' of the given module_name in the registry's - * most-recently-used list. This will be an ASCII value in the - * range ['a','z'). Returns zero on error. - * - * The slot's value in the registry has the form: - * module_name\0mru_path\0 - * - * If stored_path is given, then stored_path will contain the path name - * stored in the registry's MRU list for the given module_name. - * - * If hkey_ret is given, then hkey_ret will be a handle to the registry's - * MRU list key for the given module_name. - */ -static WCHAR FILEDLG95_MRU_get_slot(LPCWSTR module_name, LPWSTR stored_path, PHKEY hkey_ret) -{ - WCHAR mru_list[32], *cur_mru_slot; - BOOL taken[25] = {0}; - DWORD mru_list_size = sizeof(mru_list), key_type = -1, i; - HKEY hkey_tmp, *hkey; - LONG ret; - - if(hkey_ret) - hkey = hkey_ret; - else - hkey = &hkey_tmp; - - if(stored_path) - *stored_path = '\0'; - - ret = RegCreateKeyW(HKEY_CURRENT_USER, - L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedMRU", hkey); - if(ret){ - WARN("Unable to create MRU key: %ld\n", ret); - return 0; - } - - ret = RegGetValueW(*hkey, NULL, L"MRUList", RRF_RT_REG_SZ, &key_type, - (LPBYTE)mru_list, &mru_list_size); - if(ret || key_type != REG_SZ){ - if(ret == ERROR_FILE_NOT_FOUND) - return 'a'; - - WARN("Error getting MRUList data: type: %ld, ret: %ld\n", key_type, ret); - RegCloseKey(*hkey); - return 0; - } - - for(cur_mru_slot = mru_list; *cur_mru_slot; ++cur_mru_slot){ - WCHAR value_data[MAX_PATH], value_name[2] = {0}; - DWORD value_data_size = sizeof(value_data); - - *value_name = *cur_mru_slot; - - ret = RegGetValueW(*hkey, NULL, value_name, RRF_RT_REG_BINARY, - &key_type, (LPBYTE)value_data, &value_data_size); - if(ret || key_type != REG_BINARY){ - WARN("Error getting MRU slot data: type: %ld, ret: %ld\n", key_type, ret); - continue; - } - - if(!wcsicmp(module_name, value_data)){ - if(!hkey_ret) - RegCloseKey(*hkey); - if(stored_path) - lstrcpyW(stored_path, value_data + lstrlenW(value_data) + 1); - return *value_name; - } - } - - if(!hkey_ret) - RegCloseKey(*hkey); - - /* the module name isn't in the registry, so find the next open slot */ - for(cur_mru_slot = mru_list; *cur_mru_slot; ++cur_mru_slot) - taken[*cur_mru_slot - 'a'] = TRUE; - for(i = 0; i < 25; ++i){ - if(!taken[i]) - return i + 'a'; - } - - /* all slots are taken, so return the last one in MRUList */ - --cur_mru_slot; - return *cur_mru_slot; -} - -/* save the given filename as most-recently-used path for this module */ -static void FILEDLG95_MRU_save_filename(LPCWSTR filename) -{ - WCHAR module_path[MAX_PATH], *module_name, slot, slot_name[2] = {0}; - LONG ret; - HKEY hkey; - - /* get the current executable's name */ - if (!GetModuleFileNameW(GetModuleHandleW(NULL), module_path, ARRAY_SIZE(module_path))) - { - WARN("GotModuleFileName failed: %ld\n", GetLastError()); - return; - } - module_name = wcsrchr(module_path, '\\'); - if(!module_name) - module_name = module_path; - else - module_name += 1; - - slot = FILEDLG95_MRU_get_slot(module_name, NULL, &hkey); - if(!slot) - return; - *slot_name = slot; - - { /* update the slot's info */ - WCHAR *path_ends, *final; - DWORD path_len, final_len; - - /* use only the path segment of `filename' */ - path_ends = wcsrchr(filename, '\\'); - path_len = path_ends - filename; - - final_len = path_len + lstrlenW(module_name) + 2; - - final = heap_alloc(final_len * sizeof(WCHAR)); - if(!final) - return; - lstrcpyW(final, module_name); - memcpy(final + lstrlenW(final) + 1, filename, path_len * sizeof(WCHAR)); - final[final_len-1] = '\0'; - - ret = RegSetValueExW(hkey, slot_name, 0, REG_BINARY, (LPBYTE)final, - final_len * sizeof(WCHAR)); - if(ret){ - WARN("Error saving MRU data to slot %s: %ld\n", wine_dbgstr_w(slot_name), ret); - heap_free(final); - RegCloseKey(hkey); - return; - } - - heap_free(final); - } - - { /* update MRUList value */ - WCHAR old_mru_list[32], new_mru_list[32]; - WCHAR *old_mru_slot, *new_mru_slot = new_mru_list; - DWORD mru_list_size = sizeof(old_mru_list), key_type; - - ret = RegGetValueW(hkey, NULL, L"MRUList", RRF_RT_ANY, &key_type, - (LPBYTE)old_mru_list, &mru_list_size); - if(ret || key_type != REG_SZ){ - if(ret == ERROR_FILE_NOT_FOUND){ - new_mru_list[0] = slot; - new_mru_list[1] = '\0'; - }else{ - WARN("Error getting MRUList data: type: %ld, ret: %ld\n", key_type, ret); - RegCloseKey(hkey); - return; - } - }else{ - /* copy old list data over so that the new slot is at the start - * of the list */ - *new_mru_slot++ = slot; - for(old_mru_slot = old_mru_list; *old_mru_slot; ++old_mru_slot){ - if(*old_mru_slot != slot) - *new_mru_slot++ = *old_mru_slot; - } - *new_mru_slot = '\0'; - } - - ret = RegSetValueExW(hkey, L"MRUList", 0, REG_SZ, (LPBYTE)new_mru_list, - (lstrlenW(new_mru_list) + 1) * sizeof(WCHAR)); - if(ret){ - WARN("Error saving MRUList data: %ld\n", ret); - RegCloseKey(hkey); - return; - } - } -} - -/* load the most-recently-used path for this module */ -static void FILEDLG95_MRU_load_filename(LPWSTR stored_path) -{ - WCHAR module_path[MAX_PATH], *module_name; - - /* get the current executable's name */ - if (!GetModuleFileNameW(GetModuleHandleW(NULL), module_path, ARRAY_SIZE(module_path))) - { - WARN("GotModuleFileName failed: %ld\n", GetLastError()); - return; - } - module_name = wcsrchr(module_path, '\\'); - if(!module_name) - module_name = module_path; - else - module_name += 1; - - FILEDLG95_MRU_get_slot(module_name, stored_path, NULL); - TRACE("got MRU path: %s\n", wine_dbgstr_w(stored_path)); -} - -void FILEDLG95_OnOpenMessage(HWND hwnd, int idCaption, int idText) -{ - WCHAR strMsgTitle[MAX_PATH]; - WCHAR strMsgText [MAX_PATH]; - if (idCaption) - LoadStringW(COMDLG32_hInstance, idCaption, strMsgTitle, ARRAY_SIZE(strMsgTitle)); - else - strMsgTitle[0] = '\0'; - LoadStringW(COMDLG32_hInstance, idText, strMsgText, ARRAY_SIZE(strMsgText)); - MessageBoxW(hwnd,strMsgText, strMsgTitle, MB_OK | MB_ICONHAND); -} - -int FILEDLG95_ValidatePathAction(LPWSTR lpstrPathAndFile, IShellFolder **ppsf, - HWND hwnd, DWORD flags, BOOL isSaveDlg, int defAction) -{ - int nOpenAction = defAction; - LPWSTR lpszTemp, lpszTemp1; - LPITEMIDLIST pidl = NULL; - - /* check for invalid chars */ - if((wcspbrk(lpstrPathAndFile+3, L"/:<>|") != NULL) && !(flags & OFN_NOVALIDATE)) - { - FILEDLG95_OnOpenMessage(hwnd, IDS_INVALID_FILENAME_TITLE, IDS_INVALID_FILENAME); - return FALSE; - } - - if (FAILED (SHGetDesktopFolder(ppsf))) return FALSE; - - lpszTemp1 = lpszTemp = lpstrPathAndFile; - while (lpszTemp1) - { - LPSHELLFOLDER lpsfChild; - WCHAR lpwstrTemp[MAX_PATH]; - DWORD dwEaten, dwAttributes; - LPWSTR p; - - lstrcpyW(lpwstrTemp, lpszTemp); - if (lpszTemp == lpstrPathAndFile && (p = PathSkipRootW(lpwstrTemp))) - { - *p = 0; - } - else - { - p = PathFindNextComponentW(lpwstrTemp); - if (!p) break; /* end of path */ - *p = 0; - } - lpszTemp = lpszTemp + lstrlenW(lpwstrTemp); - - /* There are no wildcards when OFN_NOVALIDATE is set */ - if(*lpszTemp==0 && !(flags & OFN_NOVALIDATE)) - { - /* if the last element is a wildcard do a search */ - if(wcspbrk(lpszTemp1, L"*?") != NULL) - { - nOpenAction = ONOPEN_SEARCH; - break; - } - } - lpszTemp1 = lpszTemp; - - TRACE("parse now=%s next=%s sf=%p\n",debugstr_w(lpwstrTemp), debugstr_w(lpszTemp), *ppsf); - - /* append a backslash to drive letters */ - if(lstrlenW(lpwstrTemp)==2 && lpwstrTemp[1] == ':' && - ((lpwstrTemp[0] >= 'a' && lpwstrTemp[0] <= 'z') || - (lpwstrTemp[0] >= 'A' && lpwstrTemp[0] <= 'Z'))) - { - PathAddBackslashW(lpwstrTemp); - } - - dwAttributes = SFGAO_FOLDER; - if(SUCCEEDED(IShellFolder_ParseDisplayName(*ppsf, hwnd, NULL, lpwstrTemp, &dwEaten, &pidl, &dwAttributes))) - { - /* the path component is valid, we have a pidl of the next path component */ - TRACE("parse OK attr=0x%08lx pidl=%p\n", dwAttributes, pidl); - if(dwAttributes & SFGAO_FOLDER) - { - if(FAILED(IShellFolder_BindToObject(*ppsf, pidl, 0, &IID_IShellFolder, (LPVOID*)&lpsfChild))) - { - ERR("bind to failed\n"); /* should not fail */ - break; - } - IShellFolder_Release(*ppsf); - *ppsf = lpsfChild; - lpsfChild = NULL; - } - else - { - TRACE("value\n"); - - /* end dialog, return value */ - nOpenAction = ONOPEN_OPEN; - break; - } - ILFree(pidl); - pidl = NULL; - } - else if (!(flags & OFN_NOVALIDATE)) - { - if(*lpszTemp || /* points to trailing null for last path element */ - (lpwstrTemp[lstrlenW(lpwstrTemp)-1] == '\\')) /* or if last element ends in '\' */ - { - if(flags & OFN_PATHMUSTEXIST) - { - FILEDLG95_OnOpenMessage(hwnd, 0, IDS_PATHNOTEXISTING); - break; - } - } - else - { - if( (flags & OFN_FILEMUSTEXIST) && !isSaveDlg ) - { - FILEDLG95_OnOpenMessage(hwnd, 0, IDS_FILENOTEXISTING); - break; - } - } - /* change to the current folder */ - nOpenAction = ONOPEN_OPEN; - break; - } - else - { - nOpenAction = ONOPEN_OPEN; - break; - } - } - ILFree(pidl); - - return nOpenAction; -} - -/*********************************************************************** - * FILEDLG95_OnOpen - * - * Ok button WM_COMMAND message handler - * - * If the function succeeds, the return value is nonzero. - */ -BOOL FILEDLG95_OnOpen(HWND hwnd) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - LPWSTR lpstrFileList; - UINT nFileCount = 0; - UINT sizeUsed = 0; - BOOL ret = TRUE; - WCHAR lpstrPathAndFile[MAX_PATH]; - LPSHELLFOLDER lpsf = NULL; - int nOpenAction; - - TRACE("hwnd=%p\n", hwnd); - - /* try to browse the selected item */ - if(BrowseSelectedFolder(hwnd)) - return FALSE; - - /* get the files from the edit control */ - nFileCount = FILEDLG95_FILENAME_GetFileNames(hwnd, &lpstrFileList, &sizeUsed); - - if(nFileCount == 0) - return FALSE; - - if(nFileCount > 1) - { - ret = FILEDLG95_OnOpenMultipleFiles(hwnd, lpstrFileList, nFileCount, sizeUsed); - goto ret; - } - - TRACE("count=%u len=%u file=%s\n", nFileCount, sizeUsed, debugstr_w(lpstrFileList)); - -/* - Step 1: Build a complete path name from the current folder and - the filename or path in the edit box. - Special cases: - - the path in the edit box is a root path - (with or without drive letter) - - the edit box contains ".." (or a path with ".." in it) -*/ - - COMDLG32_GetCanonicalPath(fodInfos->ShellInfos.pidlAbsCurrent, lpstrFileList, lpstrPathAndFile); - heap_free(lpstrFileList); - -/* - Step 2: here we have a cleaned up path - - We have to parse the path step by step to see if we have to browse - to a folder if the path points to a directory or the last - valid element is a directory. - - valid variables: - lpstrPathAndFile: cleaned up path - */ - - if (nFileCount && - (fodInfos->ofnInfos->Flags & OFN_NOVALIDATE) && - !(fodInfos->ofnInfos->Flags & OFN_FILEMUSTEXIST)) - nOpenAction = ONOPEN_OPEN; - else - nOpenAction = ONOPEN_BROWSE; - - nOpenAction = FILEDLG95_ValidatePathAction(lpstrPathAndFile, &lpsf, hwnd, - fodInfos->ofnInfos->Flags, - fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG, - nOpenAction); - if(!nOpenAction) - goto ret; - -/* - Step 3: here we have a cleaned up and validated path - - valid variables: - lpsf: ShellFolder bound to the rightmost valid path component - lpstrPathAndFile: cleaned up path - nOpenAction: action to do -*/ - TRACE("end validate sf=%p\n", lpsf); - - switch(nOpenAction) - { - case ONOPEN_SEARCH: /* set the current filter to the file mask and refresh */ - TRACE("ONOPEN_SEARCH %s\n", debugstr_w(lpstrPathAndFile)); - { - int iPos; - LPWSTR lpszTemp = PathFindFileNameW(lpstrPathAndFile); - DWORD len; - - /* replace the current filter */ - heap_free(fodInfos->ShellInfos.lpstrCurrentFilter); - len = lstrlenW(lpszTemp)+1; - fodInfos->ShellInfos.lpstrCurrentFilter = heap_alloc(len * sizeof(WCHAR)); - lstrcpyW( fodInfos->ShellInfos.lpstrCurrentFilter, lpszTemp); - - /* set the filter cb to the extension when possible */ - if(-1 < (iPos = FILEDLG95_FILETYPE_SearchExt(fodInfos->DlgInfos.hwndFileTypeCB, lpszTemp))) - SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETCURSEL, iPos, 0); - } - /* fall through */ - case ONOPEN_BROWSE: /* browse to the highest folder we could bind to */ - TRACE("ONOPEN_BROWSE\n"); - { - IPersistFolder2 * ppf2; - if(SUCCEEDED(IShellFolder_QueryInterface( lpsf, &IID_IPersistFolder2, (LPVOID*)&ppf2))) - { - LPITEMIDLIST pidlCurrent; - IPersistFolder2_GetCurFolder(ppf2, &pidlCurrent); - IPersistFolder2_Release(ppf2); - if (!ILIsEqual(pidlCurrent, fodInfos->ShellInfos.pidlAbsCurrent)) - { - if (SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser, pidlCurrent, SBSP_ABSOLUTE)) - && fodInfos->ofnInfos->Flags & OFN_EXPLORER) - { - SendCustomDlgNotificationMessage(hwnd, CDN_FOLDERCHANGE); - SendMessageA(fodInfos->DlgInfos.hwndFileName, WM_SETTEXT, 0, (LPARAM)""); - } - } - else if( nOpenAction == ONOPEN_SEARCH ) - { - if (fodInfos->Shell.FOIShellView) - IShellView_Refresh(fodInfos->Shell.FOIShellView); - } - ILFree(pidlCurrent); - if (filename_is_edit( fodInfos )) - SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1); - else - { - HWND hwnd; - - hwnd = (HWND)SendMessageA(fodInfos->DlgInfos.hwndFileName, CBEM_GETEDITCONTROL, 0, 0); - SendMessageW(hwnd, EM_SETSEL, 0, -1); - } - } - } - ret = FALSE; - break; - case ONOPEN_OPEN: /* fill in the return struct and close the dialog */ - TRACE("ONOPEN_OPEN %s\n", debugstr_w(lpstrPathAndFile)); - { - WCHAR *ext = NULL; - - /* update READONLY check box flag */ - if ((SendMessageW(GetDlgItem(hwnd,IDC_OPENREADONLY),BM_GETCHECK,0,0) & 0x03) == BST_CHECKED) - fodInfos->ofnInfos->Flags |= OFN_READONLY; - else - fodInfos->ofnInfos->Flags &= ~OFN_READONLY; - - /* Attach the file extension with file name*/ - ext = PathFindExtensionW(lpstrPathAndFile); - if (! *ext && fodInfos->defext) - { - /* if no extension is specified with file name, then */ - /* attach the extension from file filter or default one */ - - WCHAR *filterExt = NULL; - LPWSTR lpstrFilter = NULL; - int PathLength = lstrlenW(lpstrPathAndFile); - - /*Get the file extension from file type filter*/ - lpstrFilter = (LPWSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB, - fodInfos->ofnInfos->nFilterIndex-1); - - if (lpstrFilter != (LPWSTR)CB_ERR) /* control is not empty */ - { - WCHAR* filterSearchIndex; - filterExt = heap_alloc((lstrlenW(lpstrFilter) + 1) * sizeof(WCHAR)); - lstrcpyW(filterExt, lpstrFilter); - - /* if a semicolon-separated list of file extensions was given, do not include the - semicolon or anything after it in the extension. - example: if filterExt was "*.abc;*.def", it will become "*.abc" */ - filterSearchIndex = wcschr(filterExt, ';'); - if (filterSearchIndex) - { - filterSearchIndex[0] = '\0'; - } - - /* find the file extension by searching for the first dot in filterExt */ - /* strip the * or anything else from the extension, "*.abc" becomes "abc" */ - /* if the extension is invalid or contains a glob, ignore it */ - filterSearchIndex = wcschr(filterExt, '.'); - if (filterSearchIndex++ && !wcschr(filterSearchIndex, '*') && !wcschr(filterSearchIndex, '?')) - { - lstrcpyW(filterExt, filterSearchIndex); - } - else - { - heap_free(filterExt); - filterExt = NULL; - } - } - - if (!filterExt) - { - /* use the default file extension */ - filterExt = heap_alloc((lstrlenW(fodInfos->defext) + 1) * sizeof(WCHAR)); - lstrcpyW(filterExt, fodInfos->defext); - } - - if (*filterExt) /* ignore filterExt="" */ - { - /* Attach the dot*/ - lstrcatW(lpstrPathAndFile, L"."); - /* Attach the extension */ - lstrcatW(lpstrPathAndFile, filterExt); - } - - heap_free(filterExt); - - /* In Open dialog: if file does not exist try without extension */ - if (!(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG) && !PathFileExistsW(lpstrPathAndFile)) - lpstrPathAndFile[PathLength] = '\0'; - - /* Set/clear the output OFN_EXTENSIONDIFFERENT flag */ - if (*ext) - ext++; - if (!lstrcmpiW(fodInfos->defext, ext)) - fodInfos->ofnInfos->Flags &= ~OFN_EXTENSIONDIFFERENT; - else - fodInfos->ofnInfos->Flags |= OFN_EXTENSIONDIFFERENT; - } - - /* In Save dialog: check if the file already exists */ - if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG - && fodInfos->ofnInfos->Flags & OFN_OVERWRITEPROMPT - && PathFileExistsW(lpstrPathAndFile)) - { - WCHAR lpstrOverwrite[100]; - int answer; - - LoadStringW(COMDLG32_hInstance, IDS_OVERWRITEFILE, lpstrOverwrite, 100); - answer = MessageBoxW(hwnd, lpstrOverwrite, fodInfos->title, - MB_YESNO | MB_ICONEXCLAMATION); - if (answer == IDNO || answer == IDCANCEL) - { - ret = FALSE; - goto ret; - } - } - - /* In Open dialog: check if it should be created if it doesn't exist */ - if (!(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG) - && fodInfos->ofnInfos->Flags & OFN_CREATEPROMPT - && !PathFileExistsW(lpstrPathAndFile)) - { - WCHAR lpstrCreate[100]; - int answer; - - LoadStringW(COMDLG32_hInstance, IDS_CREATEFILE, lpstrCreate, 100); - answer = MessageBoxW(hwnd, lpstrCreate, fodInfos->title, - MB_YESNO | MB_ICONEXCLAMATION); - if (answer == IDNO || answer == IDCANCEL) - { - ret = FALSE; - goto ret; - } - } - - /* Check that the size of the file does not exceed buffer size. - (Allow for extra \0 if OFN_MULTISELECT is set.) */ - if(lstrlenW(lpstrPathAndFile) < fodInfos->ofnInfos->nMaxFile - - ((fodInfos->ofnInfos->Flags & OFN_ALLOWMULTISELECT) ? 1 : 0)) - { - - /* fill destination buffer */ - if (fodInfos->ofnInfos->lpstrFile) - { - if(fodInfos->unicode) - { - LPOPENFILENAMEW ofn = fodInfos->ofnInfos; - - lstrcpynW(ofn->lpstrFile, lpstrPathAndFile, ofn->nMaxFile); - if (ofn->Flags & OFN_ALLOWMULTISELECT) - ofn->lpstrFile[lstrlenW(ofn->lpstrFile) + 1] = '\0'; - } - else - { - LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)fodInfos->ofnInfos; - - WideCharToMultiByte(CP_ACP, 0, lpstrPathAndFile, -1, - ofn->lpstrFile, ofn->nMaxFile, NULL, NULL); - if (ofn->Flags & OFN_ALLOWMULTISELECT) - ofn->lpstrFile[lstrlenA(ofn->lpstrFile) + 1] = '\0'; - } - } - - if(fodInfos->unicode) - { - LPWSTR lpszTemp; - - /* set filename offset */ - lpszTemp = PathFindFileNameW(lpstrPathAndFile); - fodInfos->ofnInfos->nFileOffset = (lpszTemp - lpstrPathAndFile); - - /* set extension offset */ - lpszTemp = PathFindExtensionW(lpstrPathAndFile); - fodInfos->ofnInfos->nFileExtension = (*lpszTemp) ? (lpszTemp - lpstrPathAndFile) + 1 : 0; - } - else - { - LPSTR lpszTemp; - CHAR tempFileA[MAX_PATH]; - - /* avoid using fodInfos->ofnInfos->lpstrFile since it can be NULL */ - WideCharToMultiByte(CP_ACP, 0, lpstrPathAndFile, -1, - tempFileA, sizeof(tempFileA), NULL, NULL); - - /* set filename offset */ - lpszTemp = PathFindFileNameA(tempFileA); - fodInfos->ofnInfos->nFileOffset = (lpszTemp - tempFileA); - - /* set extension offset */ - lpszTemp = PathFindExtensionA(tempFileA); - fodInfos->ofnInfos->nFileExtension = (*lpszTemp) ? (lpszTemp - tempFileA) + 1 : 0; - } - - /* set the lpstrFileTitle */ - if(fodInfos->ofnInfos->lpstrFileTitle) - { - LPWSTR lpstrFileTitle = PathFindFileNameW(lpstrPathAndFile); - if(fodInfos->unicode) - { - LPOPENFILENAMEW ofn = fodInfos->ofnInfos; - lstrcpynW(ofn->lpstrFileTitle, lpstrFileTitle, ofn->nMaxFileTitle); - } - else - { - LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)fodInfos->ofnInfos; - WideCharToMultiByte(CP_ACP, 0, lpstrFileTitle, -1, - ofn->lpstrFileTitle, ofn->nMaxFileTitle, NULL, NULL); - } - } - - /* copy currently selected filter to lpstrCustomFilter */ - if (fodInfos->ofnInfos->lpstrCustomFilter) - { - LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)fodInfos->ofnInfos; - int len = WideCharToMultiByte(CP_ACP, 0, fodInfos->ShellInfos.lpstrCurrentFilter, -1, - NULL, 0, NULL, NULL); - if (len + strlen(ofn->lpstrCustomFilter) + 1 <= ofn->nMaxCustFilter) - { - LPSTR s = ofn->lpstrCustomFilter; - s += strlen(ofn->lpstrCustomFilter)+1; - WideCharToMultiByte(CP_ACP, 0, fodInfos->ShellInfos.lpstrCurrentFilter, -1, - s, len, NULL, NULL); - } - } - - - if ( !FILEDLG95_SendFileOK(hwnd, fodInfos) ) - goto ret; - - FILEDLG95_MRU_save_filename(lpstrPathAndFile); - - TRACE("close\n"); - FILEDLG95_Clean(hwnd); - ret = EndDialog(hwnd, TRUE); - } - else - { - WORD size; - - size = lstrlenW(lpstrPathAndFile) + 1; - if (fodInfos->ofnInfos->Flags & OFN_ALLOWMULTISELECT) - size += 1; - /* return needed size in first two bytes of lpstrFile */ - if(fodInfos->ofnInfos->lpstrFile) - *(WORD *)fodInfos->ofnInfos->lpstrFile = size; - FILEDLG95_Clean(hwnd); - ret = EndDialog(hwnd, FALSE); - COMDLG32_SetCommDlgExtendedError(FNERR_BUFFERTOOSMALL); - } - } - break; - } - -ret: - if(lpsf) IShellFolder_Release(lpsf); - return ret; -} - -/*********************************************************************** - * FILEDLG95_SHELL_Init - * - * Initialisation of the shell objects - */ -static LRESULT FILEDLG95_SHELL_Init(HWND hwnd) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - - TRACE("%p\n", hwnd); - - /* - * Initialisation of the FileOpenDialogInfos structure - */ - - /* Shell */ - - /*ShellInfos */ - fodInfos->ShellInfos.hwndOwner = hwnd; - - /* Disable multi-select if flag not set */ - if (!(fodInfos->ofnInfos->Flags & OFN_ALLOWMULTISELECT)) - { - fodInfos->ShellInfos.folderSettings.fFlags |= FWF_SINGLESEL; - } - fodInfos->ShellInfos.folderSettings.fFlags |= FWF_AUTOARRANGE | FWF_ALIGNLEFT; - fodInfos->ShellInfos.folderSettings.ViewMode = FVM_LIST; - - /* Construct the IShellBrowser interface */ - fodInfos->Shell.FOIShellBrowser = IShellBrowserImpl_Construct(hwnd); - - return NOERROR; -} - -/*********************************************************************** - * FILEDLG95_SHELL_ExecuteCommand - * - * Change the folder option and refresh the view - * If the function succeeds, the return value is nonzero. - */ -static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - IContextMenu * pcm; - - TRACE("(%p,%p)\n", hwnd, lpVerb); - - if(SUCCEEDED(IShellView_GetItemObject(fodInfos->Shell.FOIShellView, - SVGIO_BACKGROUND, - &IID_IContextMenu, - (LPVOID*)&pcm))) - { - CMINVOKECOMMANDINFO ci; - ZeroMemory(&ci, sizeof(CMINVOKECOMMANDINFO)); - ci.cbSize = sizeof(CMINVOKECOMMANDINFO); - ci.lpVerb = lpVerb; - ci.hwnd = hwnd; - - IContextMenu_InvokeCommand(pcm, &ci); - IContextMenu_Release(pcm); - } - - return FALSE; -} - -/*********************************************************************** - * FILEDLG95_SHELL_UpFolder - * - * Browse to the specified object - * If the function succeeds, the return value is nonzero. - */ -static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - - TRACE("\n"); - - if(SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser, - NULL, - SBSP_PARENT))) - { - if(fodInfos->ofnInfos->Flags & OFN_EXPLORER) - SendCustomDlgNotificationMessage(hwnd, CDN_FOLDERCHANGE); - return TRUE; - } - return FALSE; -} -/*********************************************************************** - * FILEDLG95_SHELL_Clean - * - * Cleans the memory used by shell objects - */ -static void FILEDLG95_SHELL_Clean(HWND hwnd) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - - TRACE("\n"); - - ILFree(fodInfos->ShellInfos.pidlAbsCurrent); - - /* clean Shell interfaces */ - if (fodInfos->Shell.FOIShellView) - { - IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView); - IShellView_Release(fodInfos->Shell.FOIShellView); - } - if (fodInfos->Shell.FOIShellFolder) - IShellFolder_Release(fodInfos->Shell.FOIShellFolder); - IShellBrowser_Release(fodInfos->Shell.FOIShellBrowser); - if (fodInfos->Shell.FOIDataObject) - IDataObject_Release(fodInfos->Shell.FOIDataObject); -} - -/*********************************************************************** - * FILEDLG95_FILETYPE_Init - * - * Initialisation of the file type combo box - */ -static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - int nFilters = 0; /* number of filters */ - int nFilterIndexCB; - - TRACE("%p\n", hwnd); - - if(fodInfos->customfilter) - { - /* customfilter has one entry... title\0ext\0 - * Set first entry of combo box item with customfilter - */ - LPWSTR lpstrExt; - LPCWSTR lpstrPos = fodInfos->customfilter; - - /* Get the title */ - lpstrPos += lstrlenW(fodInfos->customfilter) + 1; - - /* Copy the extensions */ - if (! *lpstrPos) return E_FAIL; /* malformed filter */ - if (!(lpstrExt = heap_alloc((lstrlenW(lpstrPos)+1)*sizeof(WCHAR)))) return E_FAIL; - lstrcpyW(lpstrExt,lpstrPos); - - /* Add the item at the end of the combo */ - SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_ADDSTRING, 0, (LPARAM)fodInfos->customfilter); - SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETITEMDATA, nFilters, (LPARAM)lpstrExt); - - nFilters++; - } - if(fodInfos->filter) - { - LPCWSTR lpstrPos = fodInfos->filter; - - for(;;) - { - /* filter is a list... title\0ext\0......\0\0 - * Set the combo item text to the title and the item data - * to the ext - */ - LPCWSTR lpstrDisplay; - LPWSTR lpstrExt; - - /* Get the title */ - if(! *lpstrPos) break; /* end */ - lpstrDisplay = lpstrPos; - lpstrPos += lstrlenW(lpstrPos) + 1; - - SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_ADDSTRING, 0, (LPARAM)lpstrDisplay); - - nFilters++; - - /* Copy the extensions */ - if (!(lpstrExt = heap_alloc((lstrlenW(lpstrPos)+1)*sizeof(WCHAR)))) return E_FAIL; - lstrcpyW(lpstrExt,lpstrPos); - lpstrPos += lstrlenW(lpstrPos) + 1; - - /* Add the item at the end of the combo */ - SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETITEMDATA, nFilters - 1, (LPARAM)lpstrExt); - - /* malformed filters are added anyway... */ - if (!*lpstrExt) break; - } - } - - /* - * Set the current filter to the one specified - * in the initialisation structure - */ - if (fodInfos->filter || fodInfos->customfilter) - { - LPWSTR lpstrFilter; - - /* Check to make sure our index isn't out of bounds. */ - if ( fodInfos->ofnInfos->nFilterIndex > - nFilters - (fodInfos->customfilter == NULL ? 0 : 1) ) - fodInfos->ofnInfos->nFilterIndex = (fodInfos->customfilter == NULL ? 1 : 0); - - /* set default filter index */ - if(fodInfos->ofnInfos->nFilterIndex == 0 && fodInfos->customfilter == NULL) - fodInfos->ofnInfos->nFilterIndex = 1; - - /* calculate index of Combo Box item */ - nFilterIndexCB = fodInfos->ofnInfos->nFilterIndex; - if (fodInfos->customfilter == NULL) - nFilterIndexCB--; - - /* Set the current index selection. */ - SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETCURSEL, nFilterIndexCB, 0); - - /* Get the corresponding text string from the combo box. */ - lpstrFilter = (LPWSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB, - nFilterIndexCB); - - if ((INT_PTR)lpstrFilter == CB_ERR) /* control is empty */ - lpstrFilter = NULL; - - if(lpstrFilter) - { - DWORD len; - CharLowerW(lpstrFilter); /* lowercase */ - len = lstrlenW(lpstrFilter)+1; - fodInfos->ShellInfos.lpstrCurrentFilter = heap_alloc( len * sizeof(WCHAR) ); - lstrcpyW(fodInfos->ShellInfos.lpstrCurrentFilter,lpstrFilter); - } - } else - fodInfos->ofnInfos->nFilterIndex = 0; - return S_OK; -} - -/*********************************************************************** - * FILEDLG95_FILETYPE_OnCommand - * - * WM_COMMAND of the file type combo box - * If the function succeeds, the return value is nonzero. - */ -static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - - switch(wNotifyCode) - { - case CBN_SELENDOK: - { - LPWSTR lpstrFilter; - - /* Get the current item of the filetype combo box */ - int iItem = SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_GETCURSEL, 0, 0); - - /* set the current filter index */ - fodInfos->ofnInfos->nFilterIndex = iItem + - (fodInfos->customfilter == NULL ? 1 : 0); - - /* Set the current filter with the current selection */ - heap_free(fodInfos->ShellInfos.lpstrCurrentFilter); - - lpstrFilter = (LPWSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB, - iItem); - if((INT_PTR)lpstrFilter != CB_ERR) - { - DWORD len; - CharLowerW(lpstrFilter); /* lowercase */ - len = lstrlenW(lpstrFilter)+1; - fodInfos->ShellInfos.lpstrCurrentFilter = heap_alloc( len * sizeof(WCHAR) ); - lstrcpyW(fodInfos->ShellInfos.lpstrCurrentFilter,lpstrFilter); - if(fodInfos->ofnInfos->Flags & OFN_EXPLORER) - SendCustomDlgNotificationMessage(hwnd,CDN_TYPECHANGE); - } - - /* Refresh the actual view to display the included items*/ - if (fodInfos->Shell.FOIShellView) - IShellView_Refresh(fodInfos->Shell.FOIShellView); - } - } - return FALSE; -} -/*********************************************************************** - * FILEDLG95_FILETYPE_SearchExt - * - * searches for an extension in the filetype box - */ -static int FILEDLG95_FILETYPE_SearchExt(HWND hwnd,LPCWSTR lpstrExt) -{ - int i, iCount; - - iCount = SendMessageW(hwnd, CB_GETCOUNT, 0, 0); - - TRACE("%s\n", debugstr_w(lpstrExt)); - - if(iCount != CB_ERR) - { - for(i=0;iDlgInfos.hwndFileTypeCB, CB_GETCOUNT, 0, 0); - - TRACE("\n"); - - /* Delete each string of the combo and their associated data */ - if(iCount != CB_ERR) - { - for(iPos = iCount-1;iPos>=0;iPos--) - { - heap_free((void *)CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,iPos)); - SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_DELETESTRING, iPos, 0); - } - } - /* Current filter */ - heap_free(fodInfos->ShellInfos.lpstrCurrentFilter); -} - -/*********************************************************************** - * FILEDLG95_LOOKIN_Init - * - * Initialisation of the look in combo box - */ - -/* Small helper function, to determine if the unixfs shell extension is rooted - * at the desktop. Copied from dlls/shell32/shfldr_unixfs.c. - */ -static inline BOOL FILEDLG95_unixfs_is_rooted_at_desktop(void) { - HKEY hKey; - - if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, - L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\NameSpace\\{9D20AAE8-0625-44B0-9CA7-71889C2254D9}", 0, KEY_READ, &hKey) != ERROR_SUCCESS) - return FALSE; - - RegCloseKey(hKey); - return TRUE; -} - -static void FILEDLG95_LOOKIN_Init(HWND hwndCombo) -{ - IShellFolder *psfRoot, *psfDrives; - IEnumIDList *lpeRoot, *lpeDrives; - LPITEMIDLIST pidlDrives, pidlTmp, pidlTmp1, pidlAbsTmp; - HDC hdc; - TEXTMETRICW tm; - LookInInfos *liInfos = heap_alloc_zero(sizeof(*liInfos)); - - TRACE("%p\n", hwndCombo); - - liInfos->iMaxIndentation = 0; - - SetPropA(hwndCombo, LookInInfosStr, liInfos); - - hdc = GetDC( hwndCombo ); - SelectObject( hdc, (HFONT)SendMessageW( hwndCombo, WM_GETFONT, 0, 0 )); - GetTextMetricsW( hdc, &tm ); - ReleaseDC( hwndCombo, hdc ); - - /* set item height for both text field and listbox */ - SendMessageW(hwndCombo, CB_SETITEMHEIGHT, -1, max(tm.tmHeight, GetSystemMetrics(SM_CYSMICON))); - SendMessageW(hwndCombo, CB_SETITEMHEIGHT, 0, max(tm.tmHeight, GetSystemMetrics(SM_CYSMICON))); - - /* Turn on the extended UI for the combo box like Windows does */ - SendMessageW(hwndCombo, CB_SETEXTENDEDUI, TRUE, 0); - - /* Initialise data of Desktop folder */ - SHGetSpecialFolderLocation(0,CSIDL_DESKTOP,&pidlTmp); - FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlTmp,LISTEND); - ILFree(pidlTmp); - - SHGetSpecialFolderLocation(0,CSIDL_DRIVES,&pidlDrives); - - SHGetDesktopFolder(&psfRoot); - - if (psfRoot) - { - /* enumerate the contents of the desktop */ - if(SUCCEEDED(IShellFolder_EnumObjects(psfRoot, hwndCombo, SHCONTF_FOLDERS, &lpeRoot))) - { - while (S_OK == IEnumIDList_Next(lpeRoot, 1, &pidlTmp, NULL)) - { - FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlTmp,LISTEND); - - /* If the unixfs extension is rooted, we don't expand the drives by default */ - if (!FILEDLG95_unixfs_is_rooted_at_desktop()) - { - /* special handling for CSIDL_DRIVES */ - if (ILIsEqual(pidlTmp, pidlDrives)) - { - if(SUCCEEDED(IShellFolder_BindToObject(psfRoot, pidlTmp, NULL, &IID_IShellFolder, (LPVOID*)&psfDrives))) - { - /* enumerate the drives */ - if(SUCCEEDED(IShellFolder_EnumObjects(psfDrives, hwndCombo,SHCONTF_FOLDERS, &lpeDrives))) - { - while (S_OK == IEnumIDList_Next(lpeDrives, 1, &pidlTmp1, NULL)) - { - pidlAbsTmp = ILCombine(pidlTmp, pidlTmp1); - FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlAbsTmp,LISTEND); - ILFree(pidlAbsTmp); - ILFree(pidlTmp1); - } - IEnumIDList_Release(lpeDrives); - } - IShellFolder_Release(psfDrives); - } - } - } - - ILFree(pidlTmp); - } - IEnumIDList_Release(lpeRoot); - } - IShellFolder_Release(psfRoot); - } - - ILFree(pidlDrives); -} - -/*********************************************************************** - * FILEDLG95_LOOKIN_DrawItem - * - * WM_DRAWITEM message handler - */ -static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct) -{ - COLORREF crWin = GetSysColor(COLOR_WINDOW); - COLORREF crHighLight = GetSysColor(COLOR_HIGHLIGHT); - COLORREF crText = GetSysColor(COLOR_WINDOWTEXT); - RECT rectText; - RECT rectIcon; - SHFILEINFOW sfi; - HIMAGELIST ilItemImage; - int iIndentation; - TEXTMETRICW tm; - LPSFOLDER tmpFolder; - UINT shgfi_flags = SHGFI_PIDL | SHGFI_OPENICON | SHGFI_SYSICONINDEX | SHGFI_DISPLAYNAME; - UINT icon_width, icon_height; - - TRACE("\n"); - - if(pDIStruct->itemID == -1) - return 0; - - if(!(tmpFolder = (LPSFOLDER) CBGetItemDataPtr(pDIStruct->hwndItem, - pDIStruct->itemID))) - return 0; - - - icon_width = GetSystemMetrics(SM_CXICON); - icon_height = GetSystemMetrics(SM_CYICON); - if (pDIStruct->rcItem.bottom - pDIStruct->rcItem.top < icon_height) - { - icon_width = GetSystemMetrics(SM_CXSMICON); - icon_height = GetSystemMetrics(SM_CYSMICON); - shgfi_flags |= SHGFI_SMALLICON; - } - - ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem, - 0, &sfi, sizeof (sfi), shgfi_flags ); - - /* Is this item selected ? */ - if(pDIStruct->itemState & ODS_SELECTED) - { - SetTextColor(pDIStruct->hDC,(0x00FFFFFF & ~(crText))); - SetBkColor(pDIStruct->hDC,crHighLight); - FillRect(pDIStruct->hDC,&pDIStruct->rcItem,GetSysColorBrush(COLOR_HIGHLIGHT)); - } - else - { - SetTextColor(pDIStruct->hDC,crText); - SetBkColor(pDIStruct->hDC,crWin); - FillRect(pDIStruct->hDC,&pDIStruct->rcItem,GetSysColorBrush(COLOR_WINDOW)); - } - - /* Do not indent item if drawing in the edit of the combo */ - if(pDIStruct->itemState & ODS_COMBOBOXEDIT) - iIndentation = 0; - else - iIndentation = tmpFolder->m_iIndent; - - /* Draw text and icon */ - - /* Initialise the icon display area */ - rectIcon.left = pDIStruct->rcItem.left + 1 + icon_width/2 * iIndentation; - rectIcon.top = (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom - icon_height) / 2; - rectIcon.right = rectIcon.left + icon_width + XTEXTOFFSET; - rectIcon.bottom = (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom + icon_height) / 2; - - /* Initialise the text display area */ - GetTextMetricsW(pDIStruct->hDC, &tm); - rectText.left = rectIcon.right; - rectText.top = - (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom - tm.tmHeight) / 2; - rectText.right = pDIStruct->rcItem.right; - rectText.bottom = - (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom + tm.tmHeight) / 2; - - /* Draw the icon from the image list */ - ImageList_Draw(ilItemImage, - sfi.iIcon, - pDIStruct->hDC, - rectIcon.left, - rectIcon.top, - ILD_TRANSPARENT ); - - /* Draw the associated text */ - TextOutW(pDIStruct->hDC,rectText.left,rectText.top,sfi.szDisplayName,lstrlenW(sfi.szDisplayName)); - return NOERROR; -} - -/*********************************************************************** - * FILEDLG95_LOOKIN_OnCommand - * - * LookIn combo box WM_COMMAND message handler - * If the function succeeds, the return value is nonzero. - */ -static BOOL FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - - TRACE("%p\n", fodInfos); - - switch(wNotifyCode) - { - case CBN_SELENDOK: - { - LPSFOLDER tmpFolder; - int iItem; - - iItem = SendMessageW(fodInfos->DlgInfos.hwndLookInCB, CB_GETCURSEL, 0, 0); - - if( iItem == CB_ERR) return FALSE; - - if(!(tmpFolder = (LPSFOLDER) CBGetItemDataPtr(fodInfos->DlgInfos.hwndLookInCB, - iItem))) - return FALSE; - - - if(SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser, - tmpFolder->pidlItem, - SBSP_ABSOLUTE))) - { - if(fodInfos->ofnInfos->Flags & OFN_EXPLORER) - SendCustomDlgNotificationMessage(hwnd, CDN_FOLDERCHANGE); - return TRUE; - } - break; - } - - } - return FALSE; -} - -/*********************************************************************** - * FILEDLG95_LOOKIN_AddItem - * - * Adds an absolute pidl item to the lookin combo box - * returns the index of the inserted item - */ -static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId) -{ - LPITEMIDLIST pidlNext; - SHFILEINFOW sfi; - SFOLDER *tmpFolder; - LookInInfos *liInfos; - - TRACE("%p, %p, %d\n", hwnd, pidl, iInsertId); - - if(!pidl) - return -1; - - if(!(liInfos = GetPropA(hwnd,LookInInfosStr))) - return -1; - - tmpFolder = heap_alloc_zero(sizeof(*tmpFolder)); - tmpFolder->m_iIndent = 0; - - /* Calculate the indentation of the item in the lookin*/ - pidlNext = pidl; - while ((pidlNext = ILGetNext(pidlNext))) - { - tmpFolder->m_iIndent++; - } - - tmpFolder->pidlItem = ILClone(pidl); - - if(tmpFolder->m_iIndent > liInfos->iMaxIndentation) - liInfos->iMaxIndentation = tmpFolder->m_iIndent; - - sfi.dwAttributes = SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM; - SHGetFileInfoW((LPCWSTR)pidl, - 0, - &sfi, - sizeof(sfi), - SHGFI_DISPLAYNAME | SHGFI_PIDL | SHGFI_ATTRIBUTES | SHGFI_ATTR_SPECIFIED); - - TRACE("-- Add %s attr=0x%08lx\n", debugstr_w(sfi.szDisplayName), sfi.dwAttributes); - - if((sfi.dwAttributes & SFGAO_FILESYSANCESTOR) || (sfi.dwAttributes & SFGAO_FILESYSTEM)) - { - int iItemID; - - TRACE("-- Add %s at %u\n", debugstr_w(sfi.szDisplayName), tmpFolder->m_iIndent); - - /* Add the item at the end of the list */ - if(iInsertId < 0) - { - iItemID = SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)sfi.szDisplayName); - } - /* Insert the item at the iInsertId position*/ - else - { - iItemID = SendMessageW(hwnd, CB_INSERTSTRING, iInsertId, (LPARAM)sfi.szDisplayName); - } - - SendMessageW(hwnd, CB_SETITEMDATA, iItemID, (LPARAM)tmpFolder); - return iItemID; - } - - ILFree( tmpFolder->pidlItem ); - heap_free( tmpFolder ); - return -1; - -} - -/*********************************************************************** - * FILEDLG95_LOOKIN_InsertItemAfterParent - * - * Insert an item below its parent - */ -static int FILEDLG95_LOOKIN_InsertItemAfterParent(HWND hwnd,LPITEMIDLIST pidl) -{ - - LPITEMIDLIST pidlParent = GetParentPidl(pidl); - int iParentPos; - - TRACE("\n"); - - if (pidl == pidlParent) - return -1; - - iParentPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)pidlParent,SEARCH_PIDL); - - if(iParentPos < 0) - { - iParentPos = FILEDLG95_LOOKIN_InsertItemAfterParent(hwnd,pidlParent); - } - - ILFree(pidlParent); - - return FILEDLG95_LOOKIN_AddItem(hwnd,pidl,iParentPos + 1); -} - -/*********************************************************************** - * FILEDLG95_LOOKIN_SelectItem - * - * Adds an absolute pidl item to the lookin combo box - * returns the index of the inserted item - */ -int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl) -{ - int iItemPos; - LookInInfos *liInfos; - - TRACE("%p, %p\n", hwnd, pidl); - - iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)pidl,SEARCH_PIDL); - - liInfos = GetPropA(hwnd,LookInInfosStr); - - if(iItemPos < 0) - { - while(FILEDLG95_LOOKIN_RemoveMostExpandedItem(hwnd) > -1); - iItemPos = FILEDLG95_LOOKIN_InsertItemAfterParent(hwnd,pidl); - } - - else - { - SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,iItemPos); - while(liInfos->iMaxIndentation > tmpFolder->m_iIndent) - { - int iRemovedItem; - - if(-1 == (iRemovedItem = FILEDLG95_LOOKIN_RemoveMostExpandedItem(hwnd))) - break; - if(iRemovedItem < iItemPos) - iItemPos--; - } - } - - SendMessageW(hwnd, CB_SETCURSEL, iItemPos, 0); - liInfos->uSelectedItem = iItemPos; - - return 0; - -} - -/*********************************************************************** - * FILEDLG95_LOOKIN_RemoveMostExpandedItem - * - * Remove the item with an expansion level over iExpansionLevel - */ -static int FILEDLG95_LOOKIN_RemoveMostExpandedItem(HWND hwnd) -{ - int iItemPos; - LookInInfos *liInfos = GetPropA(hwnd,LookInInfosStr); - - TRACE("\n"); - - if(liInfos->iMaxIndentation <= 2) - return -1; - - if((iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,liInfos->iMaxIndentation,SEARCH_EXP)) >=0) - { - SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,iItemPos); - ILFree(tmpFolder->pidlItem); - heap_free(tmpFolder); - SendMessageW(hwnd, CB_DELETESTRING, iItemPos, 0); - liInfos->iMaxIndentation--; - - return iItemPos; - } - - return -1; -} - -/*********************************************************************** - * FILEDLG95_LOOKIN_SearchItem - * - * Search for pidl in the lookin combo box - * returns the index of the found item - */ -static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMethod) -{ - int i = 0; - int iCount; - - iCount = SendMessageW(hwnd, CB_GETCOUNT, 0, 0); - - TRACE("0x%08Ix 0x%x\n",searchArg, iSearchMethod); - - if (iCount != CB_ERR) - { - for(;ipidlItem)) - return i; - if(iSearchMethod == SEARCH_EXP && tmpFolder->m_iIndent == (int)searchArg) - return i; - } - } - - return -1; -} - -/*********************************************************************** - * FILEDLG95_LOOKIN_Clean - * - * Clean the memory used by the lookin combo box - */ -static void FILEDLG95_LOOKIN_Clean(HWND hwnd) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - LookInInfos *liInfos = GetPropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr); - int iPos, iCount; - - iCount = SendMessageW(fodInfos->DlgInfos.hwndLookInCB, CB_GETCOUNT, 0, 0); - - TRACE("\n"); - - /* Delete each string of the combo and their associated data */ - if (iCount != CB_ERR) - { - for(iPos = iCount-1;iPos>=0;iPos--) - { - SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(fodInfos->DlgInfos.hwndLookInCB,iPos); - ILFree(tmpFolder->pidlItem); - heap_free(tmpFolder); - SendMessageW(fodInfos->DlgInfos.hwndLookInCB, CB_DELETESTRING, iPos, 0); - } - } - - /* LookInInfos structure */ - heap_free(liInfos); - RemovePropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr); -} - -/*********************************************************************** - * get_def_format - * - * Fill the FORMATETC used in the shell id list - */ -static FORMATETC get_def_format(void) -{ - static CLIPFORMAT cfFormat; - FORMATETC formatetc; - - if (!cfFormat) cfFormat = RegisterClipboardFormatA(CFSTR_SHELLIDLISTA); - formatetc.cfFormat = cfFormat; - formatetc.ptd = 0; - formatetc.dwAspect = DVASPECT_CONTENT; - formatetc.lindex = -1; - formatetc.tymed = TYMED_HGLOBAL; - return formatetc; -} - -/*********************************************************************** - * FILEDLG95_FILENAME_FillFromSelection - * - * fills the edit box from the cached DataObject - */ -void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - LPITEMIDLIST pidl; - LPWSTR lpstrAllFiles, lpstrTmp; - UINT nFiles = 0, nFileToOpen, nFileSelected, nAllFilesLength = 0, nThisFileLength, nAllFilesMaxLength; - STGMEDIUM medium; - LPIDA cida; - FORMATETC formatetc = get_def_format(); - - TRACE("\n"); - - if (FAILED(IDataObject_GetData(fodInfos->Shell.FOIDataObject, &formatetc, &medium))) - return; - - cida = GlobalLock(medium.u.hGlobal); - nFileSelected = cida->cidl; - - /* Allocate a buffer */ - nAllFilesMaxLength = MAX_PATH + 3; - lpstrAllFiles = heap_alloc_zero(nAllFilesMaxLength * sizeof(WCHAR)); - if (!lpstrAllFiles) - goto ret; - - /* Loop through the selection, handle only files (not folders) */ - for (nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++) - { - pidl = (LPITEMIDLIST)((LPBYTE)cida + cida->aoffset[nFileToOpen + 1]); - if (pidl) - { - if (!IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl)) - { - if (nAllFilesLength + MAX_PATH + 3 > nAllFilesMaxLength) - { - nAllFilesMaxLength *= 2; - lpstrTmp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpstrAllFiles, nAllFilesMaxLength * sizeof(WCHAR)); - if (!lpstrTmp) - goto ret; - lpstrAllFiles = lpstrTmp; - } - nFiles += 1; - lpstrAllFiles[nAllFilesLength++] = '"'; - GetName(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, lpstrAllFiles + nAllFilesLength); - nThisFileLength = lstrlenW(lpstrAllFiles + nAllFilesLength); - nAllFilesLength += nThisFileLength; - lpstrAllFiles[nAllFilesLength++] = '"'; - lpstrAllFiles[nAllFilesLength++] = ' '; - } - } - } - - if (nFiles != 0) - { - /* If there's only one file, use the name as-is without quotes */ - lpstrTmp = lpstrAllFiles; - if (nFiles == 1) - { - lpstrTmp += 1; - lpstrTmp[nThisFileLength] = 0; - } - SetWindowTextW(fodInfos->DlgInfos.hwndFileName, lpstrTmp); - /* Select the file name like Windows does */ - if (filename_is_edit(fodInfos)) - SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1); - } - -ret: - heap_free(lpstrAllFiles); - COMCTL32_ReleaseStgMedium(medium); -} - - -/* copied from shell32 to avoid linking to it - * Although shell32 is already linked the behaviour of exported StrRetToStrN - * is dependent on whether emulated OS is unicode or not. - */ -static HRESULT COMDLG32_StrRetToStrNW (LPWSTR dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl) -{ - switch (src->uType) - { - case STRRET_WSTR: - lstrcpynW(dest, src->u.pOleStr, len); - CoTaskMemFree(src->u.pOleStr); - break; - - case STRRET_CSTR: - if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len ) && len) - dest[len-1] = 0; - break; - - case STRRET_OFFSET: - if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, -1, dest, len ) && len) - dest[len-1] = 0; - break; - - default: - FIXME("unknown type %x!\n", src->uType); - if (len) *dest = '\0'; - return E_FAIL; - } - return S_OK; -} - -/*********************************************************************** - * FILEDLG95_FILENAME_GetFileNames - * - * Copies the filenames to a delimited string list. - */ -static int FILEDLG95_FILENAME_GetFileNames (HWND hwnd, LPWSTR * lpstrFileList, UINT * sizeUsed) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - UINT nFileCount = 0; /* number of files */ - UINT nStrLen = 0; /* length of string in edit control */ - LPWSTR lpstrEdit; /* buffer for string from edit control */ - - TRACE("\n"); - - /* get the filenames from the filename control */ - nStrLen = GetWindowTextLengthW( fodInfos->DlgInfos.hwndFileName ); - lpstrEdit = heap_alloc( (nStrLen+1)*sizeof(WCHAR) ); - GetWindowTextW( fodInfos->DlgInfos.hwndFileName, lpstrEdit, nStrLen+1); - - TRACE("nStrLen=%u str=%s\n", nStrLen, debugstr_w(lpstrEdit)); - - nFileCount = COMDLG32_SplitFileNames(lpstrEdit, nStrLen, lpstrFileList, sizeUsed); - heap_free(lpstrEdit); - return nFileCount; -} - -/* - * DATAOBJECT Helper functions - */ - -/*********************************************************************** - * COMCTL32_ReleaseStgMedium - * - * like ReleaseStgMedium from ole32 - */ -static void COMCTL32_ReleaseStgMedium (STGMEDIUM medium) -{ - if(medium.pUnkForRelease) - { - IUnknown_Release(medium.pUnkForRelease); - } - else - { - GlobalUnlock(medium.u.hGlobal); - GlobalFree(medium.u.hGlobal); - } -} - -/*********************************************************************** - * GetPidlFromDataObject - * - * Return pidl(s) by number from the cached DataObject - * - * nPidlIndex=0 gets the fully qualified root path - */ -LPITEMIDLIST GetPidlFromDataObject ( IDataObject *doSelected, UINT nPidlIndex) -{ - - STGMEDIUM medium; - FORMATETC formatetc = get_def_format(); - LPITEMIDLIST pidl = NULL; - - TRACE("sv=%p index=%u\n", doSelected, nPidlIndex); - - if (!doSelected) - return NULL; - - /* Get the pidls from IDataObject */ - if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium))) - { - LPIDA cida = GlobalLock(medium.u.hGlobal); - if(nPidlIndex <= cida->cidl) - { - pidl = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[nPidlIndex]])); - } - COMCTL32_ReleaseStgMedium(medium); - } - return pidl; -} - -/*********************************************************************** - * GetNumSelected - * - * Return the number of selected items in the DataObject. - * -*/ -static UINT GetNumSelected( IDataObject *doSelected ) -{ - UINT retVal = 0; - STGMEDIUM medium; - FORMATETC formatetc = get_def_format(); - - TRACE("sv=%p\n", doSelected); - - if (!doSelected) return 0; - - /* Get the pidls from IDataObject */ - if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium))) - { - LPIDA cida = GlobalLock(medium.u.hGlobal); - retVal = cida->cidl; - COMCTL32_ReleaseStgMedium(medium); - return retVal; - } - return 0; -} - -/* - * TOOLS - */ - -/*********************************************************************** - * GetName - * - * Get the pidl's display name (relative to folder) and - * put it in lpstrFileName. - * - * Return NOERROR on success, - * E_FAIL otherwise - */ - -static HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPWSTR lpstrFileName) -{ - STRRET str; - HRESULT hRes; - - TRACE("sf=%p pidl=%p\n", lpsf, pidl); - - if(!lpsf) - { - SHGetDesktopFolder(&lpsf); - hRes = GetName(lpsf,pidl,dwFlags,lpstrFileName); - IShellFolder_Release(lpsf); - return hRes; - } - - /* Get the display name of the pidl relative to the folder */ - if (SUCCEEDED(hRes = IShellFolder_GetDisplayNameOf(lpsf, pidl, dwFlags, &str))) - { - return COMDLG32_StrRetToStrNW(lpstrFileName, MAX_PATH, &str, pidl); - } - return E_FAIL; -} - -/*********************************************************************** - * GetShellFolderFromPidl - * - * pidlRel is the item pidl relative - * Return the IShellFolder of the absolute pidl - */ -IShellFolder *GetShellFolderFromPidl(LPITEMIDLIST pidlAbs) -{ - IShellFolder *psf = NULL,*psfParent; - - TRACE("%p\n", pidlAbs); - - if(SUCCEEDED(SHGetDesktopFolder(&psfParent))) - { - psf = psfParent; - if(pidlAbs && pidlAbs->mkid.cb) - { - if(SUCCEEDED(IShellFolder_BindToObject(psfParent, pidlAbs, NULL, &IID_IShellFolder, (LPVOID*)&psf))) - { - IShellFolder_Release(psfParent); - return psf; - } - } - /* return the desktop */ - return psfParent; - } - return NULL; -} - -/*********************************************************************** - * GetParentPidl - * - * Return the LPITEMIDLIST to the parent of the pidl in the list - */ -LPITEMIDLIST GetParentPidl(LPITEMIDLIST pidl) -{ - LPITEMIDLIST pidlParent; - - TRACE("%p\n", pidl); - - pidlParent = ILClone(pidl); - ILRemoveLastID(pidlParent); - - return pidlParent; -} - -/*********************************************************************** - * GetPidlFromName - * - * returns the pidl of the file name relative to folder - * NULL if an error occurred - */ -static LPITEMIDLIST GetPidlFromName(IShellFolder *lpsf,LPWSTR lpcstrFileName) -{ - LPITEMIDLIST pidl = NULL; - ULONG ulEaten; - - TRACE("sf=%p file=%s\n", lpsf, debugstr_w(lpcstrFileName)); - - if(!lpcstrFileName) return NULL; - if(!*lpcstrFileName) return NULL; - - if(!lpsf) - { - if (SUCCEEDED(SHGetDesktopFolder(&lpsf))) { - IShellFolder_ParseDisplayName(lpsf, 0, NULL, lpcstrFileName, &ulEaten, &pidl, NULL); - IShellFolder_Release(lpsf); - } - } - else - { - IShellFolder_ParseDisplayName(lpsf, 0, NULL, lpcstrFileName, &ulEaten, &pidl, NULL); - } - return pidl; -} - -/* -*/ -static BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl) -{ - ULONG uAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER; - HRESULT ret; - - TRACE("%p, %p\n", psf, pidl); - - ret = IShellFolder_GetAttributesOf( psf, 1, &pidl, &uAttr ); - - TRACE("-- 0x%08lx 0x%08lx\n", uAttr, ret); - /* see documentation shell 4.1*/ - return uAttr & (SFGAO_FOLDER | SFGAO_HASSUBFOLDER); -} - -/*********************************************************************** - * BrowseSelectedFolder - */ -static BOOL BrowseSelectedFolder(HWND hwnd) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd); - BOOL bBrowseSelFolder = FALSE; - - TRACE("\n"); - - if (GetNumSelected(fodInfos->Shell.FOIDataObject) == 1) - { - LPITEMIDLIST pidlSelection; - - /* get the file selected */ - pidlSelection = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, 1); - if (IsPidlFolder (fodInfos->Shell.FOIShellFolder, pidlSelection)) - { - if ( FAILED( IShellBrowser_BrowseObject( fodInfos->Shell.FOIShellBrowser, - pidlSelection, SBSP_RELATIVE ) ) ) - { - WCHAR buf[64]; - LoadStringW( COMDLG32_hInstance, IDS_PATHNOTEXISTING, buf, ARRAY_SIZE(buf)); - MessageBoxW( hwnd, buf, fodInfos->title, MB_OK | MB_ICONEXCLAMATION ); - } - bBrowseSelFolder = TRUE; - if(fodInfos->ofnInfos->Flags & OFN_EXPLORER) - SendCustomDlgNotificationMessage(hwnd,CDN_FOLDERCHANGE); - } - ILFree( pidlSelection ); - } - - return bBrowseSelFolder; -} - -static inline BOOL valid_struct_size( DWORD size ) -{ - return (size == OPENFILENAME_SIZE_VERSION_400W) || - (size == sizeof( OPENFILENAMEW )); -} - -static inline BOOL is_win16_looks(DWORD flags) -{ - return (flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE) && - !(flags & OFN_EXPLORER)); -} - -/* ------------------ APIs ---------------------- */ - -// /*********************************************************************** - // * GetOpenFileNameA (COMDLG32.@) - // * - // * Creates a dialog box for the user to select a file to open. - // * - // * RETURNS - // * TRUE on success: user enters a valid file - // * FALSE on cancel, error, close or filename-does-not-fit-in-buffer. - // * - // */ -// BOOL WINAPI GetOpenFileNameA(OPENFILENAMEA *ofn) -// { - // TRACE("flags 0x%08lx\n", ofn->Flags); - - // if (!valid_struct_size( ofn->lStructSize )) - // { - // COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE ); - // return FALSE; - // } - - // /* OFN_FILEMUSTEXIST implies OFN_PATHMUSTEXIST */ - // if (ofn->Flags & OFN_FILEMUSTEXIST) - // ofn->Flags |= OFN_PATHMUSTEXIST; - - // if (is_win16_looks(ofn->Flags)) - // return GetFileName31A(ofn, OPEN_DIALOG); - // else - // { - // FileOpenDlgInfos info; - - // init_filedlg_infoA(ofn, &info); - // return GetFileDialog95(&info, OPEN_DIALOG); - // } -// } - -// /*********************************************************************** - // * GetOpenFileNameW (COMDLG32.@) - // * - // * Creates a dialog box for the user to select a file to open. - // * - // * RETURNS - // * TRUE on success: user enters a valid file - // * FALSE on cancel, error, close or filename-does-not-fit-in-buffer. - // * - // */ -// BOOL WINAPI GetOpenFileNameW(OPENFILENAMEW *ofn) -// { - // TRACE("flags 0x%08lx\n", ofn->Flags); - - // if (!valid_struct_size( ofn->lStructSize )) - // { - // COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE ); - // return FALSE; - // } - - // /* OFN_FILEMUSTEXIST implies OFN_PATHMUSTEXIST */ - // if (ofn->Flags & OFN_FILEMUSTEXIST) - // ofn->Flags |= OFN_PATHMUSTEXIST; - - // if (is_win16_looks(ofn->Flags)) - // return GetFileName31W(ofn, OPEN_DIALOG); - // else - // { - // FileOpenDlgInfos info; - - // init_filedlg_infoW(ofn, &info); - // return GetFileDialog95(&info, OPEN_DIALOG); - // } -// } - - -// /*********************************************************************** - // * GetSaveFileNameA (COMDLG32.@) - // * - // * Creates a dialog box for the user to select a file to save. - // * - // * RETURNS - // * TRUE on success: user enters a valid file - // * FALSE on cancel, error, close or filename-does-not-fit-in-buffer. - // * - // */ -// BOOL WINAPI GetSaveFileNameA(OPENFILENAMEA *ofn) -// { - // if (!valid_struct_size( ofn->lStructSize )) - // { - // COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE ); - // return FALSE; - // } - - // if (is_win16_looks(ofn->Flags)) - // return GetFileName31A(ofn, SAVE_DIALOG); - // else - // { - // FileOpenDlgInfos info; - - // init_filedlg_infoA(ofn, &info); - // return GetFileDialog95(&info, SAVE_DIALOG); - // } -// } - -// /*********************************************************************** - // * GetSaveFileNameW (COMDLG32.@) - // * - // * Creates a dialog box for the user to select a file to save. - // * - // * RETURNS - // * TRUE on success: user enters a valid file - // * FALSE on cancel, error, close or filename-does-not-fit-in-buffer. - // * - // */ -// BOOL WINAPI GetSaveFileNameW( - // LPOPENFILENAMEW ofn) /* [in/out] address of init structure */ -// { - // if (!valid_struct_size( ofn->lStructSize )) - // { - // COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE ); - // return FALSE; - // } - - // if (is_win16_looks(ofn->Flags)) - // return GetFileName31W(ofn, SAVE_DIALOG); - // else - // { - // FileOpenDlgInfos info; - - // init_filedlg_infoW(ofn, &info); - // return GetFileDialog95(&info, SAVE_DIALOG); - // } -// } - -// /*********************************************************************** - // * GetFileTitleA (COMDLG32.@) - // * - // * See GetFileTitleW. - // */ -// short WINAPI GetFileTitleA(LPCSTR lpFile, LPSTR lpTitle, WORD cbBuf) -// { - // int ret; - // UNICODE_STRING strWFile; - // LPWSTR lpWTitle; - - // RtlCreateUnicodeStringFromAsciiz(&strWFile, lpFile); - // lpWTitle = heap_alloc(cbBuf * sizeof(WCHAR)); - // ret = GetFileTitleW(strWFile.Buffer, lpWTitle, cbBuf); - // if (!ret) WideCharToMultiByte( CP_ACP, 0, lpWTitle, -1, lpTitle, cbBuf, NULL, NULL ); - // RtlFreeUnicodeString( &strWFile ); - // heap_free( lpWTitle ); - // return ret; -// } - - -// /*********************************************************************** - // * GetFileTitleW (COMDLG32.@) - // * - // * Get the name of a file. - // * - // * PARAMS - // * lpFile [I] name and location of file - // * lpTitle [O] returned file name - // * cbBuf [I] buffer size of lpTitle - // * - // * RETURNS - // * Success: zero - // * Failure: negative number. - // */ -// short WINAPI GetFileTitleW(LPCWSTR lpFile, LPWSTR lpTitle, WORD cbBuf) -// { - // int i, len; - // TRACE("(%p %p %d);\n", lpFile, lpTitle, cbBuf); - - // if(lpFile == NULL || lpTitle == NULL) - // return -1; - - // len = lstrlenW(lpFile); - - // if (len == 0) - // return -1; - - // if(wcspbrk(lpFile, L"*[]")) - // return -1; - - // len--; - - // if(lpFile[len] == '/' || lpFile[len] == '\\' || lpFile[len] == ':') - // return -1; - - // for(i = len; i >= 0; i--) - // { - // if (lpFile[i] == '/' || lpFile[i] == '\\' || lpFile[i] == ':') - // { - // i++; - // break; - // } - // } - - // if(i == -1) - // i++; - - // TRACE("---> %s\n", debugstr_w(&lpFile[i])); - - // len = lstrlenW(lpFile+i)+1; - // if(cbBuf < len) - // return len; - - // lstrcpyW(lpTitle, &lpFile[i]); - // return 0; -// } diff --git a/wrappers/extensions/comdlgex/filedlg31.c b/wrappers/extensions/comdlgex/filedlg31.c deleted file mode 100644 index ddd82a6869..0000000000 --- a/wrappers/extensions/comdlgex/filedlg31.c +++ /dev/null @@ -1,1189 +0,0 @@ -/* - * Win 3.1 Style File Dialogs - * - * Copyright 1994 Martin Ayotte - * Copyright 1996 Albrecht Kleine - * - * 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 -#include -#include -#include -#include "windef.h" -#include "winbase.h" -#include "winnls.h" -#include "wingdi.h" -#include "winuser.h" -#include "wine/debug.h" -#include "wine/heap.h" -#include "winreg.h" -#include "wine/winternl.h" -#include "commdlg.h" -#include "shlwapi.h" -#include "cderr.h" -#include "main.h" - -WINE_DEFAULT_DEBUG_CHANNEL(commdlg); - -#include "cdlg.h" - -#define BUFFILE 512 -#define BUFFILEALLOC 512 * sizeof(WCHAR) - -static const int fldrHeight = 16; -static const int fldrWidth = 20; - -static HICON hFolder = 0; -static HICON hFolder2 = 0; -static HICON hFloppy = 0; -static HICON hHDisk = 0; -static HICON hCDRom = 0; -static HICON hNet = 0; - -#define FD31_OFN_PROP "FILEDLG_OFN" - -typedef struct tagFD31_DATA -{ - HWND hwnd; /* file dialog window handle */ - BOOL hook; /* TRUE if the dialog is hooked */ - UINT lbselchstring; /* registered message id */ - UINT fileokstring; /* registered message id */ - LPARAM lParam; /* save original lparam */ - LPCVOID template; /* template for 32 bits resource */ - BOOL open; /* TRUE if open dialog, FALSE if save dialog */ - LPOPENFILENAMEW ofnW; /* pointer either to the original structure or - a W copy for A/16 API */ - LPOPENFILENAMEA ofnA; /* original structure if 32bits ansi dialog */ -} FD31_DATA, *PFD31_DATA; - -/*********************************************************************** - * FD31_Init [internal] - */ -static BOOL FD31_Init(void) -{ - static BOOL initialized = FALSE; - - if (!initialized) { - hFolder = LoadImageA( COMDLG32_hInstance, "FOLDER", IMAGE_ICON, 16, 16, LR_SHARED ); - hFolder2 = LoadImageA( COMDLG32_hInstance, "FOLDER2", IMAGE_ICON, 16, 16, LR_SHARED ); - hFloppy = LoadImageA( COMDLG32_hInstance, "FLOPPY", IMAGE_ICON, 16, 16, LR_SHARED ); - hHDisk = LoadImageA( COMDLG32_hInstance, "HDISK", IMAGE_ICON, 16, 16, LR_SHARED ); - hCDRom = LoadImageA( COMDLG32_hInstance, "CDROM", IMAGE_ICON, 16, 16, LR_SHARED ); - hNet = LoadImageA( COMDLG32_hInstance, "NETWORK", IMAGE_ICON, 16, 16, LR_SHARED ); - if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 || - hHDisk == 0 || hCDRom == 0 || hNet == 0) - { - ERR("Error loading icons!\n"); - return FALSE; - } - initialized = TRUE; - } - return TRUE; -} - -/*********************************************************************** - * FD31_StripEditControl [internal] - * Strip pathnames off the contents of the edit control. - */ -static void FD31_StripEditControl(HWND hwnd) -{ - WCHAR temp[BUFFILE], *cp; - - GetDlgItemTextW( hwnd, edt1, temp, ARRAY_SIZE(temp)); - cp = wcsrchr(temp, '\\'); - if (cp != NULL) { - lstrcpyW(temp, cp+1); - } - cp = wcsrchr(temp, ':'); - if (cp != NULL) { - lstrcpyW(temp, cp+1); - } - /* FIXME: shouldn't we do something with the result here? ;-) */ -} - -/*********************************************************************** - * FD31_CallWindowProc [internal] - * - * Call the appropriate hook - */ -static BOOL FD31_CallWindowProc(const FD31_DATA *lfs, UINT wMsg, WPARAM wParam, LPARAM lParam) -{ - BOOL ret; - - if (lfs->ofnA) - { - TRACE("Call hookA %p (%p, %04x, %08Ix, %08Ix)\n", - lfs->ofnA->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); - ret = lfs->ofnA->lpfnHook(lfs->hwnd, wMsg, wParam, lParam); - TRACE("ret hookA %p (%p, %04x, %08Ix, %08Ix)\n", - lfs->ofnA->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); - return ret; - } - - TRACE("Call hookW %p (%p, %04x, %08Ix, %08Ix)\n", - lfs->ofnW->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); - ret = lfs->ofnW->lpfnHook(lfs->hwnd, wMsg, wParam, lParam); - TRACE("Ret hookW %p (%p, %04x, %08Ix, %08Ix)\n", - lfs->ofnW->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); - return ret; -} - -/*********************************************************************** - * FD31_GetFileType [internal] - */ -static LPCWSTR FD31_GetFileType(LPCWSTR cfptr, LPCWSTR fptr, const WORD index) -{ - int n, i; - i = 0; - if (cfptr) - for ( ;(n = lstrlenW(cfptr)) != 0; i++) - { - cfptr += n + 1; - if (i == index) - return cfptr; - cfptr += lstrlenW(cfptr) + 1; - } - if (fptr) - for ( ;(n = lstrlenW(fptr)) != 0; i++) - { - fptr += n + 1; - if (i == index) - return fptr; - fptr += lstrlenW(fptr) + 1; - } - return L"*.*"; /* FIXME */ -} - -/*********************************************************************** - * FD31_ScanDir [internal] - */ -static BOOL FD31_ScanDir(const OPENFILENAMEW *ofn, HWND hWnd, LPCWSTR newPath) -{ - WCHAR buffer[BUFFILE]; - HWND hdlg; - LRESULT lRet = TRUE; - HCURSOR hCursorWait, oldCursor; - - TRACE("Trying to change to %s\n", debugstr_w(newPath)); - if ( newPath[0] && !SetCurrentDirectoryW( newPath )) - return FALSE; - - /* get the list of spec files */ - lstrcpynW(buffer, FD31_GetFileType(ofn->lpstrCustomFilter, - ofn->lpstrFilter, ofn->nFilterIndex - 1), BUFFILE); - - hCursorWait = LoadCursorA(0, (LPSTR)IDC_WAIT); - oldCursor = SetCursor(hCursorWait); - - /* list of files */ - if ((hdlg = GetDlgItem(hWnd, lst1)) != 0) { - WCHAR* scptr; /* ptr on semi-colon */ - WCHAR* filter = buffer; - - TRACE("Using filter %s\n", debugstr_w(filter)); - SendMessageW(hdlg, LB_RESETCONTENT, 0, 0); - while (filter) { - scptr = wcschr(filter, ';'); - if (scptr) *scptr = 0; - while (*filter == ' ') filter++; - TRACE("Using file spec %s\n", debugstr_w(filter)); - SendMessageW(hdlg, LB_DIR, 0, (LPARAM)filter); - if (scptr) *scptr = ';'; - filter = (scptr) ? (scptr + 1) : 0; - } - } - - /* list of directories */ - lstrcpyW(buffer, L"*.*"); - - if (GetDlgItem(hWnd, lst2) != 0) { - lRet = DlgDirListW(hWnd, buffer, lst2, stc1, DDL_EXCLUSIVE | DDL_DIRECTORY); - } - SetCursor(oldCursor); - return lRet; -} - -/*********************************************************************** - * FD31_WMDrawItem [internal] - */ -static LONG FD31_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam, - int savedlg, const DRAWITEMSTRUCT *lpdis) -{ - WCHAR *str; - HICON hIcon; - COLORREF oldText = 0, oldBk = 0; - - if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1) - { - if (!(str = heap_alloc(BUFFILEALLOC))) return FALSE; - SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, - (LPARAM)str); - - if ((lpdis->itemState & ODS_SELECTED) && !savedlg) - { - oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) ); - oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); - } - if (savedlg) - SetTextColor(lpdis->hDC,GetSysColor(COLOR_GRAYTEXT) ); - - ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + 1, - lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED, - &(lpdis->rcItem), str, lstrlenW(str), NULL); - - if (lpdis->itemState & ODS_SELECTED) - DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) ); - - if ((lpdis->itemState & ODS_SELECTED) && !savedlg) - { - SetBkColor( lpdis->hDC, oldBk ); - SetTextColor( lpdis->hDC, oldText ); - } - heap_free(str); - return TRUE; - } - - if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2) - { - if (!(str = heap_alloc(BUFFILEALLOC))) - return FALSE; - SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, - (LPARAM)str); - - if (lpdis->itemState & ODS_SELECTED) - { - oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) ); - oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); - } - ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth, - lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED, - &(lpdis->rcItem), str, lstrlenW(str), NULL); - - if (lpdis->itemState & ODS_SELECTED) - DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) ); - - if (lpdis->itemState & ODS_SELECTED) - { - SetBkColor( lpdis->hDC, oldBk ); - SetTextColor( lpdis->hDC, oldText ); - } - DrawIconEx( lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hFolder, 16, 16, 0, 0, DI_NORMAL ); - heap_free(str); - return TRUE; - } - if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2) - { - char root[] = "a:"; - if (!(str = heap_alloc(BUFFILEALLOC))) - return FALSE; - SendMessageW(lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID, - (LPARAM)str); - root[0] += str[2] - 'a'; - switch(GetDriveTypeA(root)) - { - case DRIVE_REMOVABLE: hIcon = hFloppy; break; - case DRIVE_CDROM: hIcon = hCDRom; break; - case DRIVE_REMOTE: hIcon = hNet; break; - case DRIVE_FIXED: - default: hIcon = hHDisk; break; - } - if (lpdis->itemState & ODS_SELECTED) - { - oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) ); - oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); - } - ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth, - lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED, - &(lpdis->rcItem), str, lstrlenW(str), NULL); - - if (lpdis->itemState & ODS_SELECTED) - { - SetBkColor( lpdis->hDC, oldBk ); - SetTextColor( lpdis->hDC, oldText ); - } - DrawIconEx( lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hIcon, 16, 16, 0, 0, DI_NORMAL ); - heap_free(str); - return TRUE; - } - return FALSE; -} - -/*********************************************************************** - * FD31_UpdateResult [internal] - * update the displayed file name (with path) - */ -static void FD31_UpdateResult(const FD31_DATA *lfs, const WCHAR *tmpstr) -{ - int lenstr2; - LPOPENFILENAMEW ofnW = lfs->ofnW; - LPOPENFILENAMEA ofnA = lfs->ofnA; - WCHAR tmpstr2[BUFFILE]; - WCHAR *p; - - TRACE("%s\n", debugstr_w(tmpstr)); - if(ofnW->Flags & OFN_NOVALIDATE) - tmpstr2[0] = '\0'; - else - GetCurrentDirectoryW(BUFFILE, tmpstr2); - lenstr2 = lstrlenW(tmpstr2); - if (lenstr2 > 3) - tmpstr2[lenstr2++]='\\'; - lstrcpynW(tmpstr2+lenstr2, tmpstr, BUFFILE-lenstr2); - if (!ofnW->lpstrFile) - return; - - lstrcpynW(ofnW->lpstrFile, tmpstr2, ofnW->nMaxFile); - - /* set filename offset */ - p = PathFindFileNameW(ofnW->lpstrFile); - ofnW->nFileOffset = (p - ofnW->lpstrFile); - - /* set extension offset */ - p = PathFindExtensionW(ofnW->lpstrFile); - ofnW->nFileExtension = (*p) ? (p - ofnW->lpstrFile) + 1 : 0; - - TRACE("file %s, file offset %d, ext offset %d\n", - debugstr_w(ofnW->lpstrFile), ofnW->nFileOffset, ofnW->nFileExtension); - - /* update the real client structures if any */ - if (ofnA) - { - LPSTR lpszTemp; - if (ofnW->nMaxFile && - !WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFile, -1, - ofnA->lpstrFile, ofnA->nMaxFile, NULL, NULL )) - ofnA->lpstrFile[ofnA->nMaxFile-1] = 0; - - /* offsets are not guaranteed to be the same in WCHAR to MULTIBYTE conversion */ - /* set filename offset */ - lpszTemp = PathFindFileNameA(ofnA->lpstrFile); - ofnA->nFileOffset = (lpszTemp - ofnA->lpstrFile); - - /* set extension offset */ - lpszTemp = PathFindExtensionA(ofnA->lpstrFile); - ofnA->nFileExtension = (*lpszTemp) ? (lpszTemp - ofnA->lpstrFile) + 1 : 0; - } -} - -/*********************************************************************** - * FD31_UpdateFileTitle [internal] - * update the displayed file name (without path) - */ -static void FD31_UpdateFileTitle(const FD31_DATA *lfs) -{ - LONG lRet; - LPOPENFILENAMEW ofnW = lfs->ofnW; - LPOPENFILENAMEA ofnA = lfs->ofnA; - - if (ofnW->lpstrFileTitle != NULL) - { - lRet = SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETCURSEL, 0, 0); - SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETTEXT, lRet, - (LPARAM)ofnW->lpstrFileTitle ); - if (ofnA) - { - if (!WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFileTitle, -1, - ofnA->lpstrFileTitle, ofnA->nMaxFileTitle, NULL, NULL )) - ofnA->lpstrFileTitle[ofnA->nMaxFileTitle-1] = 0; - } - } -} - -/*********************************************************************** - * FD31_DirListDblClick [internal] - */ -static LRESULT FD31_DirListDblClick( const FD31_DATA *lfs ) -{ - LONG lRet; - HWND hWnd = lfs->hwnd; - LPWSTR pstr; - WCHAR tmpstr[BUFFILE]; - - /* get the raw string (with brackets) */ - lRet = SendDlgItemMessageW(hWnd, lst2, LB_GETCURSEL, 0, 0); - if (lRet == LB_ERR) return TRUE; - pstr = heap_alloc(BUFFILEALLOC); - SendDlgItemMessageW(hWnd, lst2, LB_GETTEXT, lRet, - (LPARAM)pstr); - lstrcpyW( tmpstr, pstr ); - heap_free(pstr); - /* get the selected directory in tmpstr */ - if (tmpstr[0] == '[') - { - tmpstr[lstrlenW(tmpstr) - 1] = 0; - lstrcpyW(tmpstr,tmpstr+1); - } - lstrcatW(tmpstr, L"\\"); - - FD31_ScanDir(lfs->ofnW, hWnd, tmpstr); - /* notify the app */ - if (lfs->hook) - { - if (FD31_CallWindowProc(lfs, lfs->lbselchstring, lst2, - MAKELONG(lRet,CD_LBSELCHANGE))) - return TRUE; - } - return TRUE; -} - -/*********************************************************************** - * FD31_FileListSelect [internal] - * called when a new item is picked in the file list - */ -static LRESULT FD31_FileListSelect( const FD31_DATA *lfs ) -{ - LONG lRet; - HWND hWnd = lfs->hwnd; - LPWSTR pstr; - - lRet = SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETCURSEL, 0, 0); - if (lRet == LB_ERR) - return TRUE; - - /* set the edit control to the chosen file */ - if ((pstr = heap_alloc(BUFFILEALLOC))) - { - SendDlgItemMessageW(hWnd, lst1, LB_GETTEXT, lRet, - (LPARAM)pstr); - SetDlgItemTextW( hWnd, edt1, pstr ); - heap_free(pstr); - } - if (lfs->hook) - { - FD31_CallWindowProc(lfs, lfs->lbselchstring, lst1, - MAKELONG(lRet,CD_LBSELCHANGE)); - } - /* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD, - CD_LBSELNOITEMS */ - return TRUE; -} - -/*********************************************************************** - * FD31_TestPath [internal] - * before accepting the file name, test if it includes wild cards - * tries to scan the directory and returns TRUE if no error. - */ -static LRESULT FD31_TestPath( const FD31_DATA *lfs, LPWSTR path ) -{ - HWND hWnd = lfs->hwnd; - LPWSTR pBeginFileName, pstr2; - WCHAR tmpstr2[BUFFILE]; - - pBeginFileName = wcsrchr(path, '\\'); - if (pBeginFileName == NULL) - pBeginFileName = wcsrchr(path, ':'); - - if (wcschr(path,'*') != NULL || wcschr(path,'?') != NULL) - { - /* edit control contains wildcards */ - if (pBeginFileName != NULL) - { - lstrcpynW(tmpstr2, pBeginFileName + 1, BUFFILE); - *(pBeginFileName + 1) = 0; - } - else - { - lstrcpyW(tmpstr2, path); - if(!(lfs->ofnW->Flags & OFN_NOVALIDATE)) - *path = 0; - } - - TRACE("path=%s, tmpstr2=%s\n", debugstr_w(path), debugstr_w(tmpstr2)); - SetDlgItemTextW( hWnd, edt1, tmpstr2 ); - FD31_ScanDir(lfs->ofnW, hWnd, path); - return (lfs->ofnW->Flags & OFN_NOVALIDATE) != 0; - } - - /* no wildcards, we might have a directory or a filename */ - /* try appending a wildcard and reading the directory */ - - pstr2 = path + lstrlenW(path); - if (pBeginFileName == NULL || *(pBeginFileName + 1) != 0) - lstrcatW(path, L"\\"); - - /* if ScanDir succeeds, we have changed the directory */ - if (FD31_ScanDir(lfs->ofnW, hWnd, path)) - return FALSE; /* and path is not a valid file name */ - - /* if not, this must be a filename */ - - *pstr2 = 0; /* remove the wildcard added before */ - - if (pBeginFileName != NULL) - { - /* strip off the pathname */ - *pBeginFileName = 0; - SetDlgItemTextW( hWnd, edt1, pBeginFileName + 1 ); - - lstrcpynW(tmpstr2, pBeginFileName + 1, ARRAY_SIZE(tmpstr2)); - /* Should we MessageBox() if this fails? */ - if (!FD31_ScanDir(lfs->ofnW, hWnd, path)) - { - return FALSE; - } - lstrcpyW(path, tmpstr2); - } - else - SetDlgItemTextW( hWnd, edt1, path ); - return TRUE; -} - -/*********************************************************************** - * FD31_Validate [internal] - * called on: click Ok button, Enter in edit, DoubleClick in file list - */ -static LRESULT FD31_Validate( const FD31_DATA *lfs, LPCWSTR path, UINT control, INT itemIndex, - BOOL internalUse ) -{ - LONG lRet; - HWND hWnd = lfs->hwnd; - OPENFILENAMEW ofnsav; - LPOPENFILENAMEW ofnW = lfs->ofnW; - WCHAR filename[BUFFILE]; - int copied_size = min( ofnW->lStructSize, sizeof(ofnsav) ); - - memcpy( &ofnsav, ofnW, copied_size ); /* for later restoring */ - - /* get current file name */ - if (path) - lstrcpynW(filename, path, ARRAY_SIZE(filename)); - else - GetDlgItemTextW( hWnd, edt1, filename, ARRAY_SIZE(filename)); - - TRACE("got filename = %s\n", debugstr_w(filename)); - /* if we did not click in file list to get there */ - if (control != lst1) - { - if (!FD31_TestPath( lfs, filename) ) - return FALSE; - } - FD31_UpdateResult(lfs, filename); - - if (internalUse) - { /* called internally after a change in a combo */ - if (lfs->hook) - { - FD31_CallWindowProc(lfs, lfs->lbselchstring, control, - MAKELONG(itemIndex,CD_LBSELCHANGE)); - } - return TRUE; - } - - FD31_UpdateFileTitle(lfs); - if (lfs->hook) - { - lRet = FD31_CallWindowProc(lfs, lfs->fileokstring, - 0, lfs->lParam ); - if (lRet) - { - memcpy( ofnW, &ofnsav, copied_size ); /* restore old state */ - return FALSE; - } - } - if ((ofnW->Flags & OFN_ALLOWMULTISELECT) && (ofnW->Flags & OFN_EXPLORER)) - { - if (ofnW->lpstrFile) - { - LPWSTR str = ofnW->lpstrFile; - LPWSTR ptr = wcsrchr(str, '\\'); - str[lstrlenW(str) + 1] = '\0'; - *ptr = 0; - } - } - return TRUE; -} - -/*********************************************************************** - * FD31_DiskChange [internal] - * called when a new item is picked in the disk selection combo - */ -static LRESULT FD31_DiskChange( const FD31_DATA *lfs ) -{ - LONG lRet; - HWND hWnd = lfs->hwnd; - LPWSTR pstr; - WCHAR diskname[BUFFILE]; - - FD31_StripEditControl(hWnd); - lRet = SendDlgItemMessageW(hWnd, cmb2, CB_GETCURSEL, 0, 0L); - if (lRet == LB_ERR) - return 0; - pstr = heap_alloc(BUFFILEALLOC); - SendDlgItemMessageW(hWnd, cmb2, CB_GETLBTEXT, lRet, - (LPARAM)pstr); - wsprintfW(diskname, L"%c:", pstr[2]); - heap_free(pstr); - - return FD31_Validate( lfs, diskname, cmb2, lRet, TRUE ); -} - -/*********************************************************************** - * FD31_FileTypeChange [internal] - * called when a new item is picked in the file type combo - */ -static LRESULT FD31_FileTypeChange( const FD31_DATA *lfs ) -{ - LONG lRet; - LPWSTR pstr; - - lRet = SendDlgItemMessageW(lfs->hwnd, cmb1, CB_GETCURSEL, 0, 0); - if (lRet == LB_ERR) - return TRUE; - lfs->ofnW->nFilterIndex = lRet + 1; - if (lfs->ofnA) - lfs->ofnA->nFilterIndex = lRet + 1; - pstr = (LPWSTR)SendDlgItemMessageW(lfs->hwnd, cmb1, CB_GETITEMDATA, lRet, 0); - TRACE("Selected filter : %s\n", debugstr_w(pstr)); - - return FD31_Validate( lfs, pstr, cmb1, lRet, TRUE ); -} - -/*********************************************************************** - * FD31_WMCommand [internal] - */ -static LRESULT FD31_WMCommand( HWND hWnd, LPARAM lParam, UINT notification, - UINT control, const FD31_DATA *lfs ) -{ - switch (control) - { - case lst1: /* file list */ - FD31_StripEditControl(hWnd); - if (notification == LBN_DBLCLK) - { - return SendMessageW(hWnd, WM_COMMAND, IDOK, 0); - } - else if (notification == LBN_SELCHANGE) - return FD31_FileListSelect( lfs ); - break; - - case lst2: /* directory list */ - FD31_StripEditControl(hWnd); - if (notification == LBN_DBLCLK) - return FD31_DirListDblClick( lfs ); - break; - - case cmb1: /* file type drop list */ - if (notification == CBN_SELCHANGE) - return FD31_FileTypeChange( lfs ); - break; - - case chx1: - break; - - case pshHelp: - break; - - case cmb2: /* disk dropdown combo */ - if (notification == CBN_SELCHANGE) - return FD31_DiskChange( lfs ); - break; - - case IDOK: - TRACE("OK pressed\n"); - if (FD31_Validate( lfs, NULL, control, 0, FALSE )) - EndDialog(hWnd, TRUE); - return TRUE; - - case IDCANCEL: - EndDialog(hWnd, FALSE); - return TRUE; - - case IDABORT: /* can be sent by the hook procedure */ - EndDialog(hWnd, TRUE); - return TRUE; - } - return FALSE; -} - -/************************************************************************ - * FD31_MapStringPairsToW [internal] - * map string pairs to Unicode - */ -static LPWSTR FD31_MapStringPairsToW(LPCSTR strA, UINT size) -{ - LPCSTR s; - LPWSTR x; - unsigned int n, len; - - s = strA; - while (*s) - s = s+strlen(s)+1; - s++; - n = s + 1 - strA; /* Don't forget the other \0 */ - if (n < size) n = size; - - len = MultiByteToWideChar( CP_ACP, 0, strA, n, NULL, 0 ); - x = heap_alloc(len * sizeof(WCHAR)); - MultiByteToWideChar( CP_ACP, 0, strA, n, x, len ); - return x; -} - - -/************************************************************************ - * FD31_DupToW [internal] - * duplicates an Ansi string to unicode, with a buffer size - */ -static LPWSTR FD31_DupToW(LPCSTR str, DWORD size) -{ - LPWSTR strW = NULL; - if (str && (size > 0)) - { - strW = heap_alloc(size * sizeof(WCHAR)); - if (strW) MultiByteToWideChar( CP_ACP, 0, str, -1, strW, size ); - } - return strW; -} - -/************************************************************************ - * FD31_MapOfnStructA [internal] - * map a 32 bits Ansi structure to a Unicode one - */ -static void FD31_MapOfnStructA(const OPENFILENAMEA *ofnA, LPOPENFILENAMEW ofnW, BOOL open) -{ - UNICODE_STRING usBuffer; - - ofnW->hwndOwner = ofnA->hwndOwner; - ofnW->hInstance = ofnA->hInstance; - if (ofnA->lpstrFilter) - ofnW->lpstrFilter = FD31_MapStringPairsToW(ofnA->lpstrFilter, 0); - - if ((ofnA->lpstrCustomFilter) && (*(ofnA->lpstrCustomFilter))) - ofnW->lpstrCustomFilter = FD31_MapStringPairsToW(ofnA->lpstrCustomFilter, ofnA->nMaxCustFilter); - ofnW->nMaxCustFilter = ofnA->nMaxCustFilter; - ofnW->nFilterIndex = ofnA->nFilterIndex; - ofnW->nMaxFile = ofnA->nMaxFile; - ofnW->lpstrFile = FD31_DupToW(ofnA->lpstrFile, ofnW->nMaxFile); - ofnW->nMaxFileTitle = ofnA->nMaxFileTitle; - ofnW->lpstrFileTitle = FD31_DupToW(ofnA->lpstrFileTitle, ofnW->nMaxFileTitle); - if (ofnA->lpstrInitialDir) - { - RtlCreateUnicodeStringFromAsciiz (&usBuffer,ofnA->lpstrInitialDir); - ofnW->lpstrInitialDir = usBuffer.Buffer; - } - if (ofnA->lpstrTitle) { - RtlCreateUnicodeStringFromAsciiz (&usBuffer, ofnA->lpstrTitle); - ofnW->lpstrTitle = usBuffer.Buffer; - } else { - WCHAR buf[16]; - LPWSTR title_tmp; - int len; - LoadStringW(COMDLG32_hInstance, open ? IDS_OPEN_FILE : IDS_SAVE_AS, buf, ARRAY_SIZE(buf)); - len = lstrlenW(buf)+1; - title_tmp = heap_alloc(len * sizeof(WCHAR)); - memcpy(title_tmp, buf, len * sizeof(WCHAR)); - ofnW->lpstrTitle = title_tmp; - } - ofnW->Flags = ofnA->Flags; - ofnW->nFileOffset = ofnA->nFileOffset; - ofnW->nFileExtension = ofnA->nFileExtension; - ofnW->lpstrDefExt = FD31_DupToW(ofnA->lpstrDefExt, 3); - if ((ofnA->Flags & OFN_ENABLETEMPLATE) && (ofnA->lpTemplateName)) - { - if (!IS_INTRESOURCE(ofnA->lpTemplateName)) - { - RtlCreateUnicodeStringFromAsciiz (&usBuffer,ofnA->lpTemplateName); - ofnW->lpTemplateName = usBuffer.Buffer; - } - else /* numbered resource */ - ofnW->lpTemplateName = (LPCWSTR) ofnA->lpTemplateName; - } - if (ofnW->lStructSize > OPENFILENAME_SIZE_VERSION_400W) - { - ofnW->pvReserved = ofnA->pvReserved; - ofnW->dwReserved = ofnA->dwReserved; - ofnW->FlagsEx = ofnA->FlagsEx; - } -} - - -/************************************************************************ - * FD31_FreeOfnW [internal] - * Undo all allocations done by FD31_MapOfnStructA - */ -static void FD31_FreeOfnW(OPENFILENAMEW *ofnW) -{ - heap_free((void *)ofnW->lpstrFilter); - heap_free(ofnW->lpstrCustomFilter); - heap_free(ofnW->lpstrFile); - heap_free(ofnW->lpstrFileTitle); - heap_free((void *)ofnW->lpstrInitialDir); - heap_free((void *)ofnW->lpstrTitle); - if (!IS_INTRESOURCE(ofnW->lpTemplateName)) - heap_free((void *)ofnW->lpTemplateName); -} - -/************************************************************************ - * FD31_DestroyPrivate [internal] - * destroys the private object - */ -static void FD31_DestroyPrivate(PFD31_DATA lfs) -{ - HWND hwnd; - if (!lfs) return; - hwnd = lfs->hwnd; - TRACE("destroying private allocation %p\n", lfs); - - /* if ofnW has been allocated, have to free everything in it */ - if (lfs->ofnA) - { - FD31_FreeOfnW(lfs->ofnW); - heap_free(lfs->ofnW); - } - heap_free(lfs); - RemovePropA(hwnd, FD31_OFN_PROP); -} - -/*********************************************************************** - * FD31_GetTemplate [internal] - * - * Get a template (or FALSE if failure) when 16 bits dialogs are used - * by a 32 bits application - * - */ -static BOOL FD31_GetTemplate(PFD31_DATA lfs) -{ - LPOPENFILENAMEW ofnW = lfs->ofnW; - LPOPENFILENAMEA ofnA = lfs->ofnA; - HANDLE hDlgTmpl; - - if (ofnW->Flags & OFN_ENABLETEMPLATEHANDLE) - { - if (!(lfs->template = LockResource( ofnW->hInstance ))) - { - COMDLG32_SetCommDlgExtendedError( CDERR_LOADRESFAILURE ); - return FALSE; - } - } - else if (ofnW->Flags & OFN_ENABLETEMPLATE) - { - HRSRC hResInfo; - if (ofnA) - hResInfo = FindResourceA( ofnA->hInstance, ofnA->lpTemplateName, (LPSTR)RT_DIALOG ); - else - hResInfo = FindResourceW( ofnW->hInstance, ofnW->lpTemplateName, (LPWSTR)RT_DIALOG ); - if (!hResInfo) - { - COMDLG32_SetCommDlgExtendedError( CDERR_FINDRESFAILURE ); - return FALSE; - } - if (!(hDlgTmpl = LoadResource( ofnW->hInstance, hResInfo )) || - !(lfs->template = LockResource( hDlgTmpl ))) - { - COMDLG32_SetCommDlgExtendedError( CDERR_LOADRESFAILURE ); - return FALSE; - } - } - else /* get it from internal Wine resource */ - { - HRSRC hResInfo; - if (!(hResInfo = FindResourceA( COMDLG32_hInstance, lfs->open ? "OPEN_FILE" : "SAVE_FILE", (LPSTR)RT_DIALOG ))) - { - COMDLG32_SetCommDlgExtendedError( CDERR_FINDRESFAILURE ); - return FALSE; - } - if (!(hDlgTmpl = LoadResource( COMDLG32_hInstance, hResInfo )) || - !(lfs->template = LockResource( hDlgTmpl ))) - { - COMDLG32_SetCommDlgExtendedError( CDERR_LOADRESFAILURE ); - return FALSE; - } - } - return TRUE; -} - -/************************************************************************ - * FD31_AllocPrivate [internal] - * allocate a private object to hold 32 bits Unicode - * structure that will be used throughout the calls, while - * keeping available the original structures and a few variables - * On entry : type = dialog procedure type (16,32A,32W) - * dlgType = dialog type (open or save) - */ -static PFD31_DATA FD31_AllocPrivate(LPARAM lParam, UINT dlgType, BOOL IsUnicode) -{ - FD31_DATA *lfs = heap_alloc_zero(sizeof(*lfs)); - - TRACE("alloc private buf %p\n", lfs); - if (!lfs) return NULL; - lfs->hook = FALSE; - lfs->lParam = lParam; - lfs->open = (dlgType == OPEN_DIALOG); - - if (IsUnicode) - { - lfs->ofnA = NULL; - lfs->ofnW = (LPOPENFILENAMEW) lParam; - if (lfs->ofnW->Flags & OFN_ENABLEHOOK) - if (lfs->ofnW->lpfnHook) - lfs->hook = TRUE; - } - else - { - lfs->ofnA = (LPOPENFILENAMEA) lParam; - if (lfs->ofnA->Flags & OFN_ENABLEHOOK) - if (lfs->ofnA->lpfnHook) - lfs->hook = TRUE; - lfs->ofnW = heap_alloc_zero(lfs->ofnA->lStructSize); - lfs->ofnW->lStructSize = lfs->ofnA->lStructSize; - FD31_MapOfnStructA(lfs->ofnA, lfs->ofnW, lfs->open); - } - - if (! FD31_GetTemplate(lfs)) - { - FD31_DestroyPrivate(lfs); - return NULL; - } - lfs->lbselchstring = RegisterWindowMessageA(LBSELCHSTRINGA); - lfs->fileokstring = RegisterWindowMessageA(FILEOKSTRINGA); - - return lfs; -} - -/*********************************************************************** - * FD31_WMInitDialog [internal] - */ -static LONG FD31_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam) -{ - int i, n; - WCHAR tmpstr[BUFFILE]; - LPWSTR pstr, old_pstr; - LPOPENFILENAMEW ofn; - PFD31_DATA lfs = (PFD31_DATA) lParam; - - if (!lfs) return FALSE; - SetPropA(hWnd, FD31_OFN_PROP, lfs); - lfs->hwnd = hWnd; - ofn = lfs->ofnW; - - TRACE("flags=%lx initialdir=%s\n", ofn->Flags, debugstr_w(ofn->lpstrInitialDir)); - - SetWindowTextW( hWnd, ofn->lpstrTitle ); - /* read custom filter information */ - if (ofn->lpstrCustomFilter) - { - pstr = ofn->lpstrCustomFilter; - n = 0; - TRACE("lpstrCustomFilter = %p\n", pstr); - while(*pstr) - { - old_pstr = pstr; - i = SendDlgItemMessageW(hWnd, cmb1, CB_ADDSTRING, 0, - (LPARAM)(ofn->lpstrCustomFilter) + n ); - n += lstrlenW(pstr) + 1; - pstr += lstrlenW(pstr) + 1; - TRACE("add str=%s associated to %s\n", - debugstr_w(old_pstr), debugstr_w(pstr)); - SendDlgItemMessageW(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr); - n += lstrlenW(pstr) + 1; - pstr += lstrlenW(pstr) + 1; - } - } - /* read filter information */ - if (ofn->lpstrFilter) { - pstr = (LPWSTR) ofn->lpstrFilter; - n = 0; - while(*pstr) { - old_pstr = pstr; - i = SendDlgItemMessageW(hWnd, cmb1, CB_ADDSTRING, 0, - (LPARAM)(ofn->lpstrFilter + n) ); - n += lstrlenW(pstr) + 1; - pstr += lstrlenW(pstr) + 1; - TRACE("add str=%s associated to %s\n", - debugstr_w(old_pstr), debugstr_w(pstr)); - SendDlgItemMessageW(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr); - n += lstrlenW(pstr) + 1; - pstr += lstrlenW(pstr) + 1; - } - } - /* set default filter */ - if (ofn->nFilterIndex == 0 && ofn->lpstrCustomFilter == NULL) - ofn->nFilterIndex = 1; - SendDlgItemMessageW(hWnd, cmb1, CB_SETCURSEL, ofn->nFilterIndex - 1, 0); - if (ofn->lpstrFile && ofn->lpstrFile[0]) - { - TRACE( "SetText of edt1 to %s\n", debugstr_w(ofn->lpstrFile) ); - SetDlgItemTextW( hWnd, edt1, ofn->lpstrFile ); - } - else - { - lstrcpynW(tmpstr, FD31_GetFileType(ofn->lpstrCustomFilter, - ofn->lpstrFilter, ofn->nFilterIndex - 1),BUFFILE); - TRACE("nFilterIndex = %ld, SetText of edt1 to %s\n", - ofn->nFilterIndex, debugstr_w(tmpstr)); - SetDlgItemTextW( hWnd, edt1, tmpstr ); - } - /* get drive list */ - *tmpstr = 0; - DlgDirListComboBoxW(hWnd, tmpstr, cmb2, 0, DDL_DRIVES | DDL_EXCLUSIVE); - /* read initial directory */ - /* FIXME: Note that this is now very version-specific (See MSDN description of - * the OPENFILENAME structure). For example under 2000/XP any path in the - * lpstrFile overrides the lpstrInitialDir, but not under 95/98/ME - */ - if (ofn->lpstrInitialDir != NULL) - { - int len; - lstrcpynW(tmpstr, ofn->lpstrInitialDir, 511); - len = lstrlenW(tmpstr); - if (len > 0 && tmpstr[len-1] != '\\' && tmpstr[len-1] != ':') { - tmpstr[len]='\\'; - tmpstr[len+1]='\0'; - } - } - else - *tmpstr = 0; - if (!FD31_ScanDir(ofn, hWnd, tmpstr)) { - *tmpstr = 0; - if (!FD31_ScanDir(ofn, hWnd, tmpstr)) - WARN("Couldn't read initial directory %s!\n", debugstr_w(tmpstr)); - } - /* select current drive in combo 2, omit missing drives */ - { - char dir[MAX_PATH]; - char str[4] = "a:\\"; - GetCurrentDirectoryA( sizeof(dir), dir ); - for(i = 0, n = -1; i < 26; i++) - { - str[0] = 'a' + i; - if (GetDriveTypeA(str) > DRIVE_NO_ROOT_DIR) n++; - if (toupper(str[0]) == toupper(dir[0])) break; - } - } - SendDlgItemMessageW(hWnd, cmb2, CB_SETCURSEL, n, 0); - if (!(ofn->Flags & OFN_SHOWHELP)) - ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE); - if (ofn->Flags & OFN_HIDEREADONLY) - ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE); - if (lfs->hook) - return FD31_CallWindowProc(lfs, WM_INITDIALOG, wParam, lfs->lParam); - return TRUE; -} - -static int FD31_GetFldrHeight(void) -{ - return fldrHeight; -} - -/*********************************************************************** - * FD31_WMMeasureItem [internal] - */ -static LONG FD31_WMMeasureItem(LPARAM lParam) -{ - LPMEASUREITEMSTRUCT lpmeasure; - - lpmeasure = (LPMEASUREITEMSTRUCT)lParam; - lpmeasure->itemHeight = FD31_GetFldrHeight(); - return TRUE; -} - - -/*********************************************************************** - * FileOpenDlgProc [internal] - * Used for open and save, in fact. - */ -static INT_PTR CALLBACK FD31_FileOpenDlgProc(HWND hWnd, UINT wMsg, - WPARAM wParam, LPARAM lParam) -{ - PFD31_DATA lfs = (PFD31_DATA)GetPropA( hWnd, FD31_OFN_PROP ); - - TRACE("msg=%x wparam=%Ix lParam=%Ix\n", wMsg, wParam, lParam); - if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook) - { - INT_PTR lRet; - lRet = (INT_PTR)FD31_CallWindowProc( lfs, wMsg, wParam, lParam ); - if (lRet) return lRet; /* else continue message processing */ - } - switch (wMsg) - { - case WM_INITDIALOG: - return FD31_WMInitDialog( hWnd, wParam, lParam ); - - case WM_MEASUREITEM: - return FD31_WMMeasureItem( lParam ); - - case WM_DRAWITEM: - return FD31_WMDrawItem( hWnd, wParam, lParam, !lfs->open, (DRAWITEMSTRUCT *)lParam ); - - case WM_COMMAND: - return FD31_WMCommand( hWnd, lParam, HIWORD(wParam), LOWORD(wParam), lfs ); -#if 0 - case WM_CTLCOLOR: - SetBkColor( (HDC16)wParam, 0x00C0C0C0 ); - switch (HIWORD(lParam)) - { - case CTLCOLOR_BTN: - SetTextColor( (HDC16)wParam, 0x00000000 ); - return hGRAYBrush; - case CTLCOLOR_STATIC: - SetTextColor( (HDC16)wParam, 0x00000000 ); - return hGRAYBrush; - } - break; -#endif - } - return FALSE; -} - -/*********************************************************************** - * GetFileName31A [internal] - * - * Creates a win31 style dialog box for the user to select a file to open/save. - */ -BOOL GetFileName31A( OPENFILENAMEA *lpofn, UINT dlgType ) -{ - BOOL bRet = FALSE; - PFD31_DATA lfs; - - if (!lpofn || !FD31_Init()) return FALSE; - - TRACE("ofn flags %08lx\n", lpofn->Flags); - lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, FALSE); - if (lfs) - { - bRet = DialogBoxIndirectParamA( COMDLG32_hInstance, lfs->template, lpofn->hwndOwner, - FD31_FileOpenDlgProc, (LPARAM)lfs); - FD31_DestroyPrivate(lfs); - } - - TRACE("return lpstrFile='%s' !\n", lpofn->lpstrFile); - return bRet; -} - -/*********************************************************************** - * GetFileName31W [internal] - * - * Creates a win31 style dialog box for the user to select a file to open/save - */ -BOOL GetFileName31W( OPENFILENAMEW *lpofn, UINT dlgType ) -{ - BOOL bRet = FALSE; - PFD31_DATA lfs; - - if (!lpofn || !FD31_Init()) return FALSE; - - lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, TRUE); - if (lfs) - { - bRet = DialogBoxIndirectParamW( COMDLG32_hInstance, lfs->template, lpofn->hwndOwner, - FD31_FileOpenDlgProc, (LPARAM)lfs); - FD31_DestroyPrivate(lfs); - } - - TRACE("file %s, file offset %d, ext offset %d\n", - debugstr_w(lpofn->lpstrFile), lpofn->nFileOffset, lpofn->nFileExtension); - return bRet; -} diff --git a/wrappers/extensions/comdlgex/filedlgbrowser.c b/wrappers/extensions/comdlgex/filedlgbrowser.c deleted file mode 100644 index 6b3b2bb302..0000000000 --- a/wrappers/extensions/comdlgex/filedlgbrowser.c +++ /dev/null @@ -1,1058 +0,0 @@ -/* - * Implementation of IShellBrowser for the File Open common dialog - * - * Copyright 1999 Francois Boisvert - * Copyright 1999, 2000 Juergen Schmied - * - * 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 -#include - -#define COBJMACROS -#define NONAMELESSUNION - -#include "windef.h" -#include "winbase.h" -#include "winnls.h" -#include "wingdi.h" -#include "winuser.h" -#include "winreg.h" - -#define NO_SHLWAPI_STREAM -#include "shlwapi.h" -#include "filedlgbrowser.h" -#include "cdlg.h" -#include "shlguid.h" -#include "servprov.h" -#include "wine/debug.h" -#include "wine/heap.h" - -WINE_DEFAULT_DEBUG_CHANNEL(commdlg); - -#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0]) - -typedef struct -{ - - IShellBrowser IShellBrowser_iface; - ICommDlgBrowser ICommDlgBrowser_iface; - IServiceProvider IServiceProvider_iface; - LONG ref; /* Reference counter */ - HWND hwndOwner; /* Owner dialog of the interface */ - -} IShellBrowserImpl; - -static inline IShellBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface) -{ - return CONTAINING_RECORD(iface, IShellBrowserImpl, IShellBrowser_iface); -} - -static inline IShellBrowserImpl *impl_from_ICommDlgBrowser( ICommDlgBrowser *iface ) -{ - return CONTAINING_RECORD(iface, IShellBrowserImpl, ICommDlgBrowser_iface); -} - -static inline IShellBrowserImpl *impl_from_IServiceProvider( IServiceProvider *iface ) -{ - return CONTAINING_RECORD(iface, IShellBrowserImpl, IServiceProvider_iface); -} - -/************************************************************************** -* vtable -*/ -static const IShellBrowserVtbl IShellBrowserImpl_Vtbl; -static const ICommDlgBrowserVtbl IShellBrowserImpl_ICommDlgBrowser_Vtbl; -static const IServiceProviderVtbl IShellBrowserImpl_IServiceProvider_Vtbl; - -/* - * Helper functions - */ - -#define add_flag(a) if (flags & a) {strcat(str, #a );strcat(str," ");} -static void COMDLG32_DumpSBSPFlags(UINT uflags) -{ - if (TRACE_ON(commdlg)) - { - unsigned int i; - static const struct { - DWORD mask; - const char *name; - } flags[] = { -#define FE(x) { x, #x} - /* SBSP_DEFBROWSER == 0 */ - FE(SBSP_SAMEBROWSER), - FE(SBSP_NEWBROWSER), - - /* SBSP_DEFMODE == 0 */ - FE(SBSP_OPENMODE), - FE(SBSP_EXPLOREMODE), - FE(SBSP_HELPMODE), - FE(SBSP_NOTRANSFERHIST), - - /* SBSP_ABSOLUTE == 0 */ - FE(SBSP_RELATIVE), - FE(SBSP_PARENT), - FE(SBSP_NAVIGATEBACK), - FE(SBSP_NAVIGATEFORWARD), - FE(SBSP_ALLOW_AUTONAVIGATE), - - FE(SBSP_NOAUTOSELECT), - FE(SBSP_WRITENOHISTORY), - - FE(SBSP_REDIRECT), - FE(SBSP_INITIATEDBYHLINKFRAME), - }; -#undef FE - TRACE("SBSP Flags: %08x =", uflags); - for (i = 0; i < ARRAY_SIZE(flags); i++) - if (flags[i].mask & uflags) - TRACE("%s ", flags[i].name); - TRACE("\n"); - } -} - -static void COMDLG32_UpdateCurrentDir(const FileOpenDlgInfos *fodInfos) -{ - LPSHELLFOLDER psfDesktop; - STRRET strret; - HRESULT res; - - res = SHGetDesktopFolder(&psfDesktop); - if (FAILED(res)) - return; - - res = IShellFolder_GetDisplayNameOf(psfDesktop, fodInfos->ShellInfos.pidlAbsCurrent, - SHGDN_FORPARSING, &strret); - if (SUCCEEDED(res)) { - WCHAR wszCurrentDir[MAX_PATH]; - - res = StrRetToBufW(&strret, fodInfos->ShellInfos.pidlAbsCurrent, wszCurrentDir, MAX_PATH); - if (SUCCEEDED(res)) - SetCurrentDirectoryW(wszCurrentDir); - } - - IShellFolder_Release(psfDesktop); -} - -/* copied from shell32 to avoid linking to it */ -static BOOL COMDLG32_StrRetToStrNW (LPVOID dest, DWORD len, LPSTRRET src, LPCITEMIDLIST pidl) -{ - TRACE("dest=%p len=0x%x strret=%p pidl=%p\n", dest , len, src, pidl); - - switch (src->uType) - { - case STRRET_WSTR: - lstrcpynW(dest, src->u.pOleStr, len); - CoTaskMemFree(src->u.pOleStr); - break; - - case STRRET_CSTR: - if (len && !MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len )) - ((LPWSTR)dest)[len-1] = 0; - break; - - case STRRET_OFFSET: - if (pidl) - { - if (len && !MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, - -1, dest, len )) - ((LPWSTR)dest)[len-1] = 0; - } - break; - - default: - FIXME("unknown type!\n"); - if (len) - { *(LPWSTR)dest = '\0'; - } - return(FALSE); - } - return TRUE; -} - -/* - * IShellBrowser - */ - -/************************************************************************** -* IShellBrowserImpl_Construct -*/ -IShellBrowser * IShellBrowserImpl_Construct(HWND hwndOwner) -{ - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwndOwner); - IShellBrowserImpl *sb; - - sb = heap_alloc(sizeof(*sb)); - - /* Initialisation of the member variables */ - sb->ref=1; - sb->hwndOwner = hwndOwner; - - /* Initialisation of the vTables */ - sb->IShellBrowser_iface.lpVtbl = &IShellBrowserImpl_Vtbl; - sb->ICommDlgBrowser_iface.lpVtbl = &IShellBrowserImpl_ICommDlgBrowser_Vtbl; - sb->IServiceProvider_iface.lpVtbl = &IShellBrowserImpl_IServiceProvider_Vtbl; - SHGetSpecialFolderLocation(hwndOwner, CSIDL_DESKTOP, - &fodInfos->ShellInfos.pidlAbsCurrent); - - TRACE("%p\n", sb); - - return &sb->IShellBrowser_iface; -} - -/*************************************************************************** -* IShellBrowserImpl_QueryInterface -*/ -static HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface, REFIID riid, void **ppvObj) -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObj); - - *ppvObj = NULL; - - if(IsEqualIID(riid, &IID_IUnknown)) - *ppvObj = &This->IShellBrowser_iface; - else if(IsEqualIID(riid, &IID_IOleWindow)) - *ppvObj = &This->IShellBrowser_iface; - else if(IsEqualIID(riid, &IID_IShellBrowser)) - *ppvObj = &This->IShellBrowser_iface; - else if(IsEqualIID(riid, &IID_ICommDlgBrowser)) - *ppvObj = &This->ICommDlgBrowser_iface; - else if(IsEqualIID(riid, &IID_IServiceProvider)) - *ppvObj = &This->IServiceProvider_iface; - - if(*ppvObj) { - IUnknown_AddRef((IUnknown*)*ppvObj); - return S_OK; - } - - FIXME("unsupported interface, %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; -} - -/************************************************************************** -* IShellBrowser::AddRef -*/ -static ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface) -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p,%u)\n", This, ref - 1); - - return ref; -} - -/************************************************************************** -* IShellBrowserImpl_Release -*/ -static ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface) -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p,%u)\n", This, ref + 1); - - if (!ref) - heap_free(This); - - return ref; -} - -/* - * IOleWindow - */ - -/************************************************************************** -* IShellBrowserImpl_GetWindow (IOleWindow) -* -* Inherited from IOleWindow::GetWindow -* -* See Windows documentation for more details -* -* Note : We will never be window less in the File Open dialog -* -*/ -static HRESULT WINAPI IShellBrowserImpl_GetWindow(IShellBrowser * iface, - HWND * phwnd) -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - TRACE("(%p)\n", This); - - if(!This->hwndOwner) - return E_FAIL; - - *phwnd = This->hwndOwner; - - return (*phwnd) ? S_OK : E_UNEXPECTED; - -} - -/************************************************************************** -* IShellBrowserImpl_ContextSensitiveHelp -*/ -static HRESULT WINAPI IShellBrowserImpl_ContextSensitiveHelp(IShellBrowser * iface, - BOOL fEnterMode) -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - TRACE("(%p)\n", This); - - /* Feature not implemented */ - return E_NOTIMPL; -} - -/* - * IShellBrowser - */ - -/************************************************************************** -* IShellBrowserImpl_BrowseObject -* -* See Windows documentation on IShellBrowser::BrowseObject for more details -* -* This function will override user specified flags and will always -* use SBSP_DEFBROWSER and SBSP_DEFMODE. -*/ -static HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface, - LPCITEMIDLIST pidl, - UINT wFlags) -{ - HRESULT hRes; - IShellFolder *folder; - IShellView *psvTmp; - FileOpenDlgInfos *fodInfos; - LPITEMIDLIST pidlTmp; - HWND hwndView; - HWND hDlgWnd; - BOOL bViewHasFocus; - RECT rectView; - - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - TRACE("(%p)(pidl=%p,flags=0x%08x)\n", This, pidl, wFlags); - COMDLG32_DumpSBSPFlags(wFlags); - - fodInfos = get_filedlg_infoptr(This->hwndOwner); - - /* Format the pidl according to its parameter's category */ - if(wFlags & SBSP_RELATIVE) - { - - /* SBSP_RELATIVE A relative pidl (relative from the current folder) */ - if (FAILED(hRes = IShellFolder_BindToObject(fodInfos->Shell.FOIShellFolder, - pidl, NULL, &IID_IShellFolder, (void **)&folder))) - { - ERR("bind to object failed\n"); - return hRes; - } - /* create an absolute pidl */ - pidlTmp = ILCombine(fodInfos->ShellInfos.pidlAbsCurrent, pidl); - } - else if(wFlags & SBSP_PARENT) - { - /* Browse the parent folder (ignores the pidl) */ - pidlTmp = GetParentPidl(fodInfos->ShellInfos.pidlAbsCurrent); - folder = GetShellFolderFromPidl(pidlTmp); - } - else /* SBSP_ABSOLUTE is 0x0000 */ - { - /* An absolute pidl (relative from the desktop) */ - pidlTmp = ILClone(pidl); - folder = GetShellFolderFromPidl(pidlTmp); - } - - if (!folder) - { - ERR("could not browse to folder\n"); - ILFree(pidlTmp); - return E_FAIL; - } - - /* If the pidl to browse to is equal to the actual pidl ... - do nothing and pretend you did it*/ - if (ILIsEqual(pidlTmp, fodInfos->ShellInfos.pidlAbsCurrent)) - { - IShellFolder_Release(folder); - ILFree(pidlTmp); - TRACE("keep current folder\n"); - return S_OK; - } - - /* Release the current DataObject */ - if (fodInfos->Shell.FOIDataObject) - { - IDataObject_Release(fodInfos->Shell.FOIDataObject); - fodInfos->Shell.FOIDataObject = NULL; - } - - /* Create the associated view */ - TRACE("create view object\n"); - if (FAILED(hRes = IShellFolder_CreateViewObject(folder, fodInfos->ShellInfos.hwndOwner, - &IID_IShellView, (void **)&psvTmp))) - { - IShellFolder_Release(folder); - ILFree(pidlTmp); - return hRes; - } - - /* Check if listview has focus */ - bViewHasFocus = IsChild(fodInfos->ShellInfos.hwndView,GetFocus()); - - /* Get the foldersettings from the old view */ - if(fodInfos->Shell.FOIShellView) - IShellView_GetCurrentInfo(fodInfos->Shell.FOIShellView, &fodInfos->ShellInfos.folderSettings); - - /* Release the old fodInfos->Shell.FOIShellView and update its value. - We have to update this early since ShellView_CreateViewWindow of native - shell32 calls OnStateChange and needs the correct view here.*/ - if(fodInfos->Shell.FOIShellView) - { - IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView); - IShellView_Release(fodInfos->Shell.FOIShellView); - } - fodInfos->Shell.FOIShellView = psvTmp; - - /* Release old FOIShellFolder and update its value */ - if (fodInfos->Shell.FOIShellFolder) - IShellFolder_Release(fodInfos->Shell.FOIShellFolder); - fodInfos->Shell.FOIShellFolder = folder; - - /* Release old pidlAbsCurrent and update its value */ - ILFree(fodInfos->ShellInfos.pidlAbsCurrent); - fodInfos->ShellInfos.pidlAbsCurrent = pidlTmp; - - COMDLG32_UpdateCurrentDir(fodInfos); - - GetWindowRect(GetDlgItem(This->hwndOwner, IDC_SHELLSTATIC), &rectView); - MapWindowPoints(0, This->hwndOwner, (LPPOINT)&rectView, 2); - - /* Create the window */ - TRACE("create view window\n"); - if (FAILED(hRes = IShellView_CreateViewWindow(psvTmp, NULL, - &fodInfos->ShellInfos.folderSettings, fodInfos->Shell.FOIShellBrowser, - &rectView, &hwndView))) - { - WARN("Failed to create view window, hr %#x.\n", hRes); - return hRes; - } - - fodInfos->ShellInfos.hwndView = hwndView; - - /* Set view window control id to 5002 */ - SetWindowLongPtrW(hwndView, GWLP_ID, lst2); - SendMessageW( hwndView, WM_SETFONT, SendMessageW( GetParent(hwndView), WM_GETFONT, 0, 0 ), FALSE ); - - /* Select the new folder in the Look In combo box of the Open file dialog */ - FILEDLG95_LOOKIN_SelectItem(fodInfos->DlgInfos.hwndLookInCB,fodInfos->ShellInfos.pidlAbsCurrent); - - /* changes the tab order of the ListView to reflect the window's File Dialog */ - hDlgWnd = GetDlgItem(GetParent(hwndView), IDC_LOOKIN); - SetWindowPos(hwndView, hDlgWnd, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); - - /* Since we destroyed the old view if it had focus set focus to the newly created view */ - if (bViewHasFocus) - SetFocus(fodInfos->ShellInfos.hwndView); - - return hRes; -} - -/************************************************************************** -* IShellBrowserImpl_EnableModelessSB -*/ -static HRESULT WINAPI IShellBrowserImpl_EnableModelessSB(IShellBrowser *iface, - BOOL fEnable) - -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - TRACE("(%p)\n", This); - - /* Feature not implemented */ - return E_NOTIMPL; -} - -/************************************************************************** -* IShellBrowserImpl_GetControlWindow -*/ -static HRESULT WINAPI IShellBrowserImpl_GetControlWindow(IShellBrowser *iface, - UINT id, - HWND *lphwnd) - -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - TRACE("(%p)\n", This); - - /* Feature not implemented */ - return E_NOTIMPL; -} - -/************************************************************************** -* IShellBrowserImpl_GetViewStateStream -*/ -static HRESULT WINAPI IShellBrowserImpl_GetViewStateStream(IShellBrowser *iface, - DWORD grfMode, - LPSTREAM *ppStrm) - -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - FIXME("(%p 0x%08x %p)\n", This, grfMode, ppStrm); - - /* Feature not implemented */ - return E_NOTIMPL; -} - -/************************************************************************** -* IShellBrowserImpl_InsertMenusSB -*/ -static HRESULT WINAPI IShellBrowserImpl_InsertMenusSB(IShellBrowser *iface, - HMENU hmenuShared, - LPOLEMENUGROUPWIDTHS lpMenuWidths) - -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - TRACE("(%p)\n", This); - - /* Feature not implemented */ - return E_NOTIMPL; -} - -/************************************************************************** -* IShellBrowserImpl_OnViewWindowActive -*/ -static HRESULT WINAPI IShellBrowserImpl_OnViewWindowActive(IShellBrowser *iface, - IShellView *ppshv) - -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - TRACE("(%p)\n", This); - - /* Feature not implemented */ - return E_NOTIMPL; -} - -/************************************************************************** -* IShellBrowserImpl_QueryActiveShellView -*/ -static HRESULT WINAPI IShellBrowserImpl_QueryActiveShellView(IShellBrowser *iface, - IShellView **ppshv) - -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - FileOpenDlgInfos *fodInfos; - - TRACE("(%p)\n", This); - - fodInfos = get_filedlg_infoptr(This->hwndOwner); - - if(!(*ppshv = fodInfos->Shell.FOIShellView)) - { - return E_FAIL; - } - IShellView_AddRef(fodInfos->Shell.FOIShellView); - return NOERROR; -} - -/************************************************************************** -* IShellBrowserImpl_RemoveMenusSB -*/ -static HRESULT WINAPI IShellBrowserImpl_RemoveMenusSB(IShellBrowser *iface, - HMENU hmenuShared) - -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - TRACE("(%p)\n", This); - - /* Feature not implemented */ - return E_NOTIMPL; -} - -/************************************************************************** -* IShellBrowserImpl_SendControlMsg -*/ -static HRESULT WINAPI IShellBrowserImpl_SendControlMsg(IShellBrowser *iface, - UINT id, - UINT uMsg, - WPARAM wParam, - LPARAM lParam, - LRESULT *pret) - -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - LRESULT lres; - - TRACE("(%p)->(0x%08x 0x%08x 0x%08lx 0x%08lx %p)\n", This, id, uMsg, wParam, lParam, pret); - - switch (id) - { - case FCW_TOOLBAR: - lres = SendDlgItemMessageA( This->hwndOwner, IDC_TOOLBAR, uMsg, wParam, lParam); - break; - default: - FIXME("ctrl id: %x\n", id); - return E_NOTIMPL; - } - if (pret) *pret = lres; - return S_OK; -} - -/************************************************************************** -* IShellBrowserImpl_SetMenuSB -*/ -static HRESULT WINAPI IShellBrowserImpl_SetMenuSB(IShellBrowser *iface, - HMENU hmenuShared, - HOLEMENU holemenuReserved, - HWND hwndActiveObject) - -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - TRACE("(%p)\n", This); - - /* Feature not implemented */ - return E_NOTIMPL; -} - -/************************************************************************** -* IShellBrowserImpl_SetStatusTextSB -*/ -static HRESULT WINAPI IShellBrowserImpl_SetStatusTextSB(IShellBrowser *iface, - LPCOLESTR lpszStatusText) - -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - TRACE("(%p)\n", This); - - /* Feature not implemented */ - return E_NOTIMPL; -} - -/************************************************************************** -* IShellBrowserImpl_SetToolbarItems -*/ -static HRESULT WINAPI IShellBrowserImpl_SetToolbarItems(IShellBrowser *iface, - LPTBBUTTON lpButtons, - UINT nButtons, - UINT uFlags) - -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - TRACE("(%p)\n", This); - - /* Feature not implemented */ - return E_NOTIMPL; -} - -/************************************************************************** -* IShellBrowserImpl_TranslateAcceleratorSB -*/ -static HRESULT WINAPI IShellBrowserImpl_TranslateAcceleratorSB(IShellBrowser *iface, - LPMSG lpmsg, - WORD wID) - -{ - IShellBrowserImpl *This = impl_from_IShellBrowser(iface); - - TRACE("(%p)\n", This); - - /* Feature not implemented */ - return E_NOTIMPL; -} - -static const IShellBrowserVtbl IShellBrowserImpl_Vtbl = -{ - /* IUnknown */ - IShellBrowserImpl_QueryInterface, - IShellBrowserImpl_AddRef, - IShellBrowserImpl_Release, - /* IOleWindow */ - IShellBrowserImpl_GetWindow, - IShellBrowserImpl_ContextSensitiveHelp, - /* IShellBrowser */ - IShellBrowserImpl_InsertMenusSB, - IShellBrowserImpl_SetMenuSB, - IShellBrowserImpl_RemoveMenusSB, - IShellBrowserImpl_SetStatusTextSB, - IShellBrowserImpl_EnableModelessSB, - IShellBrowserImpl_TranslateAcceleratorSB, - IShellBrowserImpl_BrowseObject, - IShellBrowserImpl_GetViewStateStream, - IShellBrowserImpl_GetControlWindow, - IShellBrowserImpl_SendControlMsg, - IShellBrowserImpl_QueryActiveShellView, - IShellBrowserImpl_OnViewWindowActive, - IShellBrowserImpl_SetToolbarItems -}; - - - -/* - * ICommDlgBrowser - */ - -/*************************************************************************** -* IShellBrowserImpl_ICommDlgBrowser_QueryInterface -*/ -static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_QueryInterface( - ICommDlgBrowser *iface, - REFIID riid, - LPVOID *ppvObj) -{ - IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface); - - TRACE("(%p)\n", This); - - return IShellBrowserImpl_QueryInterface(&This->IShellBrowser_iface,riid,ppvObj); -} - -/************************************************************************** -* IShellBrowserImpl_ICommDlgBrowser_AddRef -*/ -static ULONG WINAPI IShellBrowserImpl_ICommDlgBrowser_AddRef(ICommDlgBrowser * iface) -{ - IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface); - - TRACE("(%p)\n", This); - - return IShellBrowserImpl_AddRef(&This->IShellBrowser_iface); -} - -/************************************************************************** -* IShellBrowserImpl_ICommDlgBrowser_Release -*/ -static ULONG WINAPI IShellBrowserImpl_ICommDlgBrowser_Release(ICommDlgBrowser * iface) -{ - IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface); - - TRACE("(%p)\n", This); - - return IShellBrowserImpl_Release(&This->IShellBrowser_iface); -} - -/************************************************************************** -* IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand -* -* Called when a user double-clicks in the view or presses the ENTER key -*/ -static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand(ICommDlgBrowser *iface, - IShellView *ppshv) -{ - LPITEMIDLIST pidl; - FileOpenDlgInfos *fodInfos; - - IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface); - - TRACE("(%p)\n", This); - - fodInfos = get_filedlg_infoptr(This->hwndOwner); - - /* If the selected object is not a folder, send an IDOK command to parent window */ - if((pidl = GetPidlFromDataObject(fodInfos->Shell.FOIDataObject, 1))) - { - HRESULT hRes; - - ULONG ulAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR; - IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, (LPCITEMIDLIST *)&pidl, &ulAttr); - if ((ulAttr & (SFGAO_FOLDER | SFGAO_HASSUBFOLDER)) && (ulAttr & SFGAO_FILESYSANCESTOR)) - { - hRes = IShellBrowser_BrowseObject(&This->IShellBrowser_iface,pidl,SBSP_RELATIVE); - if(fodInfos->ofnInfos->Flags & OFN_EXPLORER) - SendCustomDlgNotificationMessage(This->hwndOwner, CDN_FOLDERCHANGE); - } - else - { - /* Tell the dialog that the user selected a file */ - PostMessageA(This->hwndOwner, WM_COMMAND, IDOK, 0L); - hRes = S_OK; - } - - ILFree(pidl); - - return hRes; - } - - return E_FAIL; -} - -/************************************************************************** -* IShellBrowserImpl_OnSelChange -*/ -static HRESULT IShellBrowserImpl_OnSelChange(IShellBrowserImpl *This, const IShellView *ppshv) -{ - FileOpenDlgInfos *fodInfos; - - fodInfos = get_filedlg_infoptr(This->hwndOwner); - TRACE("(%p do=%p view=%p)\n", This, fodInfos->Shell.FOIDataObject, fodInfos->Shell.FOIShellView); - - /* release old selections */ - if (fodInfos->Shell.FOIDataObject) - IDataObject_Release(fodInfos->Shell.FOIDataObject); - - /* get a new DataObject from the ShellView */ - if(FAILED(IShellView_GetItemObject(fodInfos->Shell.FOIShellView, SVGIO_SELECTION, - &IID_IDataObject, (void**)&fodInfos->Shell.FOIDataObject))) - return E_FAIL; - - FILEDLG95_FILENAME_FillFromSelection(This->hwndOwner); - - if(fodInfos->ofnInfos->Flags & OFN_EXPLORER) - SendCustomDlgNotificationMessage(This->hwndOwner, CDN_SELCHANGE); - return S_OK; -} - -/************************************************************************** -* IShellBrowserImpl_ICommDlgBrowser_OnStateChange -*/ -static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnStateChange(ICommDlgBrowser *iface, - IShellView *ppshv, - ULONG uChange) -{ - - IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface); - - TRACE("(%p shv=%p)\n", This, ppshv); - - switch (uChange) - { - case CDBOSC_SETFOCUS: - /* FIXME: Reset the default button. - This should be taken care of by defdlg. If control - other than button receives focus the default button - should be restored. */ - SendMessageA(This->hwndOwner, DM_SETDEFID, IDOK, 0); - - break; - case CDBOSC_KILLFOCUS: - { - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(This->hwndOwner); - if(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG) - { - WCHAR szSave[16]; - LoadStringW(COMDLG32_hInstance, IDS_SAVE_BUTTON, szSave, ARRAY_SIZE(szSave)); - SetDlgItemTextW(fodInfos->ShellInfos.hwndOwner, IDOK, szSave); - } - } - break; - case CDBOSC_SELCHANGE: - return IShellBrowserImpl_OnSelChange(This, ppshv); - case CDBOSC_RENAME: - /* nothing to do */ - break; - } - - return NOERROR; -} - -/* send_includeitem_notification - * - * Sends a CDN_INCLUDEITEM notification for "pidl" to hwndParentDlg - */ -static LRESULT send_includeitem_notification(HWND hwndParentDlg, LPCITEMIDLIST pidl) -{ - LRESULT hook_result = 0; - FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwndParentDlg); - - if(!fodInfos) return 0; - - if(fodInfos->DlgInfos.hwndCustomDlg) - { - TRACE("call notify CDN_INCLUDEITEM for pidl=%p\n", pidl); - if(fodInfos->unicode) - { - OFNOTIFYEXW ofnNotify; - ofnNotify.psf = fodInfos->Shell.FOIShellFolder; - ofnNotify.pidl = (LPITEMIDLIST)pidl; - ofnNotify.hdr.hwndFrom = hwndParentDlg; - ofnNotify.hdr.idFrom = 0; - ofnNotify.hdr.code = CDN_INCLUDEITEM; - ofnNotify.lpOFN = fodInfos->ofnInfos; - hook_result = SendMessageW(fodInfos->DlgInfos.hwndCustomDlg, WM_NOTIFY, 0, (LPARAM)&ofnNotify); - } - else - { - OFNOTIFYEXA ofnNotify; - ofnNotify.psf = fodInfos->Shell.FOIShellFolder; - ofnNotify.pidl = (LPITEMIDLIST)pidl; - ofnNotify.hdr.hwndFrom = hwndParentDlg; - ofnNotify.hdr.idFrom = 0; - ofnNotify.hdr.code = CDN_INCLUDEITEM; - ofnNotify.lpOFN = (LPOPENFILENAMEA)fodInfos->ofnInfos; - hook_result = SendMessageA(fodInfos->DlgInfos.hwndCustomDlg, WM_NOTIFY, 0, (LPARAM)&ofnNotify); - } - } - TRACE("Retval: 0x%08lx\n", hook_result); - return hook_result; -} - -/************************************************************************** -* IShellBrowserImpl_ICommDlgBrowser_IncludeObject -*/ -static HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_IncludeObject(ICommDlgBrowser *iface, - IShellView * ppshv, - LPCITEMIDLIST pidl) -{ - FileOpenDlgInfos *fodInfos; - ULONG ulAttr; - STRRET str; - WCHAR szPathW[MAX_PATH]; - - IShellBrowserImpl *This = impl_from_ICommDlgBrowser(iface); - - TRACE("(%p)\n", This); - - fodInfos = get_filedlg_infoptr(This->hwndOwner); - - ulAttr = SFGAO_HIDDEN | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_LINK; - IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr); - - if( (ulAttr & SFGAO_HIDDEN) || /* hidden */ - !(ulAttr & (SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR))) /* special folder */ - return S_FALSE; - - /* always include directories and links */ - if(ulAttr & (SFGAO_FOLDER | SFGAO_LINK)) - return S_OK; - - /* if the application takes care of including the item we are done */ - if(fodInfos->ofnInfos->Flags & OFN_ENABLEINCLUDENOTIFY && - send_includeitem_notification(This->hwndOwner, pidl)) - return S_OK; - - /* Check if there is a mask to apply if not */ - if(!fodInfos->ShellInfos.lpstrCurrentFilter || !fodInfos->ShellInfos.lpstrCurrentFilter[0]) - return S_OK; - - if (SUCCEEDED(IShellFolder_GetDisplayNameOf(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, &str))) - { - if (COMDLG32_StrRetToStrNW(szPathW, MAX_PATH, &str, pidl)) - { - if (PathMatchSpecW(szPathW, fodInfos->ShellInfos.lpstrCurrentFilter)) - return S_OK; - } - } - return S_FALSE; - -} - -static const ICommDlgBrowserVtbl IShellBrowserImpl_ICommDlgBrowser_Vtbl = -{ - /* IUnknown */ - IShellBrowserImpl_ICommDlgBrowser_QueryInterface, - IShellBrowserImpl_ICommDlgBrowser_AddRef, - IShellBrowserImpl_ICommDlgBrowser_Release, - /* ICommDlgBrowser */ - IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand, - IShellBrowserImpl_ICommDlgBrowser_OnStateChange, - IShellBrowserImpl_ICommDlgBrowser_IncludeObject -}; - - - - -/* - * IServiceProvider - */ - -/*************************************************************************** -* IShellBrowserImpl_IServiceProvider_QueryInterface -*/ -static HRESULT WINAPI IShellBrowserImpl_IServiceProvider_QueryInterface( - IServiceProvider *iface, - REFIID riid, - LPVOID *ppvObj) -{ - IShellBrowserImpl *This = impl_from_IServiceProvider(iface); - - FIXME("(%p)\n", This); - - return IShellBrowserImpl_QueryInterface(&This->IShellBrowser_iface,riid,ppvObj); -} - -/************************************************************************** -* IShellBrowserImpl_IServiceProvider_AddRef -*/ -static ULONG WINAPI IShellBrowserImpl_IServiceProvider_AddRef(IServiceProvider * iface) -{ - IShellBrowserImpl *This = impl_from_IServiceProvider(iface); - - FIXME("(%p)\n", This); - - return IShellBrowserImpl_AddRef(&This->IShellBrowser_iface); -} - -/************************************************************************** -* IShellBrowserImpl_IServiceProvider_Release -*/ -static ULONG WINAPI IShellBrowserImpl_IServiceProvider_Release(IServiceProvider * iface) -{ - IShellBrowserImpl *This = impl_from_IServiceProvider(iface); - - FIXME("(%p)\n", This); - - return IShellBrowserImpl_Release(&This->IShellBrowser_iface); -} - -/************************************************************************** -* IShellBrowserImpl_IServiceProvider_Release -* -* NOTES -* the w2k shellview asks for (guidService = SID_STopLevelBrowser, -* riid = IShellBrowser) to call SendControlMsg (). -* -* FIXME -* this is a hack! -*/ - -static HRESULT WINAPI IShellBrowserImpl_IServiceProvider_QueryService( - IServiceProvider * iface, - REFGUID guidService, - REFIID riid, - void** ppv) -{ - IShellBrowserImpl *This = impl_from_IServiceProvider(iface); - - FIXME("(%p)\n\t%s\n\t%s\n", This,debugstr_guid(guidService), debugstr_guid(riid) ); - - *ppv = NULL; - if(guidService && IsEqualIID(guidService, &SID_STopLevelBrowser)) - return IShellBrowserImpl_QueryInterface(&This->IShellBrowser_iface,riid,ppv); - - FIXME("(%p) unknown interface requested\n", This); - return E_NOINTERFACE; - -} - -static const IServiceProviderVtbl IShellBrowserImpl_IServiceProvider_Vtbl = -{ - /* IUnknown */ - IShellBrowserImpl_IServiceProvider_QueryInterface, - IShellBrowserImpl_IServiceProvider_AddRef, - IShellBrowserImpl_IServiceProvider_Release, - /* IServiceProvider */ - IShellBrowserImpl_IServiceProvider_QueryService -}; diff --git a/wrappers/extensions/comdlgex/filedlgbrowser.h b/wrappers/extensions/comdlgex/filedlgbrowser.h deleted file mode 100644 index 21eb3d56df..0000000000 --- a/wrappers/extensions/comdlgex/filedlgbrowser.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Implementation of IShellBrowser for the File Open common dialog - * - * Copyright 1999 Francois Boisvert - * Copyright 1999, 2000 Juergen Schmied - * - * 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 - */ - -#ifndef SHBROWSER_H -#define SHBROWSER_H - -#ifndef RC_INVOKED -#include -#endif - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "shlobj.h" -#include "objbase.h" -#include "commdlg.h" - -/*********************************************************************** - * Defines and global variables - */ - -/* dialog internal property */ - -#define FODPROP_SAVEDLG 0x0001 /* File dialog is a Save file dialog */ -#define FODPROP_USEVIEW 0x0002 /* Indicates the user selection must be taken - from the IShellView */ - -/*********************************************************************** - * Data structure - */ - - -typedef struct -{ - LPOPENFILENAMEW ofnInfos; - BOOL unicode; - LPWSTR initdir; - LPWSTR filename; - LPCWSTR title; - LPCWSTR defext; - LPCWSTR filter; - LPCWSTR customfilter; - SIZE sizedlg; /* remember the size of the dialog */ - POINT initial_size; /* remember the initial size of the dialog */ - struct { - IShellBrowser *FOIShellBrowser; - IShellFolder *FOIShellFolder; - IShellView *FOIShellView; - IDataObject *FOIDataObject; - } Shell; - - struct { - HWND hwndOwner; - HWND hwndView; - FOLDERSETTINGS folderSettings; - LPITEMIDLIST pidlAbsCurrent; - LPWSTR lpstrCurrentFilter; - } ShellInfos; - - struct { - HWND hwndFileTypeCB; - HWND hwndLookInCB; - HWND hwndFileName; - HWND hwndTB; - HWND hwndGrip; - HWND hwndCustomDlg; - DWORD dwDlgProp; - } DlgInfos; - - struct { - UINT fileokstring; - UINT lbselchstring; - UINT helpmsgstring; - UINT sharevistring; - } HookMsg; - - BOOL ole_initialized; - LPITEMIDLIST places[5]; -} FileOpenDlgInfos; - -/*********************************************************************** - * Control IDs - */ -#define IDS_FILENOTFOUND 114 -#define IDS_VERIFYFILE 115 -#define IDS_CREATEFILE 116 -#define IDS_OVERWRITEFILE 119 -#define IDS_INVALID_FILENAME_TITLE 120 -#define IDS_INVALID_FILENAME 121 -#define IDS_PATHNOTEXISTING 122 -#define IDS_FILENOTEXISTING 123 -#define IDS_INVALID_FOLDERNAME 124 - -/* File Dialog Tooltips string IDs */ - -#define IDS_UPFOLDER 150 -#define IDS_NEWFOLDER 151 -#define IDS_LISTVIEW 152 -#define IDS_REPORTVIEW 153 -#define IDS_TODESKTOP 154 - -#define IDC_OPENREADONLY chx1 - -#define IDC_TOOLBARSTATIC stc1 -#define IDC_FILETYPESTATIC stc2 -#define IDC_FILENAMESTATIC stc3 -#define IDC_LOOKINSTATIC stc4 - -#define IDC_SHELLSTATIC lst1 - -#define IDC_FILETYPE cmb1 -#define IDC_LOOKIN cmb2 - -#define IDC_FILENAME edt1 - -#define IDC_TOOLBAR 1 -#define IDC_TOOLBARPLACES ctl1 - -/*********************************************************************** - * Prototypes for the methods of the IShellBrowserImpl class - */ -/* Constructor */ -IShellBrowser * IShellBrowserImpl_Construct(HWND hwndOwner) DECLSPEC_HIDDEN; - - -LPITEMIDLIST GetPidlFromDataObject ( IDataObject *doSelected, UINT nPidlIndex) DECLSPEC_HIDDEN; - -/* Functions used by the EDIT box */ -void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd) DECLSPEC_HIDDEN; - -/************************************************************************** -* External Prototypes -*/ -extern FileOpenDlgInfos *get_filedlg_infoptr(HWND hwnd) DECLSPEC_HIDDEN; - -extern IShellFolder* GetShellFolderFromPidl(LPITEMIDLIST pidlAbs) DECLSPEC_HIDDEN; -extern LPITEMIDLIST GetParentPidl(LPITEMIDLIST pidl) DECLSPEC_HIDDEN; - -extern int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl) DECLSPEC_HIDDEN; -extern LRESULT SendCustomDlgNotificationMessage(HWND hwndParentDlg, UINT uCode) DECLSPEC_HIDDEN; - -#endif /*SHBROWSER_H*/ diff --git a/wrappers/extensions/comdlgex/floppy.ico b/wrappers/extensions/comdlgex/floppy.ico deleted file mode 100644 index 726f876923..0000000000 Binary files a/wrappers/extensions/comdlgex/floppy.ico and /dev/null differ diff --git a/wrappers/extensions/comdlgex/folder.ico b/wrappers/extensions/comdlgex/folder.ico deleted file mode 100644 index eeba9f57c6..0000000000 Binary files a/wrappers/extensions/comdlgex/folder.ico and /dev/null differ diff --git a/wrappers/extensions/comdlgex/folder2.ico b/wrappers/extensions/comdlgex/folder2.ico deleted file mode 100644 index 6f1e662c41..0000000000 Binary files a/wrappers/extensions/comdlgex/folder2.ico and /dev/null differ diff --git a/wrappers/extensions/comdlgex/fontpics.bmp b/wrappers/extensions/comdlgex/fontpics.bmp deleted file mode 100644 index 6c3c1b6ded..0000000000 Binary files a/wrappers/extensions/comdlgex/fontpics.bmp and /dev/null differ diff --git a/wrappers/extensions/comdlgex/hdisk.ico b/wrappers/extensions/comdlgex/hdisk.ico deleted file mode 100644 index 688dbe5be9..0000000000 Binary files a/wrappers/extensions/comdlgex/hdisk.ico and /dev/null differ diff --git a/wrappers/extensions/comdlgex/itemdlg.c b/wrappers/extensions/comdlgex/itemdlg.c deleted file mode 100644 index e811eb02c2..0000000000 --- a/wrappers/extensions/comdlgex/itemdlg.c +++ /dev/null @@ -1,4910 +0,0 @@ -/* - * Common Item Dialog - * - * Copyright 2010,2011 David Hedberg - * - * 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 - -#define COBJMACROS -#define NONAMELESSUNION - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "wingdi.h" -#include "winreg.h" -#include "shlwapi.h" - -#include "commdlg.h" -#include "cdlg.h" -#include "filedlgbrowser.h" - -#include "wine/debug.h" -#include "wine/list.h" -#include - -#define IDC_NAV_TOOLBAR 200 -#define IDC_NAVBACK 201 -#define IDC_NAVFORWARD 202 -#define OFN_FORCESHOWHIDDEN 0x10000000 - -#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0]) - -#include -/* This seems to be another version of IID_IFileDialogCustomize. If - * there is any difference I have yet to find it. */ -DEFINE_GUID(IID_IFileDialogCustomizeAlt, 0x8016B7B3, 0x3D49, 0x4504, 0xA0,0xAA, 0x2A,0x37,0x49,0x4E,0x60,0x6F); - -WINE_DEFAULT_DEBUG_CHANNEL(commdlg); - -static const WCHAR notifysink_childW[] = {'n','f','s','_','c','h','i','l','d',0}; -static const WCHAR floatnotifysinkW[] = {'F','l','o','a','t','N','o','t','i','f','y','S','i','n','k',0}; -static const WCHAR radiobuttonlistW[] = {'R','a','d','i','o','B','u','t','t','o','n','L','i','s','t',0}; - -enum ITEMDLG_TYPE { - ITEMDLG_TYPE_OPEN, - ITEMDLG_TYPE_SAVE -}; - -enum ITEMDLG_CCTRL_TYPE { - IDLG_CCTRL_MENU, - IDLG_CCTRL_PUSHBUTTON, - IDLG_CCTRL_COMBOBOX, - IDLG_CCTRL_RADIOBUTTONLIST, - IDLG_CCTRL_CHECKBUTTON, - IDLG_CCTRL_EDITBOX, - IDLG_CCTRL_SEPARATOR, - IDLG_CCTRL_TEXT, - IDLG_CCTRL_OPENDROPDOWN, - IDLG_CCTRL_VISUALGROUP -}; - -typedef struct cctrl_item { - DWORD id, parent_id; - LPWSTR label; - CDCONTROLSTATEF cdcstate; - HWND hwnd; - struct list entry; -} cctrl_item; - -typedef struct { - HWND hwnd, wrapper_hwnd; - UINT id, dlgid; - enum ITEMDLG_CCTRL_TYPE type; - CDCONTROLSTATEF cdcstate; - struct list entry; - - struct list sub_cctrls; - struct list sub_cctrls_entry; - struct list sub_items; -} customctrl; - -typedef struct { - struct list entry; - IFileDialogEvents *pfde; - DWORD cookie; -} events_client; - -typedef struct FileDialogImpl { - IFileDialog2 IFileDialog2_iface; - union { - IFileOpenDialog IFileOpenDialog_iface; - IFileSaveDialog IFileSaveDialog_iface; - } u; - enum ITEMDLG_TYPE dlg_type; - IExplorerBrowserEvents IExplorerBrowserEvents_iface; - IServiceProvider IServiceProvider_iface; - ICommDlgBrowser3 ICommDlgBrowser3_iface; - IOleWindow IOleWindow_iface; - IFileDialogCustomize IFileDialogCustomize_iface; - LONG ref; - - FILEOPENDIALOGOPTIONS options; - COMDLG_FILTERSPEC *filterspecs; - UINT filterspec_count; - UINT filetypeindex; - - struct list events_clients; - DWORD events_next_cookie; - - IShellItemArray *psia_selection; - IShellItemArray *psia_results; - IShellItem *psi_defaultfolder; - IShellItem *psi_setfolder; - IShellItem *psi_folder; - - HWND dlg_hwnd; - IExplorerBrowser *peb; - DWORD ebevents_cookie; - - LPWSTR set_filename; - LPWSTR default_ext; - LPWSTR custom_title; - LPWSTR custom_okbutton; - LPWSTR custom_cancelbutton; - LPWSTR custom_filenamelabel; - - LPITEMIDLIST lpItem; - - UINT cctrl_width, cctrl_def_height, cctrls_cols; - UINT cctrl_indent, dpi_x, dpi_y; - HWND cctrls_hwnd; - struct list cctrls; - UINT_PTR cctrl_next_dlgid; - customctrl *cctrl_active_vg; - - HMENU hmenu_opendropdown; - customctrl cctrl_opendropdown; - HFONT hfont_opendropdown; - BOOL opendropdown_has_selection; - DWORD opendropdown_selection; - - GUID client_guid; -} FileDialogImpl; - -/************************************************************************** - * Event wrappers. - */ -static HRESULT events_OnFileOk(FileDialogImpl *This) -{ - events_client *cursor; - HRESULT hr = S_OK; - TRACE("%p\n", This); - - LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry) - { - TRACE("Notifying %p\n", cursor); - hr = IFileDialogEvents_OnFileOk(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface); - if(FAILED(hr) && hr != E_NOTIMPL) - break; - } - - if(hr == E_NOTIMPL) - hr = S_OK; - - return hr; -} - -static HRESULT events_OnFolderChanging(FileDialogImpl *This, IShellItem *folder) -{ - events_client *cursor; - HRESULT hr = S_OK; - TRACE("%p (%p)\n", This, folder); - - LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry) - { - TRACE("Notifying %p\n", cursor); - hr = IFileDialogEvents_OnFolderChanging(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface, folder); - if(FAILED(hr) && hr != E_NOTIMPL) - break; - } - - if(hr == E_NOTIMPL) - hr = S_OK; - - return hr; -} - -static void events_OnFolderChange(FileDialogImpl *This) -{ - events_client *cursor; - TRACE("%p\n", This); - - LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry) - { - TRACE("Notifying %p\n", cursor); - IFileDialogEvents_OnFolderChange(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface); - } -} - -static void events_OnSelectionChange(FileDialogImpl *This) -{ - events_client *cursor; - TRACE("%p\n", This); - - LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry) - { - TRACE("Notifying %p\n", cursor); - IFileDialogEvents_OnSelectionChange(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface); - } -} - -static void events_OnTypeChange(FileDialogImpl *This) -{ - events_client *cursor; - TRACE("%p\n", This); - - LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry) - { - TRACE("Notifying %p\n", cursor); - IFileDialogEvents_OnTypeChange(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface); - } -} - -static HRESULT events_OnOverwrite(FileDialogImpl *This, IShellItem *shellitem) -{ - events_client *cursor; - HRESULT hr = S_OK; - FDE_OVERWRITE_RESPONSE response = FDEOR_DEFAULT; - TRACE("%p %p\n", This, shellitem); - - LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry) - { - TRACE("Notifying %p\n", cursor); - hr = IFileDialogEvents_OnOverwrite(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface, shellitem, &response); - TRACE("<-- hr=%x response=%u\n", hr, response); - if(FAILED(hr) && hr != E_NOTIMPL) - break; - } - - if(hr == E_NOTIMPL) - hr = S_OK; - - if(SUCCEEDED(hr)) - { - if (response == FDEOR_DEFAULT) - { - WCHAR buf[100]; - int answer; - - LoadStringW(COMDLG32_hInstance, IDS_OVERWRITEFILE, buf, 100); - answer = MessageBoxW(This->dlg_hwnd, buf, This->custom_title, - MB_YESNO | MB_ICONEXCLAMATION); - if (answer == IDNO || answer == IDCANCEL) - { - hr = E_FAIL; - } - } - else if (response == FDEOR_REFUSE) - hr = E_FAIL; - } - - return hr; -} - -static inline HRESULT get_cctrl_event(IFileDialogEvents *pfde, IFileDialogControlEvents **pfdce) -{ - return IFileDialogEvents_QueryInterface(pfde, &IID_IFileDialogControlEvents, (void**)pfdce); -} - -static HRESULT cctrl_event_OnButtonClicked(FileDialogImpl *This, DWORD ctl_id) -{ - events_client *cursor; - TRACE("%p\n", This); - - LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry) - { - IFileDialogControlEvents *pfdce; - if(SUCCEEDED(get_cctrl_event(cursor->pfde, &pfdce))) - { - TRACE("Notifying %p\n", cursor); - IFileDialogControlEvents_OnButtonClicked(pfdce, &This->IFileDialogCustomize_iface, ctl_id); - IFileDialogControlEvents_Release(pfdce); - } - } - - return S_OK; -} - -static HRESULT cctrl_event_OnItemSelected(FileDialogImpl *This, DWORD ctl_id, DWORD item_id) -{ - events_client *cursor; - TRACE("%p %i %i\n", This, ctl_id, item_id); - - LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry) - { - IFileDialogControlEvents *pfdce; - if(SUCCEEDED(get_cctrl_event(cursor->pfde, &pfdce))) - { - TRACE("Notifying %p\n", cursor); - IFileDialogControlEvents_OnItemSelected(pfdce, &This->IFileDialogCustomize_iface, ctl_id, item_id); - IFileDialogControlEvents_Release(pfdce); - } - } - - return S_OK; -} - -static HRESULT cctrl_event_OnCheckButtonToggled(FileDialogImpl *This, DWORD ctl_id, BOOL checked) -{ - events_client *cursor; - TRACE("%p\n", This); - - LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry) - { - IFileDialogControlEvents *pfdce; - if(SUCCEEDED(get_cctrl_event(cursor->pfde, &pfdce))) - { - TRACE("Notifying %p\n", cursor); - IFileDialogControlEvents_OnCheckButtonToggled(pfdce, &This->IFileDialogCustomize_iface, ctl_id, checked); - IFileDialogControlEvents_Release(pfdce); - } - } - - return S_OK; -} - -static HRESULT cctrl_event_OnControlActivating(FileDialogImpl *This, - DWORD ctl_id) -{ - events_client *cursor; - TRACE("%p\n", This); - - LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry) - { - IFileDialogControlEvents *pfdce; - if(SUCCEEDED(get_cctrl_event(cursor->pfde, &pfdce))) - { - TRACE("Notifying %p\n", cursor); - IFileDialogControlEvents_OnControlActivating(pfdce, &This->IFileDialogCustomize_iface, ctl_id); - IFileDialogControlEvents_Release(pfdce); - } - } - - return S_OK; -} - -/************************************************************************** - * Helper functions. - */ -static UINT get_file_name(FileDialogImpl *This, LPWSTR *str) -{ - HWND hwnd_edit = GetDlgItem(This->dlg_hwnd, IDC_FILENAME); - UINT len; - - if(!hwnd_edit) - { - if(This->set_filename) - { - len = lstrlenW(This->set_filename); - *str = CoTaskMemAlloc(sizeof(WCHAR)*(len+1)); - lstrcpyW(*str, This->set_filename); - return len; - } - return 0; - } - - len = SendMessageW(hwnd_edit, WM_GETTEXTLENGTH, 0, 0); - *str = CoTaskMemAlloc(sizeof(WCHAR)*(len+1)); - if(!*str) - return 0; - - SendMessageW(hwnd_edit, WM_GETTEXT, len+1, (LPARAM)*str); - return len; -} - -static BOOL set_file_name(FileDialogImpl *This, LPCWSTR str) -{ - if(This->set_filename) - LocalFree(This->set_filename); - - This->set_filename = str ? StrDupW(str) : NULL; - - return SetDlgItemTextW(This->dlg_hwnd, IDC_FILENAME, This->set_filename); -} - -static void fill_filename_from_selection(FileDialogImpl *This) -{ - IShellItem *psi; - LPWSTR *names; - HRESULT hr; - UINT item_count, valid_count; - UINT len_total, i; - - if(!This->psia_selection) - return; - - hr = IShellItemArray_GetCount(This->psia_selection, &item_count); - if(FAILED(hr) || !item_count) - return; - - names = HeapAlloc(GetProcessHeap(), 0, item_count*sizeof(LPWSTR)); - - /* Get names of the selected items */ - valid_count = 0; len_total = 0; - for(i = 0; i < item_count; i++) - { - hr = IShellItemArray_GetItemAt(This->psia_selection, i, &psi); - if(SUCCEEDED(hr)) - { - UINT attr; - - hr = IShellItem_GetAttributes(psi, SFGAO_FOLDER, &attr); - if(SUCCEEDED(hr) && - (( (This->options & FOS_PICKFOLDERS) && !(attr & SFGAO_FOLDER)) || - (!(This->options & FOS_PICKFOLDERS) && (attr & SFGAO_FOLDER)))) - continue; - - hr = IShellItem_GetDisplayName(psi, (This->options & FOS_PICKFOLDERS) ? SIGDN_FILESYSPATH : SIGDN_PARENTRELATIVEPARSING, &names[valid_count]); - if(SUCCEEDED(hr)) - { - len_total += lstrlenW(names[valid_count]) + 3; - valid_count++; - } - IShellItem_Release(psi); - } - } - - if(valid_count == 1) - { - set_file_name(This, names[0]); - CoTaskMemFree(names[0]); - } - else if(valid_count > 1) - { - LPWSTR string = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len_total); - LPWSTR cur_point = string; - - for(i = 0; i < valid_count; i++) - { - LPWSTR file = names[i]; - *cur_point++ = '\"'; - lstrcpyW(cur_point, file); - cur_point += lstrlenW(file); - *cur_point++ = '\"'; - *cur_point++ = ' '; - CoTaskMemFree(file); - } - *(cur_point-1) = '\0'; - - set_file_name(This, string); - HeapFree(GetProcessHeap(), 0, string); - } - - HeapFree(GetProcessHeap(), 0, names); - return; -} - -static LPWSTR get_first_ext_from_spec(LPWSTR buf, LPCWSTR spec) -{ - WCHAR *endpos, *ext; - - lstrcpyW(buf, spec); - if( (endpos = StrChrW(buf, ';')) ) - *endpos = '\0'; - - ext = PathFindExtensionW(buf); - if(StrChrW(ext, '*')) - return NULL; - - return ext; -} - -static BOOL shell_item_exists(IShellItem* shellitem) -{ - LPWSTR filename; - HRESULT hr; - BOOL result; - - hr = IShellItem_GetDisplayName(shellitem, SIGDN_FILESYSPATH, &filename); - if (SUCCEEDED(hr)) - { - /* FIXME: Implement SFGAO_VALIDATE in Wine and use it instead. */ - result = (GetFileAttributesW(filename) != INVALID_FILE_ATTRIBUTES); - CoTaskMemFree(filename); - } - else - { - SFGAOF attributes; - result = SUCCEEDED(IShellItem_GetAttributes(shellitem, SFGAO_VALIDATE, &attributes)); - } - - return result; -} - -static HRESULT on_default_action(FileDialogImpl *This) -{ - IShellFolder *psf_parent, *psf_desktop; - LPITEMIDLIST *pidla; - LPITEMIDLIST current_folder; - LPWSTR fn_iter, files = NULL, tmp_files; - UINT file_count = 0, len, i; - int open_action; - HRESULT hr, ret = E_FAIL; - - len = get_file_name(This, &tmp_files); - if(len) - { - UINT size_used; - file_count = COMDLG32_SplitFileNames(tmp_files, len, &files, &size_used); - CoTaskMemFree(tmp_files); - } - if(!file_count) return E_FAIL; - - hr = SHGetIDListFromObject((IUnknown*)This->psi_folder, ¤t_folder); - if(FAILED(hr)) - { - ERR("Failed to get pidl for current directory.\n"); - HeapFree(GetProcessHeap(), 0, files); - return hr; - } - - TRACE("Acting on %d file(s).\n", file_count); - - pidla = HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST) * file_count); - open_action = ONOPEN_OPEN; - fn_iter = files; - - for(i = 0; i < file_count && open_action == ONOPEN_OPEN; i++) - { - WCHAR canon_filename[MAX_PATH]; - psf_parent = NULL; - - COMDLG32_GetCanonicalPath(current_folder, fn_iter, canon_filename); - - if( (This->options & FOS_NOVALIDATE) && - !(This->options & FOS_FILEMUSTEXIST) ) - open_action = ONOPEN_OPEN; - else - open_action = ONOPEN_BROWSE; - - open_action = FILEDLG95_ValidatePathAction(canon_filename, &psf_parent, This->dlg_hwnd, - This->options & ~FOS_FILEMUSTEXIST, - (This->dlg_type == ITEMDLG_TYPE_SAVE), - open_action); - - /* Add the proper extension */ - if(open_action == ONOPEN_OPEN) - { - static const WCHAR dotW[] = {'.',0}; - - if(This->dlg_type == ITEMDLG_TYPE_SAVE) - { - WCHAR extbuf[MAX_PATH], *newext = NULL; - - if(This->filterspec_count) - { - newext = get_first_ext_from_spec(extbuf, This->filterspecs[This->filetypeindex].pszSpec); - } - else if(This->default_ext) - { - lstrcpyW(extbuf, dotW); - lstrcatW(extbuf, This->default_ext); - newext = extbuf; - } - - if(newext) - { - WCHAR *ext = PathFindExtensionW(canon_filename); - if(lstrcmpW(ext, newext)) - lstrcatW(canon_filename, newext); - } - } - else - { - if( !(This->options & FOS_NOVALIDATE) && (This->options & FOS_FILEMUSTEXIST) && - !PathFileExistsW(canon_filename)) - { - if(This->default_ext) - { - lstrcatW(canon_filename, dotW); - lstrcatW(canon_filename, This->default_ext); - - if(!PathFileExistsW(canon_filename)) - { - FILEDLG95_OnOpenMessage(This->dlg_hwnd, 0, IDS_FILENOTEXISTING); - open_action = ONOPEN_BROWSE; - } - } - else - { - FILEDLG95_OnOpenMessage(This->dlg_hwnd, 0, IDS_FILENOTEXISTING); - open_action = ONOPEN_BROWSE; - } - } - } - } - - pidla[i] = COMDLG32_SHSimpleIDListFromPathAW(canon_filename); - - if(psf_parent && !(open_action == ONOPEN_BROWSE)) - IShellFolder_Release(psf_parent); - - fn_iter += (WCHAR)lstrlenW(fn_iter) + 1; - } - - HeapFree(GetProcessHeap(), 0, files); - ILFree(current_folder); - - if((This->options & FOS_PICKFOLDERS) && open_action == ONOPEN_BROWSE) - open_action = ONOPEN_OPEN; /* FIXME: Multiple folders? */ - - switch(open_action) - { - case ONOPEN_SEARCH: - FIXME("Filtering not implemented.\n"); - break; - - case ONOPEN_BROWSE: - hr = IExplorerBrowser_BrowseToObject(This->peb, (IUnknown*)psf_parent, SBSP_DEFBROWSER); - if(FAILED(hr)) - ERR("Failed to browse to directory: %08x\n", hr); - - IShellFolder_Release(psf_parent); - break; - - case ONOPEN_OPEN: - hr = SHGetDesktopFolder(&psf_desktop); - if(SUCCEEDED(hr)) - { - if(This->psia_results) - { - IShellItemArray_Release(This->psia_results); - This->psia_results = NULL; - } - - hr = SHCreateShellItemArray(NULL, psf_desktop, file_count, (PCUITEMID_CHILD_ARRAY)pidla, - &This->psia_results); - - IShellFolder_Release(psf_desktop); - - if(FAILED(hr)) - break; - - if(This->options & FOS_PICKFOLDERS) - { - SFGAOF attributes; - hr = IShellItemArray_GetAttributes(This->psia_results, SIATTRIBFLAGS_AND, SFGAO_FOLDER, &attributes); - if(hr != S_OK) - { - WCHAR buf[64]; - LoadStringW(COMDLG32_hInstance, IDS_INVALID_FOLDERNAME, buf, ARRAY_SIZE(buf)); - - MessageBoxW(This->dlg_hwnd, buf, This->custom_title, MB_OK | MB_ICONEXCLAMATION); - - IShellItemArray_Release(This->psia_results); - This->psia_results = NULL; - break; - } - } - - if((This->options & FOS_OVERWRITEPROMPT) && This->dlg_type == ITEMDLG_TYPE_SAVE) - { - IShellItem *shellitem; - - for (i=0; SUCCEEDED(hr) && ipsia_results, i, &shellitem); - if (SUCCEEDED(hr)) - { - if (shell_item_exists(shellitem)) - hr = events_OnOverwrite(This, shellitem); - - IShellItem_Release(shellitem); - } - } - - if (FAILED(hr)) - break; - } - - if(events_OnFileOk(This) == S_OK) - ret = S_OK; - } - break; - - default: - ERR("Failed.\n"); - break; - } - - /* Clean up */ - for(i = 0; i < file_count; i++) - ILFree(pidla[i]); - HeapFree(GetProcessHeap(), 0, pidla); - - /* Success closes the dialog */ - return ret; -} - -static void show_opendropdown(FileDialogImpl *This) -{ - HWND open_hwnd; - RECT open_rc; - MSG msg; - - open_hwnd = GetDlgItem(This->dlg_hwnd, IDOK); - - GetWindowRect(open_hwnd, &open_rc); - - if (TrackPopupMenu(This->hmenu_opendropdown, 0, open_rc.left, open_rc.bottom, 0, This->dlg_hwnd, NULL) && - PeekMessageW(&msg, This->dlg_hwnd, WM_MENUCOMMAND, WM_MENUCOMMAND, PM_REMOVE)) - { - MENUITEMINFOW mii; - - This->opendropdown_has_selection = TRUE; - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_ID; - GetMenuItemInfoW((HMENU)msg.lParam, msg.wParam, TRUE, &mii); - This->opendropdown_selection = mii.wID; - - if(SUCCEEDED(on_default_action(This))) - EndDialog(This->dlg_hwnd, S_OK); - else - This->opendropdown_has_selection = FALSE; - } -} - -/************************************************************************** - * Control item functions. - */ - -static void item_free(cctrl_item *item) -{ - DestroyWindow(item->hwnd); - HeapFree(GetProcessHeap(), 0, item->label); - HeapFree(GetProcessHeap(), 0, item); -} - -static cctrl_item* get_item(customctrl* parent, DWORD itemid, CDCONTROLSTATEF visible_flags, DWORD* position) -{ - DWORD dummy; - cctrl_item* item; - - if (!position) position = &dummy; - - *position = 0; - - LIST_FOR_EACH_ENTRY(item, &parent->sub_items, cctrl_item, entry) - { - if (item->id == itemid) - return item; - - if ((item->cdcstate & visible_flags) == visible_flags) - (*position)++; - } - - return NULL; -} - -static cctrl_item* get_first_item(customctrl* parent) -{ - cctrl_item* item; - - LIST_FOR_EACH_ENTRY(item, &parent->sub_items, cctrl_item, entry) - { - if ((item->cdcstate & (CDCS_VISIBLE|CDCS_ENABLED)) == (CDCS_VISIBLE|CDCS_ENABLED)) - return item; - } - - return NULL; -} - -static HRESULT add_item(customctrl* parent, DWORD itemid, LPCWSTR label, cctrl_item** result) -{ - cctrl_item* item; - LPWSTR label_copy; - - if (get_item(parent, itemid, 0, NULL)) - return E_INVALIDARG; - - item = HeapAlloc(GetProcessHeap(), 0, sizeof(*item)); - label_copy = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(label)+1)*sizeof(WCHAR)); - - if (!item || !label_copy) - { - HeapFree(GetProcessHeap(), 0, item); - HeapFree(GetProcessHeap(), 0, label_copy); - return E_OUTOFMEMORY; - } - - item->id = itemid; - item->parent_id = parent->id; - lstrcpyW(label_copy, label); - item->label = label_copy; - item->cdcstate = CDCS_VISIBLE|CDCS_ENABLED; - item->hwnd = NULL; - list_add_tail(&parent->sub_items, &item->entry); - - *result = item; - - return S_OK; -} - -/************************************************************************** - * Control functions. - */ -static inline customctrl *get_cctrl_from_dlgid(FileDialogImpl *This, DWORD dlgid) -{ - customctrl *ctrl, *sub_ctrl; - - LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry) - { - if(ctrl->dlgid == dlgid) - return ctrl; - - LIST_FOR_EACH_ENTRY(sub_ctrl, &ctrl->sub_cctrls, customctrl, sub_cctrls_entry) - if(sub_ctrl->dlgid == dlgid) - return sub_ctrl; - } - - ERR("Failed to find control with dialog id %d\n", dlgid); - return NULL; -} - -static inline customctrl *get_cctrl(FileDialogImpl *This, DWORD ctlid) -{ - customctrl *ctrl, *sub_ctrl; - - LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry) - { - if(ctrl->id == ctlid) - return ctrl; - - LIST_FOR_EACH_ENTRY(sub_ctrl, &ctrl->sub_cctrls, customctrl, sub_cctrls_entry) - if(sub_ctrl->id == ctlid) - return sub_ctrl; - } - - if (This->hmenu_opendropdown && This->cctrl_opendropdown.id == ctlid) - return &This->cctrl_opendropdown; - - TRACE("No existing control with control id %d\n", ctlid); - return NULL; -} - -static void ctrl_resize(HWND hctrl, UINT min_width, UINT max_width, BOOL multiline) -{ - LPWSTR text; - UINT len, final_width; - UINT lines, final_height; - SIZE size; - RECT rc; - HDC hdc; - WCHAR *c; - HFONT font; - - TRACE("\n"); - - len = SendMessageW(hctrl, WM_GETTEXTLENGTH, 0, 0); - text = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(len+1)); - if(!text) return; - SendMessageW(hctrl, WM_GETTEXT, len+1, (LPARAM)text); - - hdc = GetDC(hctrl); - font = (HFONT)SendMessageW(hctrl, WM_GETFONT, 0, 0); - font = SelectObject(hdc, font); - GetTextExtentPoint32W(hdc, text, lstrlenW(text), &size); - SelectObject(hdc, font); - ReleaseDC(hctrl, hdc); - - if(len && multiline) - { - /* FIXME: line-wrap */ - for(lines = 1, c = text; *c != '\0'; c++) - if(*c == '\n') lines++; - - final_height = size.cy*lines + 2*4; - } - else - { - GetWindowRect(hctrl, &rc); - final_height = rc.bottom - rc.top; - } - - final_width = min(max(size.cx, min_width) + 4, max_width); - SetWindowPos(hctrl, NULL, 0, 0, final_width, final_height, - SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); - - HeapFree(GetProcessHeap(), 0, text); -} - -static UINT ctrl_get_height(customctrl *ctrl) { - RECT rc; - GetWindowRect(ctrl->wrapper_hwnd, &rc); - return rc.bottom - rc.top; -} - -static void ctrl_free(customctrl *ctrl) -{ - customctrl *sub_cur1, *sub_cur2; - cctrl_item *item_cur1, *item_cur2; - - TRACE("Freeing control %p\n", ctrl); - if(ctrl->type == IDLG_CCTRL_MENU) - { - TBBUTTON tbb; - SendMessageW(ctrl->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb); - DestroyMenu((HMENU)tbb.dwData); - } - - LIST_FOR_EACH_ENTRY_SAFE(sub_cur1, sub_cur2, &ctrl->sub_cctrls, customctrl, sub_cctrls_entry) - { - list_remove(&sub_cur1->sub_cctrls_entry); - ctrl_free(sub_cur1); - } - - LIST_FOR_EACH_ENTRY_SAFE(item_cur1, item_cur2, &ctrl->sub_items, cctrl_item, entry) - { - list_remove(&item_cur1->entry); - item_free(item_cur1); - } - - DestroyWindow(ctrl->hwnd); - HeapFree(GetProcessHeap(), 0, ctrl); -} - -static void customctrl_resize(FileDialogImpl *This, customctrl *ctrl) -{ - RECT rc; - UINT total_height; - UINT max_width, size; - customctrl *sub_ctrl; - - switch(ctrl->type) - { - case IDLG_CCTRL_PUSHBUTTON: - case IDLG_CCTRL_COMBOBOX: - case IDLG_CCTRL_CHECKBUTTON: - case IDLG_CCTRL_TEXT: - size = MulDiv(160, This->dpi_x, USER_DEFAULT_SCREEN_DPI); - ctrl_resize(ctrl->hwnd, size, size, TRUE); - GetWindowRect(ctrl->hwnd, &rc); - SetWindowPos(ctrl->wrapper_hwnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top, - SWP_NOZORDER|SWP_NOMOVE); - break; - case IDLG_CCTRL_VISUALGROUP: - total_height = 0; - ctrl_resize(ctrl->hwnd, 0, This->cctrl_indent, TRUE); - - LIST_FOR_EACH_ENTRY(sub_ctrl, &ctrl->sub_cctrls, customctrl, sub_cctrls_entry) - { - customctrl_resize(This, sub_ctrl); - SetWindowPos(sub_ctrl->wrapper_hwnd, NULL, This->cctrl_indent, total_height, 0, 0, - SWP_NOZORDER|SWP_NOSIZE); - - total_height += ctrl_get_height(sub_ctrl); - } - - /* The label should be right adjusted */ - { - UINT width, height; - - GetWindowRect(ctrl->hwnd, &rc); - width = rc.right - rc.left; - height = rc.bottom - rc.top; - - SetWindowPos(ctrl->hwnd, NULL, This->cctrl_indent - width, 0, width, height, SWP_NOZORDER); - } - - /* Resize the wrapper window to fit all the sub controls */ - SetWindowPos(ctrl->wrapper_hwnd, NULL, 0, 0, This->cctrl_width + This->cctrl_indent, total_height, - SWP_NOZORDER|SWP_NOMOVE); - break; - case IDLG_CCTRL_RADIOBUTTONLIST: - { - cctrl_item* item; - - total_height = 0; - max_width = 0; - - LIST_FOR_EACH_ENTRY(item, &ctrl->sub_items, cctrl_item, entry) - { - size = MulDiv(160, This->dpi_x, USER_DEFAULT_SCREEN_DPI); - ctrl_resize(item->hwnd, size, size, TRUE); - SetWindowPos(item->hwnd, NULL, 0, total_height, 0, 0, - SWP_NOZORDER|SWP_NOSIZE); - - GetWindowRect(item->hwnd, &rc); - - total_height += rc.bottom - rc.top; - max_width = max(rc.right - rc.left, max_width); - } - - SetWindowPos(ctrl->hwnd, NULL, 0, 0, max_width, total_height, - SWP_NOZORDER|SWP_NOMOVE); - - SetWindowPos(ctrl->wrapper_hwnd, NULL, 0, 0, max_width, total_height, - SWP_NOZORDER|SWP_NOMOVE); - - break; - } - case IDLG_CCTRL_EDITBOX: - case IDLG_CCTRL_SEPARATOR: - case IDLG_CCTRL_MENU: - case IDLG_CCTRL_OPENDROPDOWN: - /* Nothing */ - break; - } -} - -static LRESULT notifysink_on_create(HWND hwnd, CREATESTRUCTW *crs) -{ - FileDialogImpl *This = crs->lpCreateParams; - TRACE("%p\n", This); - - SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This); - return TRUE; -} - -static LRESULT notifysink_on_bn_clicked(FileDialogImpl *This, HWND hwnd, WPARAM wparam) -{ - customctrl *ctrl = get_cctrl_from_dlgid(This, LOWORD(wparam)); - - TRACE("%p, %lx\n", This, wparam); - - if(ctrl) - { - if(ctrl->type == IDLG_CCTRL_CHECKBUTTON) - { - BOOL checked = (SendMessageW(ctrl->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED); - cctrl_event_OnCheckButtonToggled(This, ctrl->id, checked); - } - else - cctrl_event_OnButtonClicked(This, ctrl->id); - } - - return TRUE; -} - -static LRESULT notifysink_on_cbn_selchange(FileDialogImpl *This, HWND hwnd, WPARAM wparam) -{ - customctrl *ctrl = get_cctrl_from_dlgid(This, LOWORD(wparam)); - TRACE("%p, %p (%lx)\n", This, ctrl, wparam); - - if(ctrl) - { - UINT index = SendMessageW(ctrl->hwnd, CB_GETCURSEL, 0, 0); - UINT selid = SendMessageW(ctrl->hwnd, CB_GETITEMDATA, index, 0); - - cctrl_event_OnItemSelected(This, ctrl->id, selid); - } - return TRUE; -} - -static LRESULT notifysink_on_tvn_dropdown(FileDialogImpl *This, LPARAM lparam) -{ - NMTOOLBARW *nmtb = (NMTOOLBARW*)lparam; - customctrl *ctrl = get_cctrl_from_dlgid(This, GetDlgCtrlID(nmtb->hdr.hwndFrom)); - POINT pt = { 0, nmtb->rcButton.bottom }; - TBBUTTON tbb; - UINT idcmd; - - TRACE("%p, %p (%lx)\n", This, ctrl, lparam); - - if(ctrl) - { - cctrl_event_OnControlActivating(This,ctrl->id); - - SendMessageW(ctrl->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb); - ClientToScreen(ctrl->hwnd, &pt); - idcmd = TrackPopupMenu((HMENU)tbb.dwData, TPM_RETURNCMD, pt.x, pt.y, 0, This->dlg_hwnd, NULL); - if(idcmd) - cctrl_event_OnItemSelected(This, ctrl->id, idcmd); - } - - return TBDDRET_DEFAULT; -} - -static LRESULT notifysink_on_wm_command(FileDialogImpl *This, HWND hwnd, WPARAM wparam, LPARAM lparam) -{ - switch(HIWORD(wparam)) - { - case BN_CLICKED: return notifysink_on_bn_clicked(This, hwnd, wparam); - case CBN_SELCHANGE: return notifysink_on_cbn_selchange(This, hwnd, wparam); - } - - return FALSE; -} - -static LRESULT notifysink_on_wm_notify(FileDialogImpl *This, HWND hwnd, WPARAM wparam, LPARAM lparam) -{ - NMHDR *nmhdr = (NMHDR*)lparam; - - switch(nmhdr->code) - { - case TBN_DROPDOWN: return notifysink_on_tvn_dropdown(This, lparam); - } - - return FALSE; -} - -static LRESULT CALLBACK notifysink_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) -{ - FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA); - customctrl *ctrl; - HWND hwnd_child; - RECT rc; - - switch(message) - { - case WM_NCCREATE: return notifysink_on_create(hwnd, (CREATESTRUCTW*)lparam); - case WM_COMMAND: return notifysink_on_wm_command(This, hwnd, wparam, lparam); - case WM_NOTIFY: return notifysink_on_wm_notify(This, hwnd, wparam, lparam); - case WM_SIZE: - hwnd_child = GetPropW(hwnd, notifysink_childW); - ctrl = (customctrl*)GetWindowLongPtrW(hwnd_child, GWLP_USERDATA); - if(ctrl && ctrl->type != IDLG_CCTRL_VISUALGROUP) - { - GetClientRect(hwnd, &rc); - SetWindowPos(hwnd_child, NULL, 0, 0, rc.right, rc.bottom, SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER); - } - return TRUE; - } - - return DefWindowProcW(hwnd, message, wparam, lparam); -} - -static HRESULT cctrl_create_new(FileDialogImpl *This, DWORD id, - LPCWSTR text, LPCWSTR wndclass, DWORD ctrl_wsflags, - DWORD ctrl_exflags, UINT height, customctrl **ppctrl) -{ - HWND ns_hwnd, control_hwnd, parent_hwnd; - DWORD wsflags = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS; - customctrl *ctrl; - - if(get_cctrl(This, id)) - return E_UNEXPECTED; /* Duplicate id */ - - if(This->cctrl_active_vg) - parent_hwnd = This->cctrl_active_vg->wrapper_hwnd; - else - parent_hwnd = This->cctrls_hwnd; - - ns_hwnd = CreateWindowExW(0, floatnotifysinkW, NULL, wsflags, - 0, 0, This->cctrl_width, height, parent_hwnd, - (HMENU)This->cctrl_next_dlgid, COMDLG32_hInstance, This); - control_hwnd = CreateWindowExW(ctrl_exflags, wndclass, text, wsflags | ctrl_wsflags, - 0, 0, This->cctrl_width, height, ns_hwnd, - (HMENU)This->cctrl_next_dlgid, COMDLG32_hInstance, 0); - - if(!ns_hwnd || !control_hwnd) - { - ERR("Failed to create wrapper (%p) or control (%p)\n", ns_hwnd, control_hwnd); - DestroyWindow(ns_hwnd); - DestroyWindow(control_hwnd); - - return E_FAIL; - } - - SetPropW(ns_hwnd, notifysink_childW, control_hwnd); - - ctrl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(customctrl)); - if(!ctrl) - return E_OUTOFMEMORY; - - ctrl->hwnd = control_hwnd; - ctrl->wrapper_hwnd = ns_hwnd; - ctrl->id = id; - ctrl->dlgid = This->cctrl_next_dlgid; - ctrl->cdcstate = CDCS_ENABLED | CDCS_VISIBLE; - list_init(&ctrl->sub_cctrls); - list_init(&ctrl->sub_items); - - if(This->cctrl_active_vg) - list_add_tail(&This->cctrl_active_vg->sub_cctrls, &ctrl->sub_cctrls_entry); - else - list_add_tail(&This->cctrls, &ctrl->entry); - - SetWindowLongPtrW(ctrl->hwnd, GWLP_USERDATA, (LPARAM)ctrl); - - if(ppctrl) *ppctrl = ctrl; - - This->cctrl_next_dlgid++; - return S_OK; -} - -/************************************************************************** - * Container functions. - */ -static UINT ctrl_container_resize(FileDialogImpl *This, UINT container_width) -{ - UINT container_height; - UINT column_width; - UINT nr_of_cols; - UINT max_control_height, total_height = 0; - UINT cur_col_pos, cur_row_pos; - customctrl *ctrl; - BOOL fits_height; - UINT cspacing = MulDiv(90, This->dpi_x, USER_DEFAULT_SCREEN_DPI); /* Columns are spaced with 90px */ - UINT rspacing = MulDiv(4, This->dpi_y, USER_DEFAULT_SCREEN_DPI); /* Rows are spaced with 4 px. */ - - /* Given the new width of the container, this function determines the - * needed height of the container and places the controls according to - * the new layout. Returns the new height. - */ - - TRACE("%p\n", This); - - column_width = This->cctrl_width + cspacing; - nr_of_cols = (container_width - This->cctrl_indent + cspacing) / column_width; - - /* We don't need to do anything unless the number of visible columns has changed. */ - if(nr_of_cols == This->cctrls_cols) - { - RECT rc; - GetWindowRect(This->cctrls_hwnd, &rc); - return rc.bottom - rc.top; - } - - This->cctrls_cols = nr_of_cols; - - /* Get the size of the tallest control, and the total size of - * all the controls to figure out the number of slots we need. - */ - max_control_height = 0; - LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry) - { - if(ctrl->cdcstate & CDCS_VISIBLE) - { - UINT control_height = ctrl_get_height(ctrl); - max_control_height = max(max_control_height, control_height); - - total_height += control_height + rspacing; - } - } - - if(!total_height) - return 0; - - container_height = max(total_height / nr_of_cols, max_control_height + rspacing); - TRACE("Guess: container_height: %d\n",container_height); - - /* Incrementally increase container_height until all the controls - * fit. - */ - do { - UINT columns_needed = 1; - cur_row_pos = 0; - - fits_height = TRUE; - LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry) - { - if(ctrl->cdcstate & CDCS_VISIBLE) - { - UINT control_height = ctrl_get_height(ctrl); - - if(cur_row_pos + control_height > container_height) - { - if(++columns_needed > nr_of_cols) - { - container_height += 1; - fits_height = FALSE; - break; - } - cur_row_pos = 0; - } - - cur_row_pos += control_height + rspacing; - } - } - } while(!fits_height); - - TRACE("Final container height: %d\n", container_height); - - /* Move the controls to their final destination - */ - cur_col_pos = 0; cur_row_pos = 0; - LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry) - { - if(ctrl->cdcstate & CDCS_VISIBLE) - { - RECT rc; - UINT control_height, control_indent; - GetWindowRect(ctrl->wrapper_hwnd, &rc); - control_height = rc.bottom - rc.top; - - if(cur_row_pos + control_height > container_height) - { - cur_row_pos = 0; - cur_col_pos += This->cctrl_width + cspacing; - } - - - if(ctrl->type == IDLG_CCTRL_VISUALGROUP) - control_indent = 0; - else - control_indent = This->cctrl_indent; - - SetWindowPos(ctrl->wrapper_hwnd, NULL, cur_col_pos + control_indent, cur_row_pos, 0, 0, - SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); - - cur_row_pos += control_height + rspacing; - } - } - - /* Sanity check */ - if(cur_row_pos + This->cctrl_width > container_width) - ERR("-- Failed to place controls properly.\n"); - - return container_height; -} - -static void ctrl_set_font(customctrl *ctrl, HFONT font) -{ - customctrl *sub_ctrl; - cctrl_item* item; - - SendMessageW(ctrl->hwnd, WM_SETFONT, (WPARAM)font, TRUE); - - LIST_FOR_EACH_ENTRY(sub_ctrl, &ctrl->sub_cctrls, customctrl, sub_cctrls_entry) - { - ctrl_set_font(sub_ctrl, font); - } - - if (ctrl->type == IDLG_CCTRL_RADIOBUTTONLIST) - { - LIST_FOR_EACH_ENTRY(item, &ctrl->sub_items, cctrl_item, entry) - { - SendMessageW(item->hwnd, WM_SETFONT, (WPARAM)font, TRUE); - } - } -} - -static void ctrl_container_reparent(FileDialogImpl *This, HWND parent) -{ - LONG wndstyle; - - if(parent) - { - customctrl *ctrl; - HFONT font; - - wndstyle = GetWindowLongW(This->cctrls_hwnd, GWL_STYLE); - wndstyle &= ~(WS_POPUP); - wndstyle |= WS_CHILD; - SetWindowLongW(This->cctrls_hwnd, GWL_STYLE, wndstyle); - - SetParent(This->cctrls_hwnd, parent); - ShowWindow(This->cctrls_hwnd, TRUE); - - /* Set the fonts to match the dialog font. */ - font = (HFONT)SendMessageW(parent, WM_GETFONT, 0, 0); - if(!font) - ERR("Failed to get font handle from dialog.\n"); - - LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry) - { - if(font) ctrl_set_font(ctrl, font); - customctrl_resize(This, ctrl); - } - } - else - { - ShowWindow(This->cctrls_hwnd, FALSE); - - wndstyle = GetWindowLongW(This->cctrls_hwnd, GWL_STYLE); - wndstyle &= ~(WS_CHILD); - wndstyle |= WS_POPUP; - SetWindowLongW(This->cctrls_hwnd, GWL_STYLE, wndstyle); - - SetParent(This->cctrls_hwnd, NULL); - } -} - -static LRESULT ctrl_container_on_create(HWND hwnd, CREATESTRUCTW *crs) -{ - FileDialogImpl *This = crs->lpCreateParams; - TRACE("%p\n", This); - - SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This); - return TRUE; -} - -static LRESULT ctrl_container_on_wm_destroy(FileDialogImpl *This) -{ - customctrl *cur1, *cur2; - TRACE("%p\n", This); - - LIST_FOR_EACH_ENTRY_SAFE(cur1, cur2, &This->cctrls, customctrl, entry) - { - list_remove(&cur1->entry); - ctrl_free(cur1); - } - - return TRUE; -} - -static LRESULT CALLBACK ctrl_container_wndproc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam) -{ - FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA); - - switch(umessage) - { - case WM_NCCREATE: return ctrl_container_on_create(hwnd, (CREATESTRUCTW*)lparam); - case WM_DESTROY: return ctrl_container_on_wm_destroy(This); - default: return DefWindowProcW(hwnd, umessage, wparam, lparam); - } - - return FALSE; -} - -static void radiobuttonlist_set_selected_item(FileDialogImpl *This, customctrl *ctrl, cctrl_item *item) -{ - cctrl_item *cursor; - - LIST_FOR_EACH_ENTRY(cursor, &ctrl->sub_items, cctrl_item, entry) - { - SendMessageW(cursor->hwnd, BM_SETCHECK, (cursor == item) ? BST_CHECKED : BST_UNCHECKED, 0); - } -} - -static LRESULT radiobuttonlist_on_bn_clicked(FileDialogImpl *This, HWND hwnd, HWND child) -{ - DWORD ctrl_id = (DWORD)GetWindowLongPtrW(hwnd, GWLP_ID); - customctrl *ctrl; - cctrl_item *item; - BOOL found_item=FALSE; - - ctrl = get_cctrl_from_dlgid(This, ctrl_id); - - if (!ctrl) - { - ERR("Can't find this control\n"); - return 0; - } - - LIST_FOR_EACH_ENTRY(item, &ctrl->sub_items, cctrl_item, entry) - { - if (item->hwnd == child) - { - found_item = TRUE; - break; - } - } - - if (!found_item) - { - ERR("Can't find control item\n"); - return 0; - } - - radiobuttonlist_set_selected_item(This, ctrl, item); - - cctrl_event_OnItemSelected(This, ctrl->id, item->id); - - return 0; -} - -static LRESULT radiobuttonlist_on_wm_command(FileDialogImpl *This, HWND hwnd, WPARAM wparam, LPARAM lparam) -{ - switch(HIWORD(wparam)) - { - case BN_CLICKED: return radiobuttonlist_on_bn_clicked(This, hwnd, (HWND)lparam); - } - - return FALSE; -} - -static LRESULT CALLBACK radiobuttonlist_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) -{ - FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA); - - switch(message) - { - case WM_COMMAND: return radiobuttonlist_on_wm_command(This, hwnd, wparam, lparam); - } - - return DefWindowProcW(hwnd, message, wparam, lparam); -} - -static HRESULT init_custom_controls(FileDialogImpl *This) -{ - WNDCLASSW wc; - HDC hdc; - static const WCHAR ctrl_container_classname[] = - {'i','d','l','g','_','c','o','n','t','a','i','n','e','r','_','p','a','n','e',0}; - - InitCommonControlsEx(NULL); - - if( !GetClassInfoW(COMDLG32_hInstance, ctrl_container_classname, &wc) ) - { - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = ctrl_container_wndproc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = COMDLG32_hInstance; - wc.hIcon = 0; - wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW); - wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); - wc.lpszMenuName = NULL; - wc.lpszClassName = ctrl_container_classname; - - if(!RegisterClassW(&wc)) return E_FAIL; - } - - This->cctrls_hwnd = CreateWindowExW(0, ctrl_container_classname, NULL, - WS_CLIPSIBLINGS | WS_CLIPCHILDREN, - 0, 0, 0, 0, NULL, 0, - COMDLG32_hInstance, This); - if(!This->cctrls_hwnd) - return E_FAIL; - - hdc = GetDC(This->cctrls_hwnd); - This->dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); - This->dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); - ReleaseDC(This->cctrls_hwnd, hdc); - - This->cctrl_width = MulDiv(160, This->dpi_x, USER_DEFAULT_SCREEN_DPI); /* Controls have a fixed width */ - This->cctrl_indent = MulDiv(100, This->dpi_x, USER_DEFAULT_SCREEN_DPI); - This->cctrl_def_height = MulDiv(23, This->dpi_y, USER_DEFAULT_SCREEN_DPI); - This->cctrls_cols = 0; - - This->cctrl_next_dlgid = 0x2000; - list_init(&This->cctrls); - This->cctrl_active_vg = NULL; - - SetWindowLongW(This->cctrls_hwnd, GWL_STYLE, WS_TABSTOP); - - /* Register class for */ - if( !GetClassInfoW(COMDLG32_hInstance, floatnotifysinkW, &wc) || - wc.hInstance != COMDLG32_hInstance) - { - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = notifysink_proc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = COMDLG32_hInstance; - wc.hIcon = 0; - wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW); - wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); - wc.lpszMenuName = NULL; - wc.lpszClassName = floatnotifysinkW; - - if (!RegisterClassW(&wc)) - ERR("Failed to register FloatNotifySink window class.\n"); - } - - if( !GetClassInfoW(COMDLG32_hInstance, radiobuttonlistW, &wc) || - wc.hInstance != COMDLG32_hInstance) - { - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = radiobuttonlist_proc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = COMDLG32_hInstance; - wc.hIcon = 0; - wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW); - wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); - wc.lpszMenuName = NULL; - wc.lpszClassName = radiobuttonlistW; - - if (!RegisterClassW(&wc)) - ERR("Failed to register RadioButtonList window class.\n"); - } - - return S_OK; -} - -/************************************************************************** - * Window related functions. - */ -static BOOL update_open_dropdown(FileDialogImpl *This) -{ - /* Show or hide the open dropdown button as appropriate */ - BOOL show=FALSE, showing; - HWND open_hwnd, dropdown_hwnd; - - if (This->hmenu_opendropdown) - { - INT num_visible_items=0; - cctrl_item* item; - - LIST_FOR_EACH_ENTRY(item, &This->cctrl_opendropdown.sub_items, cctrl_item, entry) - { - if (item->cdcstate & CDCS_VISIBLE) - { - num_visible_items++; - if (num_visible_items >= 2) - { - show = TRUE; - break; - } - } - } - } - - open_hwnd = GetDlgItem(This->dlg_hwnd, IDOK); - dropdown_hwnd = GetDlgItem(This->dlg_hwnd, psh1); - - showing = (GetWindowLongPtrW(dropdown_hwnd, GWL_STYLE) & WS_VISIBLE) != 0; - - if (showing != show) - { - RECT open_rc, dropdown_rc; - - GetWindowRect(open_hwnd, &open_rc); - GetWindowRect(dropdown_hwnd, &dropdown_rc); - - if (show) - { - ShowWindow(dropdown_hwnd, SW_SHOW); - - SetWindowPos(open_hwnd, NULL, 0, 0, - (open_rc.right - open_rc.left) - (dropdown_rc.right - dropdown_rc.left), - open_rc.bottom - open_rc.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); - } - else - { - ShowWindow(dropdown_hwnd, SW_HIDE); - - SetWindowPos(open_hwnd, NULL, 0, 0, - (open_rc.right - open_rc.left) + (dropdown_rc.right - dropdown_rc.left), - open_rc.bottom - open_rc.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); - } - } - - return show; -} - -static void update_layout(FileDialogImpl *This) -{ - HDWP hdwp; - HWND hwnd; - RECT dialog_rc; - RECT cancel_rc, dropdown_rc, open_rc; - RECT filetype_rc, filename_rc, filenamelabel_rc; - RECT toolbar_rc, ebrowser_rc, customctrls_rc; - static const UINT vspacing = 4, hspacing = 4; - static const UINT min_width = 320, min_height = 200; - BOOL show_dropdown; - - if (!GetClientRect(This->dlg_hwnd, &dialog_rc)) - { - TRACE("Invalid dialog window, not updating layout\n"); - return; - } - - if(dialog_rc.right < min_width || dialog_rc.bottom < min_height) - { - TRACE("Dialog size (%d, %d) too small, not updating layout\n", dialog_rc.right, dialog_rc.bottom); - return; - } - - /**** - * Calculate the size of the dialog and all the parts. - */ - - /* Cancel button */ - hwnd = GetDlgItem(This->dlg_hwnd, IDCANCEL); - if(hwnd) - { - int cancel_width, cancel_height; - GetWindowRect(hwnd, &cancel_rc); - cancel_width = cancel_rc.right - cancel_rc.left; - cancel_height = cancel_rc.bottom - cancel_rc.top; - - cancel_rc.left = dialog_rc.right - cancel_width - hspacing; - cancel_rc.top = dialog_rc.bottom - cancel_height - vspacing; - cancel_rc.right = cancel_rc.left + cancel_width; - cancel_rc.bottom = cancel_rc.top + cancel_height; - } - - /* Open/Save dropdown */ - show_dropdown = update_open_dropdown(This); - - if(show_dropdown) - { - int dropdown_width, dropdown_height; - hwnd = GetDlgItem(This->dlg_hwnd, psh1); - - GetWindowRect(hwnd, &dropdown_rc); - dropdown_width = dropdown_rc.right - dropdown_rc.left; - dropdown_height = dropdown_rc.bottom - dropdown_rc.top; - - dropdown_rc.left = cancel_rc.left - dropdown_width - hspacing; - dropdown_rc.top = cancel_rc.top; - dropdown_rc.right = dropdown_rc.left + dropdown_width; - dropdown_rc.bottom = dropdown_rc.top + dropdown_height; - } - else - { - dropdown_rc.left = dropdown_rc.right = cancel_rc.left - hspacing; - dropdown_rc.top = cancel_rc.top; - dropdown_rc.bottom = cancel_rc.bottom; - } - - /* Open/Save button */ - hwnd = GetDlgItem(This->dlg_hwnd, IDOK); - if(hwnd) - { - int open_width, open_height; - GetWindowRect(hwnd, &open_rc); - open_width = open_rc.right - open_rc.left; - open_height = open_rc.bottom - open_rc.top; - - open_rc.left = dropdown_rc.left - open_width; - open_rc.top = dropdown_rc.top; - open_rc.right = open_rc.left + open_width; - open_rc.bottom = open_rc.top + open_height; - } - - /* The filetype combobox. */ - hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE); - if(hwnd) - { - int filetype_width, filetype_height; - GetWindowRect(hwnd, &filetype_rc); - - filetype_width = filetype_rc.right - filetype_rc.left; - filetype_height = filetype_rc.bottom - filetype_rc.top; - - filetype_rc.right = cancel_rc.right; - - filetype_rc.left = filetype_rc.right - filetype_width; - filetype_rc.top = cancel_rc.top - filetype_height - vspacing; - filetype_rc.bottom = filetype_rc.top + filetype_height; - - if(!This->filterspec_count) - filetype_rc.left = filetype_rc.right; - } - - /* Filename label. */ - hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC); - if(hwnd) - { - int filetypelabel_width, filetypelabel_height; - GetWindowRect(hwnd, &filenamelabel_rc); - - filetypelabel_width = filenamelabel_rc.right - filenamelabel_rc.left; - filetypelabel_height = filenamelabel_rc.bottom - filenamelabel_rc.top; - - filenamelabel_rc.left = 160; /* FIXME */ - filenamelabel_rc.top = filetype_rc.top; - filenamelabel_rc.right = filenamelabel_rc.left + filetypelabel_width; - filenamelabel_rc.bottom = filenamelabel_rc.top + filetypelabel_height; - } - - /* Filename edit box. */ - hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAME); - if(hwnd) - { - int filename_width, filename_height; - GetWindowRect(hwnd, &filename_rc); - - filename_width = filetype_rc.left - filenamelabel_rc.right - hspacing*2; - filename_height = filename_rc.bottom - filename_rc.top; - - filename_rc.left = filenamelabel_rc.right + hspacing; - filename_rc.top = filetype_rc.top; - filename_rc.right = filename_rc.left + filename_width; - filename_rc.bottom = filename_rc.top + filename_height; - } - - hwnd = GetDlgItem(This->dlg_hwnd, IDC_NAV_TOOLBAR); - if(hwnd) - { - GetWindowRect(hwnd, &toolbar_rc); - MapWindowPoints(NULL, This->dlg_hwnd, (POINT*)&toolbar_rc, 2); - } - - /* The custom controls */ - customctrls_rc.left = dialog_rc.left + hspacing; - customctrls_rc.right = dialog_rc.right - hspacing; - customctrls_rc.bottom = filename_rc.top - vspacing; - customctrls_rc.top = customctrls_rc.bottom - - ctrl_container_resize(This, customctrls_rc.right - customctrls_rc.left); - - /* The ExplorerBrowser control. */ - ebrowser_rc.left = dialog_rc.left + hspacing; - ebrowser_rc.top = toolbar_rc.bottom + vspacing; - ebrowser_rc.right = dialog_rc.right - hspacing; - ebrowser_rc.bottom = customctrls_rc.top - vspacing; - - /**** - * Move everything to the right place. - */ - - /* FIXME: The Save Dialog uses a slightly different layout. */ - hdwp = BeginDeferWindowPos(7); - - if(hdwp && This->peb) - IExplorerBrowser_SetRect(This->peb, &hdwp, ebrowser_rc); - - if(hdwp && This->cctrls_hwnd) - DeferWindowPos(hdwp, This->cctrls_hwnd, NULL, - customctrls_rc.left, customctrls_rc.top, - customctrls_rc.right - customctrls_rc.left, customctrls_rc.bottom - customctrls_rc.top, - SWP_NOZORDER | SWP_NOACTIVATE); - - /* The default controls */ - if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE)) ) - DeferWindowPos(hdwp, hwnd, NULL, filetype_rc.left, filetype_rc.top, 0, 0, - SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); - - if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAME)) ) - DeferWindowPos(hdwp, hwnd, NULL, filename_rc.left, filename_rc.top, - filename_rc.right - filename_rc.left, filename_rc.bottom - filename_rc.top, - SWP_NOZORDER | SWP_NOACTIVATE); - - if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC)) ) - DeferWindowPos(hdwp, hwnd, NULL, filenamelabel_rc.left, filenamelabel_rc.top, 0, 0, - SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); - - if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDOK)) ) - DeferWindowPos(hdwp, hwnd, NULL, open_rc.left, open_rc.top, 0, 0, - SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); - - if(hdwp && This->hmenu_opendropdown && (hwnd = GetDlgItem(This->dlg_hwnd, psh1))) - DeferWindowPos(hdwp, hwnd, NULL, dropdown_rc.left, dropdown_rc.top, 0, 0, - SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); - - if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDCANCEL)) ) - DeferWindowPos(hdwp, hwnd, NULL, cancel_rc.left, cancel_rc.top, 0, 0, - SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); - - if(hdwp) - EndDeferWindowPos(hdwp); - else - ERR("Failed to position dialog controls.\n"); - - return; -} - -static HRESULT init_explorerbrowser(FileDialogImpl *This) -{ - IShellItem *psi_folder; - IObjectWithSite *client; - FOLDERSETTINGS fos; - RECT rc = {0}; - HRESULT hr; - - /* Create ExplorerBrowser instance */ - OleInitialize(NULL); - - hr = CoCreateInstance(&CLSID_ExplorerBrowser, NULL, CLSCTX_INPROC_SERVER, - &IID_IExplorerBrowser, (void**)&This->peb); - if(FAILED(hr)) - { - ERR("Failed to instantiate ExplorerBrowser control.\n"); - return hr; - } - - IExplorerBrowser_SetOptions(This->peb, EBO_SHOWFRAMES | EBO_NOBORDER); - - hr = IExplorerBrowser_Initialize(This->peb, This->dlg_hwnd, &rc, NULL); - if(FAILED(hr)) - { - ERR("Failed to initialize the ExplorerBrowser control.\n"); - IExplorerBrowser_Release(This->peb); - This->peb = NULL; - return hr; - } - hr = IExplorerBrowser_Advise(This->peb, &This->IExplorerBrowserEvents_iface, &This->ebevents_cookie); - if(FAILED(hr)) - ERR("Advise (ExplorerBrowser) failed.\n"); - - /* Get previous options? */ - fos.ViewMode = fos.fFlags = 0; - if(!(This->options & FOS_ALLOWMULTISELECT)) - fos.fFlags |= FWF_SINGLESEL; - - IExplorerBrowser_SetFolderSettings(This->peb, &fos); - - hr = IExplorerBrowser_QueryInterface(This->peb, &IID_IObjectWithSite, (void**)&client); - if (hr == S_OK) - { - hr = IObjectWithSite_SetSite(client, (IUnknown*)&This->IFileDialog2_iface); - IObjectWithSite_Release(client); - if(FAILED(hr)) - ERR("SetSite failed, 0x%08x\n", hr); - } - - /* Browse somewhere */ - psi_folder = This->psi_setfolder ? This->psi_setfolder : This->psi_defaultfolder; - IExplorerBrowser_BrowseToObject(This->peb, (IUnknown*)psi_folder, SBSP_DEFBROWSER); - - return S_OK; -} - -static void init_toolbar(FileDialogImpl *This, HWND hwnd) -{ - HWND htoolbar; - TBADDBITMAP tbab; - TBBUTTON button[2]; - - htoolbar = CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, TBSTYLE_FLAT | WS_CHILD | WS_VISIBLE, - 0, 0, 0, 0, - hwnd, (HMENU)IDC_NAV_TOOLBAR, NULL, NULL); - - tbab.hInst = HINST_COMMCTRL; - tbab.nID = IDB_HIST_LARGE_COLOR; - SendMessageW(htoolbar, TB_ADDBITMAP, 0, (LPARAM)&tbab); - - button[0].iBitmap = HIST_BACK; - button[0].idCommand = IDC_NAVBACK; - button[0].fsState = TBSTATE_ENABLED; - button[0].fsStyle = BTNS_BUTTON; - button[0].dwData = 0; - button[0].iString = 0; - - button[1].iBitmap = HIST_FORWARD; - button[1].idCommand = IDC_NAVFORWARD; - button[1].fsState = TBSTATE_ENABLED; - button[1].fsStyle = BTNS_BUTTON; - button[1].dwData = 0; - button[1].iString = 0; - - SendMessageW(htoolbar, TB_ADDBUTTONSW, 2, (LPARAM)button); - SendMessageW(htoolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(24,24)); - SendMessageW(htoolbar, TB_AUTOSIZE, 0, 0); -} - -static void update_control_text(FileDialogImpl *This) -{ - HWND hitem; - LPCWSTR custom_okbutton; - cctrl_item* item; - UINT min_width = MulDiv(50, This->dpi_x, USER_DEFAULT_SCREEN_DPI); - UINT max_width = MulDiv(250, This->dpi_x, USER_DEFAULT_SCREEN_DPI); - - if(This->custom_title) - SetWindowTextW(This->dlg_hwnd, This->custom_title); - - if(This->hmenu_opendropdown && (item = get_first_item(&This->cctrl_opendropdown))) - custom_okbutton = item->label; - else - custom_okbutton = This->custom_okbutton; - - if(custom_okbutton && - (hitem = GetDlgItem(This->dlg_hwnd, IDOK))) - { - SetWindowTextW(hitem, custom_okbutton); - ctrl_resize(hitem, min_width, max_width, FALSE); - } - - if(This->custom_cancelbutton && - (hitem = GetDlgItem(This->dlg_hwnd, IDCANCEL))) - { - SetWindowTextW(hitem, This->custom_cancelbutton); - ctrl_resize(hitem, min_width, max_width, FALSE); - } - - if(This->custom_filenamelabel && - (hitem = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC))) - { - SetWindowTextW(hitem, This->custom_filenamelabel); - ctrl_resize(hitem, min_width, max_width, FALSE); - } -} - -static LRESULT CALLBACK dropdown_subclass_proc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam) -{ - static const WCHAR prop_this[] = {'i','t','e','m','d','l','g','_','T','h','i','s',0}; - static const WCHAR prop_oldwndproc[] = {'i','t','e','m','d','l','g','_','o','l','d','w','n','d','p','r','o','c',0}; - - if (umessage == WM_LBUTTONDOWN) - { - FileDialogImpl *This = GetPropW(hwnd, prop_this); - - SendMessageW(hwnd, BM_SETCHECK, BST_CHECKED, 0); - show_opendropdown(This); - SendMessageW(hwnd, BM_SETCHECK, BST_UNCHECKED, 0); - - return 0; - } - - return CallWindowProcW((WNDPROC)GetPropW(hwnd, prop_oldwndproc), hwnd, umessage, wparam, lparam); -} - -static LRESULT on_wm_initdialog(HWND hwnd, LPARAM lParam) -{ - FileDialogImpl *This = (FileDialogImpl*)lParam; - HWND hitem; - - TRACE("(%p, %p)\n", This, hwnd); - - SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This); - This->dlg_hwnd = hwnd; - - hitem = GetDlgItem(This->dlg_hwnd, pshHelp); - if(hitem) ShowWindow(hitem, SW_HIDE); - - hitem = GetDlgItem(This->dlg_hwnd, IDC_FILETYPESTATIC); - if(hitem) ShowWindow(hitem, SW_HIDE); - - /* Fill filetypes combobox, or hide it. */ - hitem = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE); - if(This->filterspec_count) - { - HDC hdc; - HFONT font; - SIZE size; - UINT i, maxwidth = 0; - - hdc = GetDC(hitem); - font = (HFONT)SendMessageW(hitem, WM_GETFONT, 0, 0); - SelectObject(hdc, font); - - for(i = 0; i < This->filterspec_count; i++) - { - SendMessageW(hitem, CB_ADDSTRING, 0, (LPARAM)This->filterspecs[i].pszName); - - if(GetTextExtentPoint32W(hdc, This->filterspecs[i].pszName, lstrlenW(This->filterspecs[i].pszName), &size)) - maxwidth = max(maxwidth, size.cx); - } - ReleaseDC(hitem, hdc); - - if(maxwidth > 0) - { - maxwidth += GetSystemMetrics(SM_CXVSCROLL) + 4; - SendMessageW(hitem, CB_SETDROPPEDWIDTH, (WPARAM)maxwidth, 0); - } - else - ERR("Failed to calculate width of filetype dropdown\n"); - - SendMessageW(hitem, CB_SETCURSEL, This->filetypeindex, 0); - } - else - ShowWindow(hitem, SW_HIDE); - - if(This->set_filename && - (hitem = GetDlgItem(This->dlg_hwnd, IDC_FILENAME)) ) - SendMessageW(hitem, WM_SETTEXT, 0, (LPARAM)This->set_filename); - - if(This->hmenu_opendropdown) - { - HWND dropdown_hwnd; - LOGFONTW lfw, lfw_marlett; - HFONT dialog_font; - static const WCHAR marlett[] = {'M','a','r','l','e','t','t',0}; - static const WCHAR prop_this[] = {'i','t','e','m','d','l','g','_','T','h','i','s',0}; - static const WCHAR prop_oldwndproc[] = {'i','t','e','m','d','l','g','_','o','l','d','w','n','d','p','r','o','c',0}; - - dropdown_hwnd = GetDlgItem(This->dlg_hwnd, psh1); - - /* Change dropdown button font to Marlett */ - dialog_font = (HFONT)SendMessageW(dropdown_hwnd, WM_GETFONT, 0, 0); - - GetObjectW(dialog_font, sizeof(lfw), &lfw); - - memset(&lfw_marlett, 0, sizeof(lfw_marlett)); - lstrcpyW(lfw_marlett.lfFaceName, marlett); - lfw_marlett.lfHeight = lfw.lfHeight; - lfw_marlett.lfCharSet = SYMBOL_CHARSET; - - This->hfont_opendropdown = CreateFontIndirectW(&lfw_marlett); - - SendMessageW(dropdown_hwnd, WM_SETFONT, (LPARAM)This->hfont_opendropdown, 0); - - /* Subclass button so we can handle LBUTTONDOWN */ - SetPropW(dropdown_hwnd, prop_this, This); - SetPropW(dropdown_hwnd, prop_oldwndproc, - (HANDLE)SetWindowLongPtrW(dropdown_hwnd, GWLP_WNDPROC, (LONG_PTR)dropdown_subclass_proc)); - } - - ctrl_container_reparent(This, This->dlg_hwnd); - init_explorerbrowser(This); - init_toolbar(This, hwnd); - update_control_text(This); - update_layout(This); - - if(This->filterspec_count) - events_OnTypeChange(This); - - if ((hitem = GetDlgItem(This->dlg_hwnd, IDC_FILENAME))) - SetFocus(hitem); - - return FALSE; -} - -static LRESULT on_wm_size(FileDialogImpl *This) -{ - update_layout(This); - return FALSE; -} - -static LRESULT on_wm_getminmaxinfo(FileDialogImpl *This, LPARAM lparam) -{ - MINMAXINFO *mmi = (MINMAXINFO*)lparam; - TRACE("%p (%p)\n", This, mmi); - - /* FIXME */ - mmi->ptMinTrackSize.x = 640; - mmi->ptMinTrackSize.y = 480; - - return FALSE; -} - -static LRESULT on_wm_destroy(FileDialogImpl *This) -{ - TRACE("%p\n", This); - - if(This->peb) - { - IExplorerBrowser_Destroy(This->peb); - IExplorerBrowser_Release(This->peb); - This->peb = NULL; - } - - ctrl_container_reparent(This, NULL); - This->dlg_hwnd = NULL; - - DeleteObject(This->hfont_opendropdown); - This->hfont_opendropdown = NULL; - - return TRUE; -} - -static LRESULT on_idok(FileDialogImpl *This) -{ - TRACE("%p\n", This); - - if(SUCCEEDED(on_default_action(This))) - EndDialog(This->dlg_hwnd, S_OK); - - return FALSE; -} - -static LRESULT on_idcancel(FileDialogImpl *This) -{ - TRACE("%p\n", This); - - EndDialog(This->dlg_hwnd, HRESULT_FROM_WIN32(ERROR_CANCELLED)); - - return FALSE; -} - -static LRESULT on_command_opendropdown(FileDialogImpl *This, WPARAM wparam, LPARAM lparam) -{ - if(HIWORD(wparam) == BN_CLICKED) - { - HWND hwnd = (HWND)lparam; - SendMessageW(hwnd, BM_SETCHECK, BST_CHECKED, 0); - show_opendropdown(This); - SendMessageW(hwnd, BM_SETCHECK, BST_UNCHECKED, 0); - } - - return FALSE; -} - -static LRESULT on_browse_back(FileDialogImpl *This) -{ - TRACE("%p\n", This); - IExplorerBrowser_BrowseToIDList(This->peb, NULL, SBSP_NAVIGATEBACK); - return FALSE; -} - -static LRESULT on_browse_forward(FileDialogImpl *This) -{ - TRACE("%p\n", This); - IExplorerBrowser_BrowseToIDList(This->peb, NULL, SBSP_NAVIGATEFORWARD); - return FALSE; -} - -static LRESULT on_command_filetype(FileDialogImpl *This, WPARAM wparam, LPARAM lparam) -{ - if(HIWORD(wparam) == CBN_SELCHANGE) - { - IShellView *psv; - HRESULT hr; - LPWSTR filename; - UINT prev_index = This->filetypeindex; - - This->filetypeindex = SendMessageW((HWND)lparam, CB_GETCURSEL, 0, 0); - TRACE("File type selection changed to %d.\n", This->filetypeindex); - - if(prev_index == This->filetypeindex) - return FALSE; - - hr = IExplorerBrowser_GetCurrentView(This->peb, &IID_IShellView, (void**)&psv); - if(SUCCEEDED(hr)) - { - IShellView_Refresh(psv); - IShellView_Release(psv); - } - - if(This->dlg_type == ITEMDLG_TYPE_SAVE && get_file_name(This, &filename)) - { - WCHAR buf[MAX_PATH], extbuf[MAX_PATH], *ext; - - ext = get_first_ext_from_spec(extbuf, This->filterspecs[This->filetypeindex].pszSpec); - if(ext) - { - lstrcpyW(buf, filename); - - if(PathMatchSpecW(buf, This->filterspecs[prev_index].pszSpec)) - PathRemoveExtensionW(buf); - - lstrcatW(buf, ext); - set_file_name(This, buf); - } - CoTaskMemFree(filename); - } - - /* The documentation claims that OnTypeChange is called only - * when the dialog is opened, but this is obviously not the - * case. */ - events_OnTypeChange(This); - } - - return FALSE; -} - -static LRESULT on_wm_command(FileDialogImpl *This, WPARAM wparam, LPARAM lparam) -{ - switch(LOWORD(wparam)) - { - case IDOK: return on_idok(This); - case IDCANCEL: return on_idcancel(This); - case psh1: return on_command_opendropdown(This, wparam, lparam); - case IDC_NAVBACK: return on_browse_back(This); - case IDC_NAVFORWARD: return on_browse_forward(This); - case IDC_FILETYPE: return on_command_filetype(This, wparam, lparam); - default: TRACE("Unknown command.\n"); - } - return FALSE; -} - -static LRESULT CALLBACK itemdlg_dlgproc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam) -{ - FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA); - - switch(umessage) - { - case WM_INITDIALOG: return on_wm_initdialog(hwnd, lparam); - case WM_COMMAND: return on_wm_command(This, wparam, lparam); - case WM_SIZE: return on_wm_size(This); - case WM_GETMINMAXINFO: return on_wm_getminmaxinfo(This, lparam); - case WM_DESTROY: return on_wm_destroy(This); - } - - return FALSE; -} - -// Converts Windows Vista IFileDialog filters to Windows XP OpenFileNameW filters. Returns a pointer to a string. -LPWSTR ConvertVistaFiltersToXPFilters(COMDLG_FILTERSPEC *VistaFilters, DWORD FilterAmount) { - size_t Size = 1 + FilterAmount * 2; // double null termination - LPWSTR Pointer; - LPWSTR CurrentPointer; - size_t StrLength; - DWORD i; - for (i = 0; i < FilterAmount; i++) { - COMDLG_FILTERSPEC Filter = VistaFilters[i]; - Size += wcslen(Filter.pszName); - Size += wcslen(Filter.pszSpec); - } - - Pointer = HeapAlloc(GetProcessHeap(), 8, Size * 2); - - if (!Pointer) - return NULL; - - CurrentPointer = Pointer; - for (i = 0; i < FilterAmount; i++) { - COMDLG_FILTERSPEC Filter = VistaFilters[i]; - StrLength = wcslen(Filter.pszName); - memcpy(CurrentPointer, Filter.pszName, StrLength * 2); - CurrentPointer += StrLength + 1; - StrLength = wcslen(Filter.pszSpec); - memcpy(CurrentPointer, Filter.pszSpec, StrLength * 2); - CurrentPointer += StrLength + 1; - } - - return Pointer; -} - -/*********************************************************************** - * GetPidlFromName - * - * returns the pidl of the file name relative to folder - * NULL if an error occurred - */ -static LPITEMIDLIST GetPidlFromName(IShellFolder *lpsf,LPWSTR lpcstrFileName) -{ - LPITEMIDLIST pidl = NULL; - ULONG ulEaten; - - TRACE("sf=%p file=%s\n", lpsf, debugstr_w(lpcstrFileName)); - - if(!lpcstrFileName) return NULL; - if(!*lpcstrFileName) return NULL; - - if(!lpsf) - { - if (SUCCEEDED(SHGetDesktopFolder(&lpsf))) { - IShellFolder_ParseDisplayName(lpsf, 0, NULL, lpcstrFileName, &ulEaten, &pidl, NULL); - IShellFolder_Release(lpsf); - } - } - else - { - IShellFolder_ParseDisplayName(lpsf, 0, NULL, lpcstrFileName, &ulEaten, &pidl, NULL); - } - return pidl; -} - -DWORD ConvertFileDialogFlagsToOpenFileNameFlags(FILEOPENDIALOGOPTIONS options){ - DWORD Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_ALLOWMULTISELECT; - - if(options & FOS_ALLOWMULTISELECT) - { - Flags |= OFN_ALLOWMULTISELECT; - } - if(options & FOS_OVERWRITEPROMPT) - { - Flags |= OFN_OVERWRITEPROMPT; - } - if(options & FOS_CREATEPROMPT) - { - Flags |= OFN_CREATEPROMPT; - } - if(options & FOS_DONTADDTORECENT) - { - Flags |= OFN_DONTADDTORECENT; - } - if(options & FOS_FORCESHOWHIDDEN) - { - Flags |= OFN_FORCESHOWHIDDEN; - } - if(options & FOS_NOCHANGEDIR) - { - Flags |= OFN_NOCHANGEDIR; - } - if(options & FOS_NODEREFERENCELINKS) - { - Flags |= OFN_NODEREFERENCELINKS; - } - if(options & FOS_NOTESTFILECREATE) - { - Flags |= OFN_NOTESTFILECREATE; - } - if(options & FOS_NOVALIDATE) - { - Flags |= OFN_NOVALIDATE; - } - if(options & FOS_PATHMUSTEXIST) - { - Flags |= OFN_PATHMUSTEXIST; - } - if(options & FOS_SHAREAWARE) - { - Flags |= OFN_SHAREAWARE; - } - - return Flags; -} - -static HRESULT create_dialog(FileDialogImpl *This, HWND parent) -{ - INT_PTR res; - OPENFILENAMEW ofn; - LPWSTR szDir; - LPWSTR fileName; - BROWSEINFOW bInfo; - UINT cFileTypes = This->filterspec_count; - HRESULT hr; - PIDLIST_ABSOLUTE idListAbolute = NULL; - IShellItem* ppsi; - wchar_t* currentPart; - wchar_t fullPath[MAX_PATH]; - wchar_t* folderPath; - int countFiles; - int i; - PCIDLIST_ABSOLUTE *pidlArray = NULL; - PIDLIST_ABSOLUTE pidlCurrent; - - fileName = (LPWSTR)HeapAlloc(GetProcessHeap(), 8, MAX_PATH * 2); - - if(This->set_filename) - { - //memcpy(fileName, This->set_filename, MAX_PATH * 2); - wcscpy(fileName, This->set_filename); - } - - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = parent; - ofn.hInstance = COMDLG32_hInstance; - ofn.lpstrFilter = (LPCWSTR)ConvertVistaFiltersToXPFilters(This->filterspecs, cFileTypes);//L"Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; - ofn.lpstrFile = (LPWSTR)fileName; - ofn.lpstrTitle = (LPWSTR)This->custom_title; - ofn.nMaxFile = MAX_PATH; - ofn.Flags = ConvertFileDialogFlagsToOpenFileNameFlags(This->options); - ofn.lpstrDefExt = (LPCWSTR)This->default_ext; - - if(This->options & FOS_PICKFOLDERS) - { - CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); - - szDir = (LPWSTR)HeapAlloc(GetProcessHeap(), 8, MAX_PATH * 2); - bInfo.hwndOwner = parent; - bInfo.pidlRoot = NULL; - bInfo.pszDisplayName = szDir; // Address of a buffer to receive the display name of the folder selected by the user - bInfo.lpszTitle = This->custom_title?This->custom_title:L"Please, select a folder"; // Title of the dialog - bInfo.ulFlags = 0 ; - bInfo.lpfn = NULL; - bInfo.lParam = 0; - bInfo.iImage = -1; - This->lpItem = SHBrowseForFolderW(&bInfo); - }else{ - if(This->dlg_type == ITEMDLG_TYPE_OPEN) - { - ofn.Flags |= OFN_FILEMUSTEXIST; - res = GetOpenFileNameW(&ofn); - } - if(This->dlg_type == ITEMDLG_TYPE_SAVE) - { - ofn.Flags |= OFN_NOREADONLYRETURN; - res = GetSaveFileNameW(&ofn); - } - } - - if(res || This->lpItem){ - // Inicializa a COM (Component Object Model) - CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); - - if(This->options & FOS_PICKFOLDERS){ - if(This->lpItem) - { - hr = SHCreateItemFromIDList(This->lpItem, &IID_IShellItem, (void**)&ppsi); - DbgPrint("create_dialog::SHCreateItemFromIDList return: %08x\n", hr); - } - }else{ - if(fileName){ - if(This->dlg_type == ITEMDLG_TYPE_OPEN) - { - if(This->options & FOS_ALLOWMULTISELECT) - { - folderPath = (wchar_t*)fileName; - currentPart = (wchar_t*)folderPath; - countFiles = 0; - - currentPart += wcslen(currentPart) + 1; - - if(currentPart){ - while (*currentPart != L'\0') { - if (PathCombineW(fullPath, folderPath, currentPart)) { - pidlCurrent = NULL; - // Cria um PIDLIST_ABSOLUTE para o caminho atual - hr = SHParseDisplayName(fullPath, NULL, &pidlCurrent, 0, NULL); - // Aloca memória para o novo caminho na lista - pidlArray = (PIDLIST_ABSOLUTE*)CoTaskMemRealloc(pidlArray, sizeof(PIDLIST_ABSOLUTE) * (countFiles + 1)); - // Adiciona o PIDLIST_ABSOLUTE à lista - pidlArray[countFiles] = pidlCurrent; - countFiles++; - } - currentPart += wcslen(currentPart) + 1; - } - }else{ - countFiles++; - } - if(pidlArray && countFiles > 1) - { - hr = SHCreateShellItemArrayFromIDLists(countFiles, pidlArray, &This->psia_results); - This->set_filename = NULL; - for (i = 0; i < countFiles; i++) - { - CoTaskMemFree(pidlArray[i]); - } - - // Libera o array - LocalFree(pidlArray); - LocalFree(pidlCurrent); - return hr; - } - } - - hr = SHCreateItemFromParsingName(fileName, NULL, &IID_IShellItem, (void**)&ppsi); - } - if(This->dlg_type == ITEMDLG_TYPE_SAVE) - { - DbgPrint("create_dialog::This->set_filename atual %ws\n", fileName); - idListAbolute = SHSimpleIDListFromPath(fileName); - - if(idListAbolute){ - hr = SHCreateItemFromIDList(idListAbolute, &IID_IShellItem, (void**)&ppsi); - } - } - } - } - - // Cria um IShellItemArray a partir do IShellItem - hr = SHCreateShellItemArrayFromShellItem(ppsi, &IID_IShellItemArray, (void**)&This->psia_results); - - DbgPrint("create_dialog::SHCreateShellItemArrayFromShellItem return: %08x\n", hr); - return hr; - } - - return E_UNEXPECTED; -} - -/************************************************************************** - * IFileDialog implementation - */ -static inline FileDialogImpl *impl_from_IFileDialog2(IFileDialog2 *iface) -{ - return CONTAINING_RECORD(iface, FileDialogImpl, IFileDialog2_iface); -} - -static HRESULT WINAPI IFileDialog2_fnQueryInterface(IFileDialog2 *iface, - REFIID riid, - void **ppvObject) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%s, %p)\n", This, debugstr_guid(riid), ppvObject); - - *ppvObject = NULL; - if(IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IFileDialog) || - IsEqualGUID(riid, &IID_IFileDialog2)) - { - *ppvObject = iface; - } - else if(IsEqualGUID(riid, &IID_IFileOpenDialog) && This->dlg_type == ITEMDLG_TYPE_OPEN) - { - *ppvObject = &This->u.IFileOpenDialog_iface; - } - else if(IsEqualGUID(riid, &IID_IFileSaveDialog) && This->dlg_type == ITEMDLG_TYPE_SAVE) - { - *ppvObject = &This->u.IFileSaveDialog_iface; - } - else if(IsEqualGUID(riid, &IID_IExplorerBrowserEvents)) - { - *ppvObject = &This->IExplorerBrowserEvents_iface; - } - else if(IsEqualGUID(riid, &IID_IServiceProvider)) - { - *ppvObject = &This->IServiceProvider_iface; - } - else if(IsEqualGUID(&IID_ICommDlgBrowser3, riid) || - IsEqualGUID(&IID_ICommDlgBrowser2, riid) || - IsEqualGUID(&IID_ICommDlgBrowser, riid)) - { - *ppvObject = &This->ICommDlgBrowser3_iface; - } - else if(IsEqualGUID(&IID_IOleWindow, riid)) - { - *ppvObject = &This->IOleWindow_iface; - } - else if(IsEqualGUID(riid, &IID_IFileDialogCustomize) || - IsEqualGUID(riid, &IID_IFileDialogCustomizeAlt)) - { - *ppvObject = &This->IFileDialogCustomize_iface; - } - else - FIXME("Unknown interface requested: %s.\n", debugstr_guid(riid)); - - if(*ppvObject) - { - IUnknown_AddRef((IUnknown*)*ppvObject); - return S_OK; - } - - return E_NOINTERFACE; -} - -static ULONG WINAPI IFileDialog2_fnAddRef(IFileDialog2 *iface) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - LONG ref = InterlockedIncrement(&This->ref); - TRACE("%p - ref %d\n", This, ref); - - return ref; -} - -static ULONG WINAPI IFileDialog2_fnRelease(IFileDialog2 *iface) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - LONG ref = InterlockedDecrement(&This->ref); - TRACE("%p - ref %d\n", This, ref); - - if(!ref) - { - UINT i; - for(i = 0; i < This->filterspec_count; i++) - { - LocalFree((void*)This->filterspecs[i].pszName); - LocalFree((void*)This->filterspecs[i].pszSpec); - } - HeapFree(GetProcessHeap(), 0, This->filterspecs); - - DestroyWindow(This->cctrls_hwnd); - - if(This->psi_defaultfolder) IShellItem_Release(This->psi_defaultfolder); - if(This->psi_setfolder) IShellItem_Release(This->psi_setfolder); - if(This->psi_folder) IShellItem_Release(This->psi_folder); - if(This->psia_selection) IShellItemArray_Release(This->psia_selection); - if(This->psia_results) IShellItemArray_Release(This->psia_results); - - LocalFree(This->set_filename); - LocalFree(This->default_ext); - LocalFree(This->custom_title); - LocalFree(This->custom_okbutton); - LocalFree(This->custom_cancelbutton); - LocalFree(This->custom_filenamelabel); - - DestroyMenu(This->hmenu_opendropdown); - DeleteObject(This->hfont_opendropdown); - - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI IFileDialog2_fnShow(IFileDialog2 *iface, HWND hwndOwner) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%p)\n", iface, hwndOwner); - - This->opendropdown_has_selection = FALSE; - - return create_dialog(This, hwndOwner); -} - -static HRESULT WINAPI IFileDialog2_fnSetFileTypes(IFileDialog2 *iface, UINT cFileTypes, - const COMDLG_FILTERSPEC *rgFilterSpec) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - UINT i; - TRACE("%p (%d, %p)\n", This, cFileTypes, rgFilterSpec); - - if(This->filterspecs) - return E_UNEXPECTED; - - if(!rgFilterSpec) - return E_INVALIDARG; - - if(!cFileTypes) - return S_OK; - - This->filterspecs = HeapAlloc(GetProcessHeap(), 0, sizeof(COMDLG_FILTERSPEC)*cFileTypes); - for(i = 0; i < cFileTypes; i++) - { - This->filterspecs[i].pszName = StrDupW(rgFilterSpec[i].pszName); - This->filterspecs[i].pszSpec = StrDupW(rgFilterSpec[i].pszSpec); - } - This->filterspec_count = cFileTypes; - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnSetFileTypeIndex(IFileDialog2 *iface, UINT iFileType) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%d)\n", This, iFileType); - - if(!This->filterspecs) - return E_FAIL; - - iFileType = max(iFileType, 1); - iFileType = min(iFileType, This->filterspec_count); - This->filetypeindex = iFileType-1; - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnGetFileTypeIndex(IFileDialog2 *iface, UINT *piFileType) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%p)\n", This, piFileType); - - if(!piFileType) - return E_INVALIDARG; - - if(This->filterspec_count == 0) - *piFileType = 0; - else - *piFileType = This->filetypeindex + 1; - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnAdvise(IFileDialog2 *iface, IFileDialogEvents *pfde, DWORD *pdwCookie) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - events_client *client; - TRACE("%p (%p, %p)\n", This, pfde, pdwCookie); - - if(!pfde || !pdwCookie) - return E_INVALIDARG; - - client = HeapAlloc(GetProcessHeap(), 0, sizeof(events_client)); - client->pfde = pfde; - client->cookie = ++This->events_next_cookie; - - IFileDialogEvents_AddRef(pfde); - *pdwCookie = client->cookie; - - list_add_tail(&This->events_clients, &client->entry); - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnUnadvise(IFileDialog2 *iface, DWORD dwCookie) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - events_client *client, *found = NULL; - TRACE("%p (%d)\n", This, dwCookie); - - LIST_FOR_EACH_ENTRY(client, &This->events_clients, events_client, entry) - { - if(client->cookie == dwCookie) - { - found = client; - break; - } - } - - if(found) - { - list_remove(&found->entry); - IFileDialogEvents_Release(found->pfde); - HeapFree(GetProcessHeap(), 0, found); - return S_OK; - } - - return E_INVALIDARG; -} - -static HRESULT WINAPI IFileDialog2_fnSetOptions(IFileDialog2 *iface, FILEOPENDIALOGOPTIONS fos) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (0x%x)\n", This, fos); - - if (fos & ~(FOS_OVERWRITEPROMPT | FOS_STRICTFILETYPES | FOS_NOCHANGEDIR | FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM - | FOS_ALLNONSTORAGEITEMS | FOS_NOVALIDATE | FOS_ALLOWMULTISELECT | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST - | FOS_CREATEPROMPT | FOS_SHAREAWARE | FOS_NOREADONLYRETURN | FOS_NOTESTFILECREATE | FOS_HIDEMRUPLACES - | FOS_HIDEPINNEDPLACES | FOS_NODEREFERENCELINKS | FOS_DONTADDTORECENT | FOS_FORCESHOWHIDDEN - | FOS_DEFAULTNOMINIMODE | FOS_FORCEPREVIEWPANEON | FOS_SUPPORTSTREAMABLEITEMS)) - { - WARN("Invalid option %#x\n", fos); - return E_INVALIDARG; - } - - if( !(This->options & FOS_PICKFOLDERS) && (fos & FOS_PICKFOLDERS) ) - { - WCHAR buf[30]; - LoadStringW(COMDLG32_hInstance, IDS_SELECT_FOLDER, buf, ARRAY_SIZE(buf)); - IFileDialog2_SetTitle(iface, buf); - } - - This->options = fos; - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnGetOptions(IFileDialog2 *iface, FILEOPENDIALOGOPTIONS *pfos) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%p)\n", This, pfos); - - if(!pfos) - return E_INVALIDARG; - - *pfos = This->options; - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnSetDefaultFolder(IFileDialog2 *iface, IShellItem *psi) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%p)\n", This, psi); - if(This->psi_defaultfolder) - IShellItem_Release(This->psi_defaultfolder); - - This->psi_defaultfolder = psi; - - if(This->psi_defaultfolder) - IShellItem_AddRef(This->psi_defaultfolder); - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnSetFolder(IFileDialog2 *iface, IShellItem *psi) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%p)\n", This, psi); - if(This->psi_setfolder) - IShellItem_Release(This->psi_setfolder); - - This->psi_setfolder = psi; - - if(This->psi_setfolder) - IShellItem_AddRef(This->psi_setfolder); - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnGetFolder(IFileDialog2 *iface, IShellItem **ppsi) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%p)\n", This, ppsi); - if(!ppsi) - return E_INVALIDARG; - - /* FIXME: - If the dialog is shown, return the current(ly selected) folder. */ - - *ppsi = NULL; - if(This->psi_folder) - *ppsi = This->psi_folder; - else if(This->psi_setfolder) - *ppsi = This->psi_setfolder; - else if(This->psi_defaultfolder) - *ppsi = This->psi_defaultfolder; - - if(*ppsi) - { - IShellItem_AddRef(*ppsi); - return S_OK; - } - - return E_FAIL; -} - -static HRESULT WINAPI IFileDialog2_fnGetCurrentSelection(IFileDialog2 *iface, IShellItem **ppsi) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - HRESULT hr; - TRACE("%p (%p)\n", This, ppsi); - - if(!ppsi) - return E_INVALIDARG; - - if(This->psia_selection) - { - /* FIXME: Check filename edit box */ - hr = IShellItemArray_GetItemAt(This->psia_selection, 0, ppsi); - return hr; - } - - return E_FAIL; -} - -static HRESULT WINAPI IFileDialog2_fnSetFileName(IFileDialog2 *iface, LPCWSTR pszName) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%s)\n", iface, debugstr_w(pszName)); - - set_file_name(This, pszName); - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnGetFileName(IFileDialog2 *iface, LPWSTR *pszName) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%p)\n", iface, pszName); - - if(!pszName) - return E_INVALIDARG; - - *pszName = NULL; - get_file_name(This, pszName); - return *pszName ? S_OK : E_FAIL; -} - -static HRESULT WINAPI IFileDialog2_fnSetTitle(IFileDialog2 *iface, LPCWSTR pszTitle) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%s)\n", This, debugstr_w(pszTitle)); - - LocalFree(This->custom_title); - This->custom_title = StrDupW(pszTitle); - update_control_text(This); - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnSetOkButtonLabel(IFileDialog2 *iface, LPCWSTR pszText) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%s)\n", This, debugstr_w(pszText)); - - LocalFree(This->custom_okbutton); - This->custom_okbutton = StrDupW(pszText); - update_control_text(This); - update_layout(This); - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnSetFileNameLabel(IFileDialog2 *iface, LPCWSTR pszLabel) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%s)\n", This, debugstr_w(pszLabel)); - - LocalFree(This->custom_filenamelabel); - This->custom_filenamelabel = StrDupW(pszLabel); - update_control_text(This); - update_layout(This); - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnGetResult(IFileDialog2 *iface, IShellItem **ppsi) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - HRESULT hr; - - if(This->psia_results) - { - UINT item_count; - hr = IShellItemArray_GetCount(This->psia_results, &item_count); - if(SUCCEEDED(hr)) - { - if(item_count != 1) - return E_FAIL; - - /* Adds a reference. */ - hr = IShellItemArray_GetItemAt(This->psia_results, 0, ppsi); - } - - return hr; - } - - return E_UNEXPECTED; -} - -static HRESULT WINAPI IFileDialog2_fnAddPlace(IFileDialog2 *iface, IShellItem *psi, FDAP fdap) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - FIXME("stub - %p (%p, %d)\n", This, psi, fdap); - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnSetDefaultExtension(IFileDialog2 *iface, LPCWSTR pszDefaultExtension) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%s)\n", This, debugstr_w(pszDefaultExtension)); - - LocalFree(This->default_ext); - This->default_ext = StrDupW(pszDefaultExtension); - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnClose(IFileDialog2 *iface, HRESULT hr) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (0x%08x)\n", This, hr); - - if(This->dlg_hwnd) - EndDialog(This->dlg_hwnd, hr); - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnSetClientGuid(IFileDialog2 *iface, REFGUID guid) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%s)\n", This, debugstr_guid(guid)); - This->client_guid = *guid; - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnClearClientData(IFileDialog2 *iface) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - FIXME("stub - %p\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI IFileDialog2_fnSetFilter(IFileDialog2 *iface, IShellItemFilter *pFilter) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - FIXME("stub - %p (%p)\n", This, pFilter); - return E_NOTIMPL; -} - -static HRESULT WINAPI IFileDialog2_fnSetCancelButtonLabel(IFileDialog2 *iface, LPCWSTR pszLabel) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - TRACE("%p (%s)\n", This, debugstr_w(pszLabel)); - - LocalFree(This->custom_cancelbutton); - This->custom_cancelbutton = StrDupW(pszLabel); - update_control_text(This); - update_layout(This); - - return S_OK; -} - -static HRESULT WINAPI IFileDialog2_fnSetNavigationRoot(IFileDialog2 *iface, IShellItem *psi) -{ - FileDialogImpl *This = impl_from_IFileDialog2(iface); - FIXME("stub - %p (%p)\n", This, psi); - return E_NOTIMPL; -} - -static const IFileDialog2Vtbl vt_IFileDialog2 = { - IFileDialog2_fnQueryInterface, - IFileDialog2_fnAddRef, - IFileDialog2_fnRelease, - IFileDialog2_fnShow, - IFileDialog2_fnSetFileTypes, - IFileDialog2_fnSetFileTypeIndex, - IFileDialog2_fnGetFileTypeIndex, - IFileDialog2_fnAdvise, - IFileDialog2_fnUnadvise, - IFileDialog2_fnSetOptions, - IFileDialog2_fnGetOptions, - IFileDialog2_fnSetDefaultFolder, - IFileDialog2_fnSetFolder, - IFileDialog2_fnGetFolder, - IFileDialog2_fnGetCurrentSelection, - IFileDialog2_fnSetFileName, - IFileDialog2_fnGetFileName, - IFileDialog2_fnSetTitle, - IFileDialog2_fnSetOkButtonLabel, - IFileDialog2_fnSetFileNameLabel, - IFileDialog2_fnGetResult, - IFileDialog2_fnAddPlace, - IFileDialog2_fnSetDefaultExtension, - IFileDialog2_fnClose, - IFileDialog2_fnSetClientGuid, - IFileDialog2_fnClearClientData, - IFileDialog2_fnSetFilter, - IFileDialog2_fnSetCancelButtonLabel, - IFileDialog2_fnSetNavigationRoot -}; - -/************************************************************************** - * IFileOpenDialog - */ -static inline FileDialogImpl *impl_from_IFileOpenDialog(IFileOpenDialog *iface) -{ - return CONTAINING_RECORD(iface, FileDialogImpl, u.IFileOpenDialog_iface); -} - -static HRESULT WINAPI IFileOpenDialog_fnQueryInterface(IFileOpenDialog *iface, - REFIID riid, void **ppvObject) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject); -} - -static ULONG WINAPI IFileOpenDialog_fnAddRef(IFileOpenDialog *iface) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_AddRef(&This->IFileDialog2_iface); -} - -static ULONG WINAPI IFileOpenDialog_fnRelease(IFileOpenDialog *iface) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_Release(&This->IFileDialog2_iface); -} - -static HRESULT WINAPI IFileOpenDialog_fnShow(IFileOpenDialog *iface, HWND hwndOwner) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_Show(&This->IFileDialog2_iface, hwndOwner); -} - -static HRESULT WINAPI IFileOpenDialog_fnSetFileTypes(IFileOpenDialog *iface, UINT cFileTypes, - const COMDLG_FILTERSPEC *rgFilterSpec) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_SetFileTypes(&This->IFileDialog2_iface, cFileTypes, rgFilterSpec); -} - -static HRESULT WINAPI IFileOpenDialog_fnSetFileTypeIndex(IFileOpenDialog *iface, UINT iFileType) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_SetFileTypeIndex(&This->IFileDialog2_iface, iFileType); -} - -static HRESULT WINAPI IFileOpenDialog_fnGetFileTypeIndex(IFileOpenDialog *iface, UINT *piFileType) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_GetFileTypeIndex(&This->IFileDialog2_iface, piFileType); -} - -static HRESULT WINAPI IFileOpenDialog_fnAdvise(IFileOpenDialog *iface, IFileDialogEvents *pfde, - DWORD *pdwCookie) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_Advise(&This->IFileDialog2_iface, pfde, pdwCookie); -} - -static HRESULT WINAPI IFileOpenDialog_fnUnadvise(IFileOpenDialog *iface, DWORD dwCookie) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_Unadvise(&This->IFileDialog2_iface, dwCookie); -} - -static HRESULT WINAPI IFileOpenDialog_fnSetOptions(IFileOpenDialog *iface, FILEOPENDIALOGOPTIONS fos) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_SetOptions(&This->IFileDialog2_iface, fos); -} - -static HRESULT WINAPI IFileOpenDialog_fnGetOptions(IFileOpenDialog *iface, FILEOPENDIALOGOPTIONS *pfos) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_GetOptions(&This->IFileDialog2_iface, pfos); -} - -static HRESULT WINAPI IFileOpenDialog_fnSetDefaultFolder(IFileOpenDialog *iface, IShellItem *psi) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_SetDefaultFolder(&This->IFileDialog2_iface, psi); -} - -static HRESULT WINAPI IFileOpenDialog_fnSetFolder(IFileOpenDialog *iface, IShellItem *psi) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_SetFolder(&This->IFileDialog2_iface, psi); -} - -static HRESULT WINAPI IFileOpenDialog_fnGetFolder(IFileOpenDialog *iface, IShellItem **ppsi) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_GetFolder(&This->IFileDialog2_iface, ppsi); -} - -static HRESULT WINAPI IFileOpenDialog_fnGetCurrentSelection(IFileOpenDialog *iface, IShellItem **ppsi) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_GetCurrentSelection(&This->IFileDialog2_iface, ppsi); -} - -static HRESULT WINAPI IFileOpenDialog_fnSetFileName(IFileOpenDialog *iface, LPCWSTR pszName) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_SetFileName(&This->IFileDialog2_iface, pszName); -} - -static HRESULT WINAPI IFileOpenDialog_fnGetFileName(IFileOpenDialog *iface, LPWSTR *pszName) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_GetFileName(&This->IFileDialog2_iface, pszName); -} - -static HRESULT WINAPI IFileOpenDialog_fnSetTitle(IFileOpenDialog *iface, LPCWSTR pszTitle) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_SetTitle(&This->IFileDialog2_iface, pszTitle); -} - -static HRESULT WINAPI IFileOpenDialog_fnSetOkButtonLabel(IFileOpenDialog *iface, LPCWSTR pszText) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_SetOkButtonLabel(&This->IFileDialog2_iface, pszText); -} - -static HRESULT WINAPI IFileOpenDialog_fnSetFileNameLabel(IFileOpenDialog *iface, LPCWSTR pszLabel) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_SetFileNameLabel(&This->IFileDialog2_iface, pszLabel); -} - -static HRESULT WINAPI IFileOpenDialog_fnGetResult(IFileOpenDialog *iface, IShellItem **ppsi) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_GetResult(&This->IFileDialog2_iface, ppsi); -} - -static HRESULT WINAPI IFileOpenDialog_fnAddPlace(IFileOpenDialog *iface, IShellItem *psi, FDAP fdap) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_AddPlace(&This->IFileDialog2_iface, psi, fdap); -} - -static HRESULT WINAPI IFileOpenDialog_fnSetDefaultExtension(IFileOpenDialog *iface, - LPCWSTR pszDefaultExtension) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_SetDefaultExtension(&This->IFileDialog2_iface, pszDefaultExtension); -} - -static HRESULT WINAPI IFileOpenDialog_fnClose(IFileOpenDialog *iface, HRESULT hr) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_Close(&This->IFileDialog2_iface, hr); -} - -static HRESULT WINAPI IFileOpenDialog_fnSetClientGuid(IFileOpenDialog *iface, REFGUID guid) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_SetClientGuid(&This->IFileDialog2_iface, guid); -} - -static HRESULT WINAPI IFileOpenDialog_fnClearClientData(IFileOpenDialog *iface) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_ClearClientData(&This->IFileDialog2_iface); -} - -static HRESULT WINAPI IFileOpenDialog_fnSetFilter(IFileOpenDialog *iface, IShellItemFilter *pFilter) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - return IFileDialog2_SetFilter(&This->IFileDialog2_iface, pFilter); -} - -static HRESULT WINAPI IFileOpenDialog_fnGetResults(IFileOpenDialog *iface, IShellItemArray **ppenum) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - TRACE("%p (%p)\n", This, ppenum); - - *ppenum = This->psia_results; - - if(*ppenum) - { - IShellItemArray_AddRef(*ppenum); - return S_OK; - } - - return E_FAIL; -} - -static HRESULT WINAPI IFileOpenDialog_fnGetSelectedItems(IFileOpenDialog *iface, IShellItemArray **ppsai) -{ - FileDialogImpl *This = impl_from_IFileOpenDialog(iface); - TRACE("%p (%p)\n", This, ppsai); - - if(This->psia_selection) - { - *ppsai = This->psia_selection; - IShellItemArray_AddRef(*ppsai); - return S_OK; - } - - return E_FAIL; -} - -static const IFileOpenDialogVtbl vt_IFileOpenDialog = { - IFileOpenDialog_fnQueryInterface, - IFileOpenDialog_fnAddRef, - IFileOpenDialog_fnRelease, - IFileOpenDialog_fnShow, - IFileOpenDialog_fnSetFileTypes, - IFileOpenDialog_fnSetFileTypeIndex, - IFileOpenDialog_fnGetFileTypeIndex, - IFileOpenDialog_fnAdvise, - IFileOpenDialog_fnUnadvise, - IFileOpenDialog_fnSetOptions, - IFileOpenDialog_fnGetOptions, - IFileOpenDialog_fnSetDefaultFolder, - IFileOpenDialog_fnSetFolder, - IFileOpenDialog_fnGetFolder, - IFileOpenDialog_fnGetCurrentSelection, - IFileOpenDialog_fnSetFileName, - IFileOpenDialog_fnGetFileName, - IFileOpenDialog_fnSetTitle, - IFileOpenDialog_fnSetOkButtonLabel, - IFileOpenDialog_fnSetFileNameLabel, - IFileOpenDialog_fnGetResult, - IFileOpenDialog_fnAddPlace, - IFileOpenDialog_fnSetDefaultExtension, - IFileOpenDialog_fnClose, - IFileOpenDialog_fnSetClientGuid, - IFileOpenDialog_fnClearClientData, - IFileOpenDialog_fnSetFilter, - IFileOpenDialog_fnGetResults, - IFileOpenDialog_fnGetSelectedItems -}; - -/************************************************************************** - * IFileSaveDialog - */ -static inline FileDialogImpl *impl_from_IFileSaveDialog(IFileSaveDialog *iface) -{ - return CONTAINING_RECORD(iface, FileDialogImpl, u.IFileSaveDialog_iface); -} - -static HRESULT WINAPI IFileSaveDialog_fnQueryInterface(IFileSaveDialog *iface, - REFIID riid, - void **ppvObject) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject); -} - -static ULONG WINAPI IFileSaveDialog_fnAddRef(IFileSaveDialog *iface) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_AddRef(&This->IFileDialog2_iface); -} - -static ULONG WINAPI IFileSaveDialog_fnRelease(IFileSaveDialog *iface) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_Release(&This->IFileDialog2_iface); -} - -static HRESULT WINAPI IFileSaveDialog_fnShow(IFileSaveDialog *iface, HWND hwndOwner) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_Show(&This->IFileDialog2_iface, hwndOwner); -} - -static HRESULT WINAPI IFileSaveDialog_fnSetFileTypes(IFileSaveDialog *iface, UINT cFileTypes, - const COMDLG_FILTERSPEC *rgFilterSpec) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_SetFileTypes(&This->IFileDialog2_iface, cFileTypes, rgFilterSpec); -} - -static HRESULT WINAPI IFileSaveDialog_fnSetFileTypeIndex(IFileSaveDialog *iface, UINT iFileType) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_SetFileTypeIndex(&This->IFileDialog2_iface, iFileType); -} - -static HRESULT WINAPI IFileSaveDialog_fnGetFileTypeIndex(IFileSaveDialog *iface, UINT *piFileType) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_GetFileTypeIndex(&This->IFileDialog2_iface, piFileType); -} - -static HRESULT WINAPI IFileSaveDialog_fnAdvise(IFileSaveDialog *iface, IFileDialogEvents *pfde, - DWORD *pdwCookie) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_Advise(&This->IFileDialog2_iface, pfde, pdwCookie); -} - -static HRESULT WINAPI IFileSaveDialog_fnUnadvise(IFileSaveDialog *iface, DWORD dwCookie) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_Unadvise(&This->IFileDialog2_iface, dwCookie); -} - -static HRESULT WINAPI IFileSaveDialog_fnSetOptions(IFileSaveDialog *iface, FILEOPENDIALOGOPTIONS fos) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_SetOptions(&This->IFileDialog2_iface, fos); -} - -static HRESULT WINAPI IFileSaveDialog_fnGetOptions(IFileSaveDialog *iface, FILEOPENDIALOGOPTIONS *pfos) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_GetOptions(&This->IFileDialog2_iface, pfos); -} - -static HRESULT WINAPI IFileSaveDialog_fnSetDefaultFolder(IFileSaveDialog *iface, IShellItem *psi) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_SetDefaultFolder(&This->IFileDialog2_iface, psi); -} - -static HRESULT WINAPI IFileSaveDialog_fnSetFolder(IFileSaveDialog *iface, IShellItem *psi) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_SetFolder(&This->IFileDialog2_iface, psi); -} - -static HRESULT WINAPI IFileSaveDialog_fnGetFolder(IFileSaveDialog *iface, IShellItem **ppsi) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_GetFolder(&This->IFileDialog2_iface, ppsi); -} - -static HRESULT WINAPI IFileSaveDialog_fnGetCurrentSelection(IFileSaveDialog *iface, IShellItem **ppsi) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_GetCurrentSelection(&This->IFileDialog2_iface, ppsi); -} - -static HRESULT WINAPI IFileSaveDialog_fnSetFileName(IFileSaveDialog *iface, LPCWSTR pszName) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_SetFileName(&This->IFileDialog2_iface, pszName); -} - -static HRESULT WINAPI IFileSaveDialog_fnGetFileName(IFileSaveDialog *iface, LPWSTR *pszName) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_GetFileName(&This->IFileDialog2_iface, pszName); -} - -static HRESULT WINAPI IFileSaveDialog_fnSetTitle(IFileSaveDialog *iface, LPCWSTR pszTitle) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_SetTitle(&This->IFileDialog2_iface, pszTitle); -} - -static HRESULT WINAPI IFileSaveDialog_fnSetOkButtonLabel(IFileSaveDialog *iface, LPCWSTR pszText) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_SetOkButtonLabel(&This->IFileDialog2_iface, pszText); -} - -static HRESULT WINAPI IFileSaveDialog_fnSetFileNameLabel(IFileSaveDialog *iface, LPCWSTR pszLabel) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_SetFileNameLabel(&This->IFileDialog2_iface, pszLabel); -} - -static HRESULT WINAPI IFileSaveDialog_fnGetResult(IFileSaveDialog *iface, IShellItem **ppsi) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_GetResult(&This->IFileDialog2_iface, ppsi); -} - -static HRESULT WINAPI IFileSaveDialog_fnAddPlace(IFileSaveDialog *iface, IShellItem *psi, FDAP fdap) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_AddPlace(&This->IFileDialog2_iface, psi, fdap); -} - -static HRESULT WINAPI IFileSaveDialog_fnSetDefaultExtension(IFileSaveDialog *iface, - LPCWSTR pszDefaultExtension) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_SetDefaultExtension(&This->IFileDialog2_iface, pszDefaultExtension); -} - -static HRESULT WINAPI IFileSaveDialog_fnClose(IFileSaveDialog *iface, HRESULT hr) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_Close(&This->IFileDialog2_iface, hr); -} - -static HRESULT WINAPI IFileSaveDialog_fnSetClientGuid(IFileSaveDialog *iface, REFGUID guid) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_SetClientGuid(&This->IFileDialog2_iface, guid); -} - -static HRESULT WINAPI IFileSaveDialog_fnClearClientData(IFileSaveDialog *iface) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_ClearClientData(&This->IFileDialog2_iface); -} - -static HRESULT WINAPI IFileSaveDialog_fnSetFilter(IFileSaveDialog *iface, IShellItemFilter *pFilter) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - return IFileDialog2_SetFilter(&This->IFileDialog2_iface, pFilter); -} - -static HRESULT WINAPI IFileSaveDialog_fnSetSaveAsItem(IFileSaveDialog* iface, IShellItem *psi) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - FIXME("stub - %p (%p)\n", This, psi); - return E_NOTIMPL; -} - -static HRESULT WINAPI IFileSaveDialog_fnSetProperties(IFileSaveDialog* iface, IPropertyStore *pStore) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - FIXME("stub - %p (%p)\n", This, pStore); - return E_NOTIMPL; -} - -static HRESULT WINAPI IFileSaveDialog_fnSetCollectedProperties(IFileSaveDialog* iface, - IPropertyDescriptionList *pList, - BOOL fAppendDefault) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - FIXME("stub - %p (%p, %d)\n", This, pList, fAppendDefault); - return E_NOTIMPL; -} - -static HRESULT WINAPI IFileSaveDialog_fnGetProperties(IFileSaveDialog* iface, IPropertyStore **ppStore) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - FIXME("stub - %p (%p)\n", This, ppStore); - return E_NOTIMPL; -} - -static HRESULT WINAPI IFileSaveDialog_fnApplyProperties(IFileSaveDialog* iface, - IShellItem *psi, - IPropertyStore *pStore, - HWND hwnd, - IFileOperationProgressSink *pSink) -{ - FileDialogImpl *This = impl_from_IFileSaveDialog(iface); - FIXME("%p (%p, %p, %p, %p)\n", This, psi, pStore, hwnd, pSink); - return E_NOTIMPL; -} - -static const IFileSaveDialogVtbl vt_IFileSaveDialog = { - IFileSaveDialog_fnQueryInterface, - IFileSaveDialog_fnAddRef, - IFileSaveDialog_fnRelease, - IFileSaveDialog_fnShow, - IFileSaveDialog_fnSetFileTypes, - IFileSaveDialog_fnSetFileTypeIndex, - IFileSaveDialog_fnGetFileTypeIndex, - IFileSaveDialog_fnAdvise, - IFileSaveDialog_fnUnadvise, - IFileSaveDialog_fnSetOptions, - IFileSaveDialog_fnGetOptions, - IFileSaveDialog_fnSetDefaultFolder, - IFileSaveDialog_fnSetFolder, - IFileSaveDialog_fnGetFolder, - IFileSaveDialog_fnGetCurrentSelection, - IFileSaveDialog_fnSetFileName, - IFileSaveDialog_fnGetFileName, - IFileSaveDialog_fnSetTitle, - IFileSaveDialog_fnSetOkButtonLabel, - IFileSaveDialog_fnSetFileNameLabel, - IFileSaveDialog_fnGetResult, - IFileSaveDialog_fnAddPlace, - IFileSaveDialog_fnSetDefaultExtension, - IFileSaveDialog_fnClose, - IFileSaveDialog_fnSetClientGuid, - IFileSaveDialog_fnClearClientData, - IFileSaveDialog_fnSetFilter, - IFileSaveDialog_fnSetSaveAsItem, - IFileSaveDialog_fnSetProperties, - IFileSaveDialog_fnSetCollectedProperties, - IFileSaveDialog_fnGetProperties, - IFileSaveDialog_fnApplyProperties -}; - -/************************************************************************** - * IExplorerBrowserEvents implementation - */ -static inline FileDialogImpl *impl_from_IExplorerBrowserEvents(IExplorerBrowserEvents *iface) -{ - return CONTAINING_RECORD(iface, FileDialogImpl, IExplorerBrowserEvents_iface); -} - -static HRESULT WINAPI IExplorerBrowserEvents_fnQueryInterface(IExplorerBrowserEvents *iface, - REFIID riid, void **ppvObject) -{ - FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface); - TRACE("%p (%s, %p)\n", This, debugstr_guid(riid), ppvObject); - - return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject); -} - -static ULONG WINAPI IExplorerBrowserEvents_fnAddRef(IExplorerBrowserEvents *iface) -{ - FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface); - TRACE("%p\n", This); - return IFileDialog2_AddRef(&This->IFileDialog2_iface); -} - -static ULONG WINAPI IExplorerBrowserEvents_fnRelease(IExplorerBrowserEvents *iface) -{ - FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface); - TRACE("%p\n", This); - return IFileDialog2_Release(&This->IFileDialog2_iface); -} - -static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrowserEvents *iface, - PCIDLIST_ABSOLUTE pidlFolder) -{ - FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface); - IShellItem *psi; - HRESULT hr; - TRACE("%p (%p)\n", This, pidlFolder); - - hr = SHCreateItemFromIDList(pidlFolder, &IID_IShellItem, (void**)&psi); - if(SUCCEEDED(hr)) - { - hr = events_OnFolderChanging(This, psi); - IShellItem_Release(psi); - - /* The ExplorerBrowser treats S_FALSE as S_OK, we don't. */ - if(hr == S_FALSE) - hr = E_FAIL; - - return hr; - } - else - ERR("Failed to convert pidl (%p) to a shellitem.\n", pidlFolder); - - return S_OK; -} - -static HRESULT WINAPI IExplorerBrowserEvents_fnOnViewCreated(IExplorerBrowserEvents *iface, - IShellView *psv) -{ - FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface); - TRACE("%p (%p)\n", This, psv); - return S_OK; -} - -static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBrowserEvents *iface, - PCIDLIST_ABSOLUTE pidlFolder) -{ - FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface); - HRESULT hr; - TRACE("%p (%p)\n", This, pidlFolder); - - if(This->psi_folder) - IShellItem_Release(This->psi_folder); - - hr = SHCreateItemFromIDList(pidlFolder, &IID_IShellItem, (void**)&This->psi_folder); - if(FAILED(hr)) - { - ERR("Failed to get the current folder.\n"); - This->psi_folder = NULL; - } - - events_OnFolderChange(This); - - return S_OK; -} - -static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationFailed(IExplorerBrowserEvents *iface, - PCIDLIST_ABSOLUTE pidlFolder) -{ - FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface); - TRACE("%p (%p)\n", This, pidlFolder); - return S_OK; -} - -static const IExplorerBrowserEventsVtbl vt_IExplorerBrowserEvents = { - IExplorerBrowserEvents_fnQueryInterface, - IExplorerBrowserEvents_fnAddRef, - IExplorerBrowserEvents_fnRelease, - IExplorerBrowserEvents_fnOnNavigationPending, - IExplorerBrowserEvents_fnOnViewCreated, - IExplorerBrowserEvents_fnOnNavigationComplete, - IExplorerBrowserEvents_fnOnNavigationFailed -}; - -/************************************************************************** - * IServiceProvider implementation - */ -static inline FileDialogImpl *impl_from_IServiceProvider(IServiceProvider *iface) -{ - return CONTAINING_RECORD(iface, FileDialogImpl, IServiceProvider_iface); -} - -static HRESULT WINAPI IServiceProvider_fnQueryInterface(IServiceProvider *iface, - REFIID riid, void **ppvObject) -{ - FileDialogImpl *This = impl_from_IServiceProvider(iface); - TRACE("%p\n", This); - return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject); -} - -static ULONG WINAPI IServiceProvider_fnAddRef(IServiceProvider *iface) -{ - FileDialogImpl *This = impl_from_IServiceProvider(iface); - TRACE("%p\n", This); - return IFileDialog2_AddRef(&This->IFileDialog2_iface); -} - -static ULONG WINAPI IServiceProvider_fnRelease(IServiceProvider *iface) -{ - FileDialogImpl *This = impl_from_IServiceProvider(iface); - TRACE("%p\n", This); - return IFileDialog2_Release(&This->IFileDialog2_iface); -} - -static HRESULT WINAPI IServiceProvider_fnQueryService(IServiceProvider *iface, - REFGUID guidService, - REFIID riid, void **ppv) -{ - FileDialogImpl *This = impl_from_IServiceProvider(iface); - HRESULT hr = E_NOTIMPL; - TRACE("%p (%s, %s, %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv); - - *ppv = NULL; - if(IsEqualGUID(guidService, &SID_STopLevelBrowser) && This->peb) - hr = IExplorerBrowser_QueryInterface(This->peb, riid, ppv); - else if(IsEqualGUID(guidService, &SID_SExplorerBrowserFrame)) - hr = IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppv); - else - FIXME("Interface %s requested from unknown service %s\n", - debugstr_guid(riid), debugstr_guid(guidService)); - - return hr; -} - -static const IServiceProviderVtbl vt_IServiceProvider = { - IServiceProvider_fnQueryInterface, - IServiceProvider_fnAddRef, - IServiceProvider_fnRelease, - IServiceProvider_fnQueryService -}; - -/************************************************************************** - * ICommDlgBrowser3 implementation - */ -static inline FileDialogImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface) -{ - return CONTAINING_RECORD(iface, FileDialogImpl, ICommDlgBrowser3_iface); -} - -static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface, - REFIID riid, void **ppvObject) -{ - FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface); - TRACE("%p\n", This); - return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject); -} - -static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface) -{ - FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface); - TRACE("%p\n", This); - return IFileDialog2_AddRef(&This->IFileDialog2_iface); -} - -static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface) -{ - FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface); - TRACE("%p\n", This); - return IFileDialog2_Release(&This->IFileDialog2_iface); -} - -static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface, - IShellView *shv) -{ - FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface); - HRESULT hr; - TRACE("%p (%p)\n", This, shv); - - hr = on_default_action(This); - - if(SUCCEEDED(hr)) - EndDialog(This->dlg_hwnd, S_OK); - - return S_OK; -} - -static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface, - IShellView *shv, ULONG uChange ) -{ - FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface); - IDataObject *new_selection; - HRESULT hr; - TRACE("%p (%p, %x)\n", This, shv, uChange); - - switch(uChange) - { - case CDBOSC_SELCHANGE: - if(This->psia_selection) - { - IShellItemArray_Release(This->psia_selection); - This->psia_selection = NULL; - } - - hr = IShellView_GetItemObject(shv, SVGIO_SELECTION, &IID_IDataObject, (void**)&new_selection); - if(SUCCEEDED(hr)) - { - hr = SHCreateShellItemArrayFromDataObject(new_selection, &IID_IShellItemArray, - (void**)&This->psia_selection); - if(SUCCEEDED(hr)) - { - fill_filename_from_selection(This); - events_OnSelectionChange(This); - } - - IDataObject_Release(new_selection); - } - break; - default: - TRACE("Unhandled state change\n"); - } - return S_OK; -} - -static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface, - IShellView *shv, LPCITEMIDLIST pidl) -{ - FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface); - IShellItem *psi; - LPWSTR filename; - LPITEMIDLIST parent_pidl; - HRESULT hr; - ULONG attr; - TRACE("%p (%p, %p)\n", This, shv, pidl); - - if(!This->filterspec_count && !(This->options & FOS_PICKFOLDERS)) - return S_OK; - - hr = SHGetIDListFromObject((IUnknown*)shv, &parent_pidl); - if(SUCCEEDED(hr)) - { - LPITEMIDLIST full_pidl = ILCombine(parent_pidl, pidl); - hr = SHCreateItemFromIDList(full_pidl, &IID_IShellItem, (void**)&psi); - ILFree(parent_pidl); - ILFree(full_pidl); - } - if(FAILED(hr)) - { - ERR("Failed to get shellitem (%08x).\n", hr); - return S_OK; - } - - hr = IShellItem_GetAttributes(psi, SFGAO_FOLDER|SFGAO_LINK, &attr); - if(FAILED(hr) || (attr & (SFGAO_FOLDER | SFGAO_LINK))) - { - IShellItem_Release(psi); - return S_OK; - } - - if((This->options & FOS_PICKFOLDERS) && !(attr & (SFGAO_FOLDER | SFGAO_LINK))) - { - IShellItem_Release(psi); - return S_FALSE; - } - - hr = S_OK; - if(SUCCEEDED(IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &filename))) - { - if(!PathMatchSpecW(filename, This->filterspecs[This->filetypeindex].pszSpec)) - hr = S_FALSE; - CoTaskMemFree(filename); - } - - IShellItem_Release(psi); - return hr; -} - -static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface, - IShellView *ppshv, DWORD dwNotifyType) -{ - FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface); - FIXME("Stub: %p (%p, 0x%x)\n", This, ppshv, dwNotifyType); - return E_NOTIMPL; -} - -static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface, - IShellView *pshv, - LPWSTR pszText, int cchMax) -{ - FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface); - FIXME("Stub: %p (%p, %p, %d)\n", This, pshv, pszText, cchMax); - return E_NOTIMPL; -} - -static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface, DWORD *pdwFlags) -{ - FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface); - FIXME("Stub: %p (%p)\n", This, pdwFlags); - return E_NOTIMPL; -} - -static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface, - IShellView *pshv, int iColumn) -{ - FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface); - FIXME("Stub: %p (%p, %d)\n", This, pshv, iColumn); - return E_NOTIMPL; -} - -static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface, - LPWSTR pszFileSpec, int cchFileSpec) -{ - FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface); - FIXME("Stub: %p (%p, %d)\n", This, pszFileSpec, cchFileSpec); - return E_NOTIMPL; -} - -static HRESULT WINAPI ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3 *iface, - IShellView *pshv) -{ - FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface); - FIXME("Stub: %p (%p)\n", This, pshv); - return E_NOTIMPL; -} - -static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = { - ICommDlgBrowser3_fnQueryInterface, - ICommDlgBrowser3_fnAddRef, - ICommDlgBrowser3_fnRelease, - ICommDlgBrowser3_fnOnDefaultCommand, - ICommDlgBrowser3_fnOnStateChange, - ICommDlgBrowser3_fnIncludeObject, - ICommDlgBrowser3_fnNotify, - ICommDlgBrowser3_fnGetDefaultMenuText, - ICommDlgBrowser3_fnGetViewFlags, - ICommDlgBrowser3_fnOnColumnClicked, - ICommDlgBrowser3_fnGetCurrentFilter, - ICommDlgBrowser3_fnOnPreviewCreated -}; - -/************************************************************************** - * IOleWindow implementation - */ -static inline FileDialogImpl *impl_from_IOleWindow(IOleWindow *iface) -{ - return CONTAINING_RECORD(iface, FileDialogImpl, IOleWindow_iface); -} - -static HRESULT WINAPI IOleWindow_fnQueryInterface(IOleWindow *iface, REFIID riid, void **ppvObject) -{ - FileDialogImpl *This = impl_from_IOleWindow(iface); - return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject); -} - -static ULONG WINAPI IOleWindow_fnAddRef(IOleWindow *iface) -{ - FileDialogImpl *This = impl_from_IOleWindow(iface); - return IFileDialog2_AddRef(&This->IFileDialog2_iface); -} - -static ULONG WINAPI IOleWindow_fnRelease(IOleWindow *iface) -{ - FileDialogImpl *This = impl_from_IOleWindow(iface); - return IFileDialog2_Release(&This->IFileDialog2_iface); -} - -static HRESULT WINAPI IOleWindow_fnContextSensitiveHelp(IOleWindow *iface, BOOL fEnterMOde) -{ - FileDialogImpl *This = impl_from_IOleWindow(iface); - FIXME("Stub: %p (%d)\n", This, fEnterMOde); - return E_NOTIMPL; -} - -static HRESULT WINAPI IOleWindow_fnGetWindow(IOleWindow *iface, HWND *phwnd) -{ - FileDialogImpl *This = impl_from_IOleWindow(iface); - TRACE("%p (%p)\n", This, phwnd); - *phwnd = This->dlg_hwnd; - return S_OK; -} - -static const IOleWindowVtbl vt_IOleWindow = { - IOleWindow_fnQueryInterface, - IOleWindow_fnAddRef, - IOleWindow_fnRelease, - IOleWindow_fnGetWindow, - IOleWindow_fnContextSensitiveHelp -}; - -/************************************************************************** - * IFileDialogCustomize implementation - */ -static inline FileDialogImpl *impl_from_IFileDialogCustomize(IFileDialogCustomize *iface) -{ - return CONTAINING_RECORD(iface, FileDialogImpl, IFileDialogCustomize_iface); -} - -static HRESULT WINAPI IFileDialogCustomize_fnQueryInterface(IFileDialogCustomize *iface, - REFIID riid, void **ppvObject) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject); -} - -static ULONG WINAPI IFileDialogCustomize_fnAddRef(IFileDialogCustomize *iface) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - return IFileDialog2_AddRef(&This->IFileDialog2_iface); -} - -static ULONG WINAPI IFileDialogCustomize_fnRelease(IFileDialogCustomize *iface) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - return IFileDialog2_Release(&This->IFileDialog2_iface); -} - -static HRESULT WINAPI IFileDialogCustomize_fnEnableOpenDropDown(IFileDialogCustomize *iface, - DWORD dwIDCtl) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - MENUINFO mi; - TRACE("%p (%d)\n", This, dwIDCtl); - - if (This->hmenu_opendropdown || get_cctrl(This, dwIDCtl)) - return E_UNEXPECTED; - - This->hmenu_opendropdown = CreatePopupMenu(); - - if (!This->hmenu_opendropdown) - return E_OUTOFMEMORY; - - mi.cbSize = sizeof(mi); - mi.fMask = MIM_STYLE; - mi.dwStyle = MNS_NOTIFYBYPOS; - SetMenuInfo(This->hmenu_opendropdown, &mi); - - This->cctrl_opendropdown.hwnd = NULL; - This->cctrl_opendropdown.wrapper_hwnd = NULL; - This->cctrl_opendropdown.id = dwIDCtl; - This->cctrl_opendropdown.dlgid = 0; - This->cctrl_opendropdown.type = IDLG_CCTRL_OPENDROPDOWN; - This->cctrl_opendropdown.cdcstate = CDCS_ENABLED | CDCS_VISIBLE; - list_init(&This->cctrl_opendropdown.sub_cctrls); - list_init(&This->cctrl_opendropdown.sub_items); - - return S_OK; -} - -static HRESULT WINAPI IFileDialogCustomize_fnAddMenu(IFileDialogCustomize *iface, - DWORD dwIDCtl, - LPCWSTR pszLabel) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl; - TBBUTTON tbb; - HRESULT hr; - TRACE("%p (%d, %p)\n", This, dwIDCtl, pszLabel); - - hr = cctrl_create_new(This, dwIDCtl, NULL, TOOLBARCLASSNAMEW, - TBSTYLE_FLAT | CCS_NODIVIDER, 0, - This->cctrl_def_height, &ctrl); - if(SUCCEEDED(hr)) - { - SendMessageW(ctrl->hwnd, TB_BUTTONSTRUCTSIZE, sizeof(tbb), 0); - ctrl->type = IDLG_CCTRL_MENU; - - /* Add the actual button with a popup menu. */ - tbb.iBitmap = I_IMAGENONE; - tbb.dwData = (DWORD_PTR)CreatePopupMenu(); - tbb.iString = (DWORD_PTR)pszLabel; - tbb.fsState = TBSTATE_ENABLED; - tbb.fsStyle = BTNS_WHOLEDROPDOWN; - tbb.idCommand = 1; - - SendMessageW(ctrl->hwnd, TB_ADDBUTTONSW, 1, (LPARAM)&tbb); - } - - return hr; -} - -static HRESULT WINAPI IFileDialogCustomize_fnAddPushButton(IFileDialogCustomize *iface, - DWORD dwIDCtl, - LPCWSTR pszLabel) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl; - HRESULT hr; - TRACE("%p (%d, %p)\n", This, dwIDCtl, pszLabel); - - hr = cctrl_create_new(This, dwIDCtl, pszLabel, WC_BUTTONW, BS_MULTILINE, 0, - This->cctrl_def_height, &ctrl); - if(SUCCEEDED(hr)) - ctrl->type = IDLG_CCTRL_PUSHBUTTON; - - return hr; -} - -static HRESULT WINAPI IFileDialogCustomize_fnAddComboBox(IFileDialogCustomize *iface, - DWORD dwIDCtl) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl; - HRESULT hr; - TRACE("%p (%d)\n", This, dwIDCtl); - - hr = cctrl_create_new(This, dwIDCtl, NULL, WC_COMBOBOXW, CBS_DROPDOWNLIST, 0, - This->cctrl_def_height, &ctrl); - if(SUCCEEDED(hr)) - ctrl->type = IDLG_CCTRL_COMBOBOX; - - return hr; -} - -static HRESULT WINAPI IFileDialogCustomize_fnAddRadioButtonList(IFileDialogCustomize *iface, - DWORD dwIDCtl) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl; - HRESULT hr; - TRACE("%p (%d)\n", This, dwIDCtl); - - hr = cctrl_create_new(This, dwIDCtl, NULL, radiobuttonlistW, 0, 0, 0, &ctrl); - if(SUCCEEDED(hr)) - { - ctrl->type = IDLG_CCTRL_RADIOBUTTONLIST; - SetWindowLongPtrW(ctrl->hwnd, GWLP_USERDATA, (LPARAM)This); - } - - return hr; -} - -static HRESULT WINAPI IFileDialogCustomize_fnAddCheckButton(IFileDialogCustomize *iface, - DWORD dwIDCtl, - LPCWSTR pszLabel, - BOOL bChecked) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl; - HRESULT hr; - TRACE("%p (%d, %p, %d)\n", This, dwIDCtl, pszLabel, bChecked); - - hr = cctrl_create_new(This, dwIDCtl, pszLabel, WC_BUTTONW, BS_AUTOCHECKBOX|BS_MULTILINE, 0, - This->cctrl_def_height, &ctrl); - if(SUCCEEDED(hr)) - { - ctrl->type = IDLG_CCTRL_CHECKBUTTON; - SendMessageW(ctrl->hwnd, BM_SETCHECK, bChecked ? BST_CHECKED : BST_UNCHECKED, 0); - } - - return hr; -} - -static HRESULT WINAPI IFileDialogCustomize_fnAddEditBox(IFileDialogCustomize *iface, - DWORD dwIDCtl, - LPCWSTR pszText) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl; - HRESULT hr; - TRACE("%p (%d, %p)\n", This, dwIDCtl, pszText); - - hr = cctrl_create_new(This, dwIDCtl, pszText, WC_EDITW, ES_AUTOHSCROLL, WS_EX_CLIENTEDGE, - This->cctrl_def_height, &ctrl); - if(SUCCEEDED(hr)) - ctrl->type = IDLG_CCTRL_EDITBOX; - - return hr; -} - -static HRESULT WINAPI IFileDialogCustomize_fnAddSeparator(IFileDialogCustomize *iface, - DWORD dwIDCtl) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl; - HRESULT hr; - TRACE("%p (%d)\n", This, dwIDCtl); - - hr = cctrl_create_new(This, dwIDCtl, NULL, WC_STATICW, SS_ETCHEDHORZ, 0, - GetSystemMetrics(SM_CYEDGE), &ctrl); - if(SUCCEEDED(hr)) - ctrl->type = IDLG_CCTRL_SEPARATOR; - - return hr; -} - -static HRESULT WINAPI IFileDialogCustomize_fnAddText(IFileDialogCustomize *iface, - DWORD dwIDCtl, - LPCWSTR pszText) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl; - HRESULT hr; - TRACE("%p (%d, %p)\n", This, dwIDCtl, pszText); - - hr = cctrl_create_new(This, dwIDCtl, pszText, WC_STATICW, 0, 0, - This->cctrl_def_height, &ctrl); - if(SUCCEEDED(hr)) - ctrl->type = IDLG_CCTRL_TEXT; - - return hr; -} - -static HRESULT WINAPI IFileDialogCustomize_fnSetControlLabel(IFileDialogCustomize *iface, - DWORD dwIDCtl, - LPCWSTR pszLabel) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl = get_cctrl(This, dwIDCtl); - TRACE("%p (%d, %p)\n", This, dwIDCtl, pszLabel); - - if(!ctrl) return E_INVALIDARG; - - switch(ctrl->type) - { - case IDLG_CCTRL_MENU: - case IDLG_CCTRL_PUSHBUTTON: - case IDLG_CCTRL_CHECKBUTTON: - case IDLG_CCTRL_TEXT: - case IDLG_CCTRL_VISUALGROUP: - SendMessageW(ctrl->hwnd, WM_SETTEXT, 0, (LPARAM)pszLabel); - break; - case IDLG_CCTRL_OPENDROPDOWN: - return E_NOTIMPL; - default: - break; - } - - return S_OK; -} - -static HRESULT WINAPI IFileDialogCustomize_fnGetControlState(IFileDialogCustomize *iface, - DWORD dwIDCtl, - CDCONTROLSTATEF *pdwState) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl = get_cctrl(This, dwIDCtl); - TRACE("%p (%d, %p)\n", This, dwIDCtl, pdwState); - - if(!ctrl || ctrl->type == IDLG_CCTRL_OPENDROPDOWN) return E_NOTIMPL; - - *pdwState = ctrl->cdcstate; - return S_OK; -} - -static HRESULT WINAPI IFileDialogCustomize_fnSetControlState(IFileDialogCustomize *iface, - DWORD dwIDCtl, - CDCONTROLSTATEF dwState) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl = get_cctrl(This,dwIDCtl); - TRACE("%p (%d, %x)\n", This, dwIDCtl, dwState); - - if(ctrl && ctrl->hwnd) - { - LONG wndstyle = GetWindowLongW(ctrl->hwnd, GWL_STYLE); - - if(dwState & CDCS_ENABLED) - wndstyle &= ~(WS_DISABLED); - else - wndstyle |= WS_DISABLED; - - if(dwState & CDCS_VISIBLE) - wndstyle |= WS_VISIBLE; - else - wndstyle &= ~(WS_VISIBLE); - - SetWindowLongW(ctrl->hwnd, GWL_STYLE, wndstyle); - - /* We save the state separately since at least one application - * relies on being able to hide a control. */ - ctrl->cdcstate = dwState; - } - - return S_OK; -} - -static HRESULT WINAPI IFileDialogCustomize_fnGetEditBoxText(IFileDialogCustomize *iface, - DWORD dwIDCtl, - WCHAR **ppszText) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl = get_cctrl(This, dwIDCtl); - WCHAR len, *text; - TRACE("%p (%d, %p)\n", This, dwIDCtl, ppszText); - - if(!ctrl || !ctrl->hwnd || !(len = SendMessageW(ctrl->hwnd, WM_GETTEXTLENGTH, 0, 0))) - return E_FAIL; - - text = CoTaskMemAlloc(sizeof(WCHAR)*(len+1)); - if(!text) return E_FAIL; - - SendMessageW(ctrl->hwnd, WM_GETTEXT, len+1, (LPARAM)text); - *ppszText = text; - return S_OK; -} - -static HRESULT WINAPI IFileDialogCustomize_fnSetEditBoxText(IFileDialogCustomize *iface, - DWORD dwIDCtl, - LPCWSTR pszText) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl = get_cctrl(This, dwIDCtl); - TRACE("%p (%d, %s)\n", This, dwIDCtl, debugstr_w(pszText)); - - if(!ctrl || ctrl->type != IDLG_CCTRL_EDITBOX) - return E_FAIL; - - SendMessageW(ctrl->hwnd, WM_SETTEXT, 0, (LPARAM)pszText); - return S_OK; -} - -static HRESULT WINAPI IFileDialogCustomize_fnGetCheckButtonState(IFileDialogCustomize *iface, - DWORD dwIDCtl, - BOOL *pbChecked) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl = get_cctrl(This, dwIDCtl); - TRACE("%p (%d, %p)\n", This, dwIDCtl, pbChecked); - - if(ctrl && ctrl->hwnd) - *pbChecked = (SendMessageW(ctrl->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED); - - return S_OK; -} - -static HRESULT WINAPI IFileDialogCustomize_fnSetCheckButtonState(IFileDialogCustomize *iface, - DWORD dwIDCtl, - BOOL bChecked) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl = get_cctrl(This, dwIDCtl); - TRACE("%p (%d, %d)\n", This, dwIDCtl, bChecked); - - if(ctrl && ctrl->hwnd) - SendMessageW(ctrl->hwnd, BM_SETCHECK, bChecked ? BST_CHECKED:BST_UNCHECKED, 0); - - return S_OK; -} - -static UINT get_combobox_index_from_id(HWND cb_hwnd, DWORD dwIDItem) -{ - UINT count = SendMessageW(cb_hwnd, CB_GETCOUNT, 0, 0); - UINT i; - if(!count || (count == CB_ERR)) - return -1; - - for(i = 0; i < count; i++) - if(SendMessageW(cb_hwnd, CB_GETITEMDATA, i, 0) == dwIDItem) - return i; - - TRACE("Item with id %d not found in combobox %p (item count: %d)\n", dwIDItem, cb_hwnd, count); - return -1; -} - -static HRESULT WINAPI IFileDialogCustomize_fnAddControlItem(IFileDialogCustomize *iface, - DWORD dwIDCtl, - DWORD dwIDItem, - LPCWSTR pszLabel) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl = get_cctrl(This, dwIDCtl); - HRESULT hr; - TRACE("%p (%d, %d, %s)\n", This, dwIDCtl, dwIDItem, debugstr_w(pszLabel)); - - if(!ctrl) return E_FAIL; - - switch(ctrl->type) - { - case IDLG_CCTRL_COMBOBOX: - { - UINT index; - cctrl_item* item; - - hr = add_item(ctrl, dwIDItem, pszLabel, &item); - - if (FAILED(hr)) return hr; - - index = SendMessageW(ctrl->hwnd, CB_ADDSTRING, 0, (LPARAM)pszLabel); - SendMessageW(ctrl->hwnd, CB_SETITEMDATA, index, dwIDItem); - - return S_OK; - } - case IDLG_CCTRL_MENU: - case IDLG_CCTRL_OPENDROPDOWN: - { - cctrl_item* item; - HMENU hmenu; - - hr = add_item(ctrl, dwIDItem, pszLabel, &item); - - if (FAILED(hr)) return hr; - - if (ctrl->type == IDLG_CCTRL_MENU) - { - TBBUTTON tbb; - SendMessageW(ctrl->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb); - hmenu = (HMENU)tbb.dwData; - } - else /* ctrl->type == IDLG_CCTRL_OPENDROPDOWN */ - hmenu = This->hmenu_opendropdown; - - AppendMenuW(hmenu, MF_STRING, dwIDItem, pszLabel); - return S_OK; - } - case IDLG_CCTRL_RADIOBUTTONLIST: - { - cctrl_item* item; - - hr = add_item(ctrl, dwIDItem, pszLabel, &item); - - if (SUCCEEDED(hr)) - { - item->hwnd = CreateWindowExW(0, WC_BUTTONW, pszLabel, - WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|BS_RADIOBUTTON|BS_MULTILINE, - 0, 0, 0, 0, ctrl->hwnd, ULongToHandle(dwIDItem), COMDLG32_hInstance, 0); - - if (!item->hwnd) - { - ERR("Failed to create radio button\n"); - list_remove(&item->entry); - item_free(item); - return E_FAIL; - } - } - - return hr; - } - default: - break; - } - - return E_NOINTERFACE; /* win7 */ -} - -static HRESULT WINAPI IFileDialogCustomize_fnRemoveControlItem(IFileDialogCustomize *iface, - DWORD dwIDCtl, - DWORD dwIDItem) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl = get_cctrl(This, dwIDCtl); - TRACE("%p (%d, %d)\n", This, dwIDCtl, dwIDItem); - - if(!ctrl) return E_FAIL; - - switch(ctrl->type) - { - case IDLG_CCTRL_COMBOBOX: - { - cctrl_item* item; - DWORD position; - - item = get_item(ctrl, dwIDItem, CDCS_VISIBLE|CDCS_ENABLED, &position); - - if ((item->cdcstate & (CDCS_VISIBLE|CDCS_ENABLED)) == (CDCS_VISIBLE|CDCS_ENABLED)) - { - if(SendMessageW(ctrl->hwnd, CB_DELETESTRING, position, 0) == CB_ERR) - return E_FAIL; - } - - list_remove(&item->entry); - item_free(item); - - return S_OK; - } - case IDLG_CCTRL_MENU: - case IDLG_CCTRL_OPENDROPDOWN: - { - HMENU hmenu; - cctrl_item* item; - - item = get_item(ctrl, dwIDItem, 0, NULL); - - if (!item) - return E_UNEXPECTED; - - if (item->cdcstate & CDCS_VISIBLE) - { - if (ctrl->type == IDLG_CCTRL_MENU) - { - TBBUTTON tbb; - SendMessageW(ctrl->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb); - hmenu = (HMENU)tbb.dwData; - } - else /* ctrl->type == IDLG_CCTRL_OPENDROPDOWN */ - hmenu = This->hmenu_opendropdown; - - if(!hmenu || !DeleteMenu(hmenu, dwIDItem, MF_BYCOMMAND)) - return E_UNEXPECTED; - } - - list_remove(&item->entry); - item_free(item); - - return S_OK; - } - case IDLG_CCTRL_RADIOBUTTONLIST: - { - cctrl_item* item; - - item = get_item(ctrl, dwIDItem, 0, NULL); - - if (!item) - return E_UNEXPECTED; - - list_remove(&item->entry); - item_free(item); - - return S_OK; - } - default: - break; - } - - return E_FAIL; -} - -static HRESULT WINAPI IFileDialogCustomize_fnRemoveAllControlItems(IFileDialogCustomize *iface, - DWORD dwIDCtl) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - TRACE("%p (%d)\n", This, dwIDCtl); - - /* Not implemented by native */ - return E_NOTIMPL; -} - -static HRESULT WINAPI IFileDialogCustomize_fnGetControlItemState(IFileDialogCustomize *iface, - DWORD dwIDCtl, - DWORD dwIDItem, - CDCONTROLSTATEF *pdwState) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl = get_cctrl(This, dwIDCtl); - TRACE("%p (%d, %d, %p)\n", This, dwIDCtl, dwIDItem, pdwState); - - if(!ctrl) return E_FAIL; - - switch(ctrl->type) - { - case IDLG_CCTRL_COMBOBOX: - case IDLG_CCTRL_MENU: - case IDLG_CCTRL_OPENDROPDOWN: - case IDLG_CCTRL_RADIOBUTTONLIST: - { - cctrl_item* item; - - item = get_item(ctrl, dwIDItem, 0, NULL); - - if (!item) - return E_UNEXPECTED; - - *pdwState = item->cdcstate; - - return S_OK; - } - default: - break; - } - - return E_FAIL; -} - -static HRESULT WINAPI IFileDialogCustomize_fnSetControlItemState(IFileDialogCustomize *iface, - DWORD dwIDCtl, - DWORD dwIDItem, - CDCONTROLSTATEF dwState) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl = get_cctrl(This, dwIDCtl); - TRACE("%p (%d, %d, %x)\n", This, dwIDCtl, dwIDItem, dwState); - - if(!ctrl) return E_FAIL; - - switch(ctrl->type) - { - case IDLG_CCTRL_COMBOBOX: - { - cctrl_item* item; - BOOL visible, was_visible; - DWORD position; - - item = get_item(ctrl, dwIDItem, CDCS_VISIBLE|CDCS_ENABLED, &position); - - if (!item) - return E_UNEXPECTED; - - visible = ((dwState & (CDCS_VISIBLE|CDCS_ENABLED)) == (CDCS_VISIBLE|CDCS_ENABLED)); - was_visible = ((item->cdcstate & (CDCS_VISIBLE|CDCS_ENABLED)) == (CDCS_VISIBLE|CDCS_ENABLED)); - - if (visible && !was_visible) - { - SendMessageW(ctrl->hwnd, CB_INSERTSTRING, position, (LPARAM)item->label); - SendMessageW(ctrl->hwnd, CB_SETITEMDATA, position, dwIDItem); - } - else if (!visible && was_visible) - { - SendMessageW(ctrl->hwnd, CB_DELETESTRING, position, 0); - } - - item->cdcstate = dwState; - - return S_OK; - } - case IDLG_CCTRL_MENU: - case IDLG_CCTRL_OPENDROPDOWN: - { - HMENU hmenu; - cctrl_item* item; - CDCONTROLSTATEF prev_state; - DWORD position; - - item = get_item(ctrl, dwIDItem, CDCS_VISIBLE, &position); - - if (!item) - return E_UNEXPECTED; - - prev_state = item->cdcstate; - - if (ctrl->type == IDLG_CCTRL_MENU) - { - TBBUTTON tbb; - SendMessageW(ctrl->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb); - hmenu = (HMENU)tbb.dwData; - } - else /* ctrl->type == IDLG_CCTRL_OPENDROPDOWN */ - hmenu = This->hmenu_opendropdown; - - if (dwState & CDCS_VISIBLE) - { - if (prev_state & CDCS_VISIBLE) - { - /* change state */ - EnableMenuItem(hmenu, dwIDItem, - MF_BYCOMMAND|((dwState & CDCS_ENABLED) ? MFS_ENABLED : MFS_DISABLED)); - } - else - { - /* show item */ - MENUITEMINFOW mii; - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_ID|MIIM_STATE|MIIM_STRING; - mii.fState = (dwState & CDCS_ENABLED) ? MFS_ENABLED : MFS_DISABLED; - mii.wID = dwIDItem; - mii.dwTypeData = item->label; - - InsertMenuItemW(hmenu, position, TRUE, &mii); - } - } - else if (prev_state & CDCS_VISIBLE) - { - /* hide item */ - DeleteMenu(hmenu, dwIDItem, MF_BYCOMMAND); - } - - item->cdcstate = dwState; - - if (ctrl->type == IDLG_CCTRL_OPENDROPDOWN) - { - update_control_text(This); - update_layout(This); - } - - return S_OK; - } - case IDLG_CCTRL_RADIOBUTTONLIST: - { - cctrl_item* item; - - item = get_item(ctrl, dwIDItem, CDCS_VISIBLE, NULL); - - if (!item) - return E_UNEXPECTED; - - /* Oddly, native allows setting this but doesn't seem to do anything with it. */ - item->cdcstate = dwState; - - return S_OK; - } - default: - break; - } - - return E_FAIL; -} - -static HRESULT WINAPI IFileDialogCustomize_fnGetSelectedControlItem(IFileDialogCustomize *iface, - DWORD dwIDCtl, - DWORD *pdwIDItem) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl = get_cctrl(This, dwIDCtl); - TRACE("%p (%d, %p)\n", This, dwIDCtl, pdwIDItem); - - if(!ctrl) return E_FAIL; - - switch(ctrl->type) - { - case IDLG_CCTRL_COMBOBOX: - { - UINT index = SendMessageW(ctrl->hwnd, CB_GETCURSEL, 0, 0); - if(index == CB_ERR) - return E_FAIL; - - *pdwIDItem = SendMessageW(ctrl->hwnd, CB_GETITEMDATA, index, 0); - return S_OK; - } - case IDLG_CCTRL_OPENDROPDOWN: - if (This->opendropdown_has_selection) - { - *pdwIDItem = This->opendropdown_selection; - return S_OK; - } - else - { - /* Return first enabled item. */ - cctrl_item* item = get_first_item(ctrl); - - if (item) - { - *pdwIDItem = item->id; - return S_OK; - } - - WARN("no enabled items in open dropdown\n"); - return E_FAIL; - } - case IDLG_CCTRL_RADIOBUTTONLIST: - { - cctrl_item* item; - - LIST_FOR_EACH_ENTRY(item, &ctrl->sub_items, cctrl_item, entry) - { - if (SendMessageW(item->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED) - { - *pdwIDItem = item->id; - return S_OK; - } - } - - WARN("no checked items in radio button list\n"); - return E_FAIL; - } - default: - FIXME("Unsupported control type %d\n", ctrl->type); - } - - return E_NOTIMPL; -} - -static HRESULT WINAPI IFileDialogCustomize_fnSetSelectedControlItem(IFileDialogCustomize *iface, - DWORD dwIDCtl, - DWORD dwIDItem) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *ctrl = get_cctrl(This, dwIDCtl); - TRACE("%p (%d, %d)\n", This, dwIDCtl, dwIDItem); - - if(!ctrl) return E_INVALIDARG; - - switch(ctrl->type) - { - case IDLG_CCTRL_COMBOBOX: - { - UINT index = get_combobox_index_from_id(ctrl->hwnd, dwIDItem); - - if(index == -1) - return E_INVALIDARG; - - if(SendMessageW(ctrl->hwnd, CB_SETCURSEL, index, 0) == CB_ERR) - return E_FAIL; - - return S_OK; - } - case IDLG_CCTRL_RADIOBUTTONLIST: - { - cctrl_item* item; - - item = get_item(ctrl, dwIDItem, 0, NULL); - - if (item) - { - radiobuttonlist_set_selected_item(This, ctrl, item); - return S_OK; - } - - return E_INVALIDARG; - } - default: - FIXME("Unsupported control type %d\n", ctrl->type); - } - - return E_INVALIDARG; -} - -static HRESULT WINAPI IFileDialogCustomize_fnStartVisualGroup(IFileDialogCustomize *iface, - DWORD dwIDCtl, - LPCWSTR pszLabel) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - customctrl *vg; - HRESULT hr; - TRACE("%p (%d, %s)\n", This, dwIDCtl, debugstr_w(pszLabel)); - - if(This->cctrl_active_vg) - return E_UNEXPECTED; - - hr = cctrl_create_new(This, dwIDCtl, pszLabel, WC_STATICW, 0, 0, - This->cctrl_def_height, &vg); - if(SUCCEEDED(hr)) - { - vg->type = IDLG_CCTRL_VISUALGROUP; - This->cctrl_active_vg = vg; - } - - return hr; -} - -static HRESULT WINAPI IFileDialogCustomize_fnEndVisualGroup(IFileDialogCustomize *iface) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - TRACE("%p\n", This); - - This->cctrl_active_vg = NULL; - - return S_OK; -} - -static HRESULT WINAPI IFileDialogCustomize_fnMakeProminent(IFileDialogCustomize *iface, - DWORD dwIDCtl) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - FIXME("stub - %p (%d)\n", This, dwIDCtl); - return S_OK; -} - -static HRESULT WINAPI IFileDialogCustomize_fnSetControlItemText(IFileDialogCustomize *iface, - DWORD dwIDCtl, - DWORD dwIDItem, - LPCWSTR pszLabel) -{ - FileDialogImpl *This = impl_from_IFileDialogCustomize(iface); - FIXME("stub - %p (%d, %d, %s)\n", This, dwIDCtl, dwIDItem, debugstr_w(pszLabel)); - return E_NOTIMPL; -} - -static const IFileDialogCustomizeVtbl vt_IFileDialogCustomize = { - IFileDialogCustomize_fnQueryInterface, - IFileDialogCustomize_fnAddRef, - IFileDialogCustomize_fnRelease, - IFileDialogCustomize_fnEnableOpenDropDown, - IFileDialogCustomize_fnAddMenu, - IFileDialogCustomize_fnAddPushButton, - IFileDialogCustomize_fnAddComboBox, - IFileDialogCustomize_fnAddRadioButtonList, - IFileDialogCustomize_fnAddCheckButton, - IFileDialogCustomize_fnAddEditBox, - IFileDialogCustomize_fnAddSeparator, - IFileDialogCustomize_fnAddText, - IFileDialogCustomize_fnSetControlLabel, - IFileDialogCustomize_fnGetControlState, - IFileDialogCustomize_fnSetControlState, - IFileDialogCustomize_fnGetEditBoxText, - IFileDialogCustomize_fnSetEditBoxText, - IFileDialogCustomize_fnGetCheckButtonState, - IFileDialogCustomize_fnSetCheckButtonState, - IFileDialogCustomize_fnAddControlItem, - IFileDialogCustomize_fnRemoveControlItem, - IFileDialogCustomize_fnRemoveAllControlItems, - IFileDialogCustomize_fnGetControlItemState, - IFileDialogCustomize_fnSetControlItemState, - IFileDialogCustomize_fnGetSelectedControlItem, - IFileDialogCustomize_fnSetSelectedControlItem, - IFileDialogCustomize_fnStartVisualGroup, - IFileDialogCustomize_fnEndVisualGroup, - IFileDialogCustomize_fnMakeProminent, - IFileDialogCustomize_fnSetControlItemText -}; - -static HRESULT FileDialog_constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv, enum ITEMDLG_TYPE type) -{ - FileDialogImpl *fdimpl; - HRESULT hr; - IShellFolder *psf; - TRACE("%p, %s, %p\n", pUnkOuter, debugstr_guid(riid), ppv); - - if(!ppv) - return E_POINTER; - if(pUnkOuter) - return CLASS_E_NOAGGREGATION; - - fdimpl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FileDialogImpl)); - if(!fdimpl) - return E_OUTOFMEMORY; - - fdimpl->ref = 1; - fdimpl->IFileDialog2_iface.lpVtbl = &vt_IFileDialog2; - fdimpl->IExplorerBrowserEvents_iface.lpVtbl = &vt_IExplorerBrowserEvents; - fdimpl->IServiceProvider_iface.lpVtbl = &vt_IServiceProvider; - fdimpl->ICommDlgBrowser3_iface.lpVtbl = &vt_ICommDlgBrowser3; - fdimpl->IOleWindow_iface.lpVtbl = &vt_IOleWindow; - fdimpl->IFileDialogCustomize_iface.lpVtbl = &vt_IFileDialogCustomize; - - if(type == ITEMDLG_TYPE_OPEN) - { - fdimpl->dlg_type = ITEMDLG_TYPE_OPEN; - fdimpl->u.IFileOpenDialog_iface.lpVtbl = &vt_IFileOpenDialog; - fdimpl->options = FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_NOCHANGEDIR; - fdimpl->custom_title = fdimpl->custom_okbutton = NULL; - } - else - { - WCHAR buf[16]; - fdimpl->dlg_type = ITEMDLG_TYPE_SAVE; - fdimpl->u.IFileSaveDialog_iface.lpVtbl = &vt_IFileSaveDialog; - fdimpl->options = FOS_OVERWRITEPROMPT | FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR; - - LoadStringW(COMDLG32_hInstance, IDS_SAVE, buf, ARRAY_SIZE(buf)); - fdimpl->custom_title = StrDupW(buf); - fdimpl->custom_okbutton = StrDupW(buf); - } - - list_init(&fdimpl->events_clients); - - /* FIXME: The default folder setting should be restored for the - * application if it was previously set. */ - SHGetDesktopFolder(&psf); - SHGetItemFromObject((IUnknown*)psf, &IID_IShellItem, (void**)&fdimpl->psi_defaultfolder); - IShellFolder_Release(psf); - - hr = init_custom_controls(fdimpl); - if(FAILED(hr)) - { - ERR("Failed to initialize custom controls (0x%08x).\n", hr); - IFileDialog2_Release(&fdimpl->IFileDialog2_iface); - return E_FAIL; - } - - hr = IFileDialog2_QueryInterface(&fdimpl->IFileDialog2_iface, riid, ppv); - IFileDialog2_Release(&fdimpl->IFileDialog2_iface); - return hr; -} - -HRESULT FileOpenDialog_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv) -{ - return FileDialog_constructor(pUnkOuter, riid, ppv, ITEMDLG_TYPE_OPEN); -} - -HRESULT FileSaveDialog_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv) -{ - return FileDialog_constructor(pUnkOuter, riid, ppv, ITEMDLG_TYPE_SAVE); -} diff --git a/wrappers/extensions/comdlgex/main.c b/wrappers/extensions/comdlgex/main.c deleted file mode 100644 index c96af67fc1..0000000000 --- a/wrappers/extensions/comdlgex/main.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Performance Data Helper (pdh.dll) - * - * Copyright 2007 Andrey Turkin - * Copyright 2007 Hans Leidekker - * - * 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 - */ - -#define WIN32_NO_STATUS - -#include -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT -#include -#include - -//#include "winperf.h" - -#include -#include -#include -#include - -WINE_DEFAULT_DEBUG_CHANNEL(comdlg32); diff --git a/wrappers/extensions/comdlgex/main.h b/wrappers/extensions/comdlgex/main.h deleted file mode 100644 index afc89c5f7f..0000000000 --- a/wrappers/extensions/comdlgex/main.h +++ /dev/null @@ -1,16 +0,0 @@ -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -LSTATUS -WINAPI -RegGetValueW( - _In_ HKEY hkey, - _In_opt_ LPCWSTR lpSubKey, - _In_opt_ LPCWSTR lpValue, - _In_ DWORD dwFlags, - _Out_opt_ LPDWORD pdwType, - _When_((dwFlags & 0x7F) == RRF_RT_REG_SZ || (dwFlags & 0x7F) == RRF_RT_REG_EXPAND_SZ || - (dwFlags & 0x7F) == (RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ) || *pdwType == REG_SZ || - *pdwType == REG_EXPAND_SZ, _Post_z_) - _When_((dwFlags & 0x7F) == RRF_RT_REG_MULTI_SZ || *pdwType == REG_MULTI_SZ, _Post_ _NullNull_terminated_) - _Out_writes_bytes_to_opt_(*pcbData,*pcbData) PVOID pvData, - _Inout_opt_ LPDWORD pcbData); \ No newline at end of file diff --git a/wrappers/extensions/comdlgex/network.ico b/wrappers/extensions/comdlgex/network.ico deleted file mode 100644 index 1683b7ce4c..0000000000 Binary files a/wrappers/extensions/comdlgex/network.ico and /dev/null differ diff --git a/wrappers/extensions/comdlgex/pd32_collate.ico b/wrappers/extensions/comdlgex/pd32_collate.ico deleted file mode 100644 index 55756e7f7a..0000000000 Binary files a/wrappers/extensions/comdlgex/pd32_collate.ico and /dev/null differ diff --git a/wrappers/extensions/comdlgex/pd32_collate.svg b/wrappers/extensions/comdlgex/pd32_collate.svg deleted file mode 100644 index 23e6f4761a..0000000000 --- a/wrappers/extensions/comdlgex/pd32_collate.svg +++ /dev/null @@ -1,676 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/wrappers/extensions/comdlgex/pd32_landscape.ico b/wrappers/extensions/comdlgex/pd32_landscape.ico deleted file mode 100644 index 1a31e6a8d1..0000000000 Binary files a/wrappers/extensions/comdlgex/pd32_landscape.ico and /dev/null differ diff --git a/wrappers/extensions/comdlgex/pd32_landscape.svg b/wrappers/extensions/comdlgex/pd32_landscape.svg deleted file mode 100644 index d52cac3321..0000000000 --- a/wrappers/extensions/comdlgex/pd32_landscape.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/wrappers/extensions/comdlgex/pd32_nocollate.ico b/wrappers/extensions/comdlgex/pd32_nocollate.ico deleted file mode 100644 index b71013a9ac..0000000000 Binary files a/wrappers/extensions/comdlgex/pd32_nocollate.ico and /dev/null differ diff --git a/wrappers/extensions/comdlgex/pd32_nocollate.svg b/wrappers/extensions/comdlgex/pd32_nocollate.svg deleted file mode 100644 index f12e05e6ec..0000000000 --- a/wrappers/extensions/comdlgex/pd32_nocollate.svg +++ /dev/null @@ -1,1689 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/wrappers/extensions/comdlgex/pd32_portrait.ico b/wrappers/extensions/comdlgex/pd32_portrait.ico deleted file mode 100644 index 432f73877a..0000000000 Binary files a/wrappers/extensions/comdlgex/pd32_portrait.ico and /dev/null differ diff --git a/wrappers/extensions/comdlgex/pd32_portrait.svg b/wrappers/extensions/comdlgex/pd32_portrait.svg deleted file mode 100644 index 911d64cf59..0000000000 --- a/wrappers/extensions/comdlgex/pd32_portrait.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/wrappers/extensions/comdlgex/printdlg.c b/wrappers/extensions/comdlgex/printdlg.c deleted file mode 100644 index e268050294..0000000000 --- a/wrappers/extensions/comdlgex/printdlg.c +++ /dev/null @@ -1,4256 +0,0 @@ -/* - * COMMDLG - Print Dialog - * - * Copyright 1994 Martin Ayotte - * Copyright 1996 Albrecht Kleine - * Copyright 1999 Klaas van Gend - * Copyright 2000 Huw D M Davies - * Copyright 2010 Vitaly Perov - * - * 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 -#include -#include -#include -#include - -#define COBJMACROS -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "winspool.h" -#include "winerror.h" -#include "objbase.h" -#include "commdlg.h" - -#include "wine/debug.h" - -#include "dlgs.h" -#include "cderr.h" -#include "cdlg.h" - -WINE_DEFAULT_DEBUG_CHANNEL(commdlg); - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -/* Yes these constants are the same, but we're just copying win98 */ -#define UPDOWN_ID 0x270f -#define MAX_COPIES 9999 - -/* This PRINTDLGA internal structure stores - * pointers to several throughout useful structures. - */ - -typedef struct -{ - LPDEVMODEA lpDevMode; - LPPRINTDLGA lpPrintDlg; - LPPRINTER_INFO_2A lpPrinterInfo; - LPDRIVER_INFO_3A lpDriverInfo; - UINT HelpMessageID; - HICON hCollateIcon; /* PrintDlg only */ - HICON hNoCollateIcon; /* PrintDlg only */ - HICON hPortraitIcon; /* PrintSetupDlg only */ - HICON hLandscapeIcon; /* PrintSetupDlg only */ - HWND hwndUpDown; -} PRINT_PTRA; - -typedef struct -{ - LPDEVMODEW lpDevMode; - LPPRINTDLGW lpPrintDlg; - LPPRINTER_INFO_2W lpPrinterInfo; - LPDRIVER_INFO_3W lpDriverInfo; - UINT HelpMessageID; - HICON hCollateIcon; /* PrintDlg only */ - HICON hNoCollateIcon; /* PrintDlg only */ - HICON hPortraitIcon; /* PrintSetupDlg only */ - HICON hLandscapeIcon; /* PrintSetupDlg only */ - HWND hwndUpDown; -} PRINT_PTRW; - -/* Debugging info */ -struct pd_flags -{ - DWORD flag; - LPCSTR name; -}; - -static const struct pd_flags psd_flags[] = { - {PSD_MINMARGINS,"PSD_MINMARGINS"}, - {PSD_MARGINS,"PSD_MARGINS"}, - {PSD_INTHOUSANDTHSOFINCHES,"PSD_INTHOUSANDTHSOFINCHES"}, - {PSD_INHUNDREDTHSOFMILLIMETERS,"PSD_INHUNDREDTHSOFMILLIMETERS"}, - {PSD_DISABLEMARGINS,"PSD_DISABLEMARGINS"}, - {PSD_DISABLEPRINTER,"PSD_DISABLEPRINTER"}, - {PSD_NOWARNING,"PSD_NOWARNING"}, - {PSD_DISABLEORIENTATION,"PSD_DISABLEORIENTATION"}, - {PSD_RETURNDEFAULT,"PSD_RETURNDEFAULT"}, - {PSD_DISABLEPAPER,"PSD_DISABLEPAPER"}, - {PSD_SHOWHELP,"PSD_SHOWHELP"}, - {PSD_ENABLEPAGESETUPHOOK,"PSD_ENABLEPAGESETUPHOOK"}, - {PSD_ENABLEPAGESETUPTEMPLATE,"PSD_ENABLEPAGESETUPTEMPLATE"}, - {PSD_ENABLEPAGESETUPTEMPLATEHANDLE,"PSD_ENABLEPAGESETUPTEMPLATEHANDLE"}, - {PSD_ENABLEPAGEPAINTHOOK,"PSD_ENABLEPAGEPAINTHOOK"}, - {PSD_DISABLEPAGEPAINTING,"PSD_DISABLEPAGEPAINTING"}, - {-1, NULL} -}; - -static const struct pd_flags pd_flags[] = { - {PD_SELECTION, "PD_SELECTION "}, - {PD_PAGENUMS, "PD_PAGENUMS "}, - {PD_NOSELECTION, "PD_NOSELECTION "}, - {PD_NOPAGENUMS, "PD_NOPAGENUMS "}, - {PD_COLLATE, "PD_COLLATE "}, - {PD_PRINTTOFILE, "PD_PRINTTOFILE "}, - {PD_PRINTSETUP, "PD_PRINTSETUP "}, - {PD_NOWARNING, "PD_NOWARNING "}, - {PD_RETURNDC, "PD_RETURNDC "}, - {PD_RETURNIC, "PD_RETURNIC "}, - {PD_RETURNDEFAULT, "PD_RETURNDEFAULT "}, - {PD_SHOWHELP, "PD_SHOWHELP "}, - {PD_ENABLEPRINTHOOK, "PD_ENABLEPRINTHOOK "}, - {PD_ENABLESETUPHOOK, "PD_ENABLESETUPHOOK "}, - {PD_ENABLEPRINTTEMPLATE, "PD_ENABLEPRINTTEMPLATE "}, - {PD_ENABLESETUPTEMPLATE, "PD_ENABLESETUPTEMPLATE "}, - {PD_ENABLEPRINTTEMPLATEHANDLE, "PD_ENABLEPRINTTEMPLATEHANDLE "}, - {PD_ENABLESETUPTEMPLATEHANDLE, "PD_ENABLESETUPTEMPLATEHANDLE "}, - {PD_USEDEVMODECOPIES, "PD_USEDEVMODECOPIES[ANDCOLLATE] "}, - {PD_DISABLEPRINTTOFILE, "PD_DISABLEPRINTTOFILE "}, - {PD_HIDEPRINTTOFILE, "PD_HIDEPRINTTOFILE "}, - {PD_NONETWORKBUTTON, "PD_NONETWORKBUTTON "}, - {-1, NULL} -}; -/* address of wndproc for subclassed Static control */ -static WNDPROC lpfnStaticWndProc; -static WNDPROC edit_wndproc; -/* the text of the fake document to render for the Page Setup dialog */ -static WCHAR wszFakeDocumentText[1024]; -static const WCHAR printdlg_prop[] = L"__WINE_PRINTDLGDATA"; -static const WCHAR pagesetupdlg_prop[] = L"__WINE_PAGESETUPDLGDATA"; - - -/*********************************************************************** - * get_driver_info [internal] - * - * get DRIVER_INFO_3W for the current printer handle, - * alloc the buffer, when needed - */ -static DRIVER_INFO_3W * get_driver_infoW(HANDLE hprn) -{ - DRIVER_INFO_3W *di3 = NULL; - DWORD needed = 0; - BOOL res; - - res = GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed); - if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { - di3 = malloc(needed); - res = GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)di3, needed, &needed); - } - - if (res) - return di3; - - TRACE("GetPrinterDriverW failed with %lu\n", GetLastError()); - free(di3); - return NULL; -} - -static DRIVER_INFO_3A * get_driver_infoA(HANDLE hprn) -{ - DRIVER_INFO_3A *di3 = NULL; - DWORD needed = 0; - BOOL res; - - res = GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed); - if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { - di3 = malloc(needed); - res = GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)di3, needed, &needed); - } - - if (res) - return di3; - - TRACE("GetPrinterDriverA failed with %lu\n", GetLastError()); - free(di3); - return NULL; -} - - -/*********************************************************************** - * get_printer_info [internal] - * - * get PRINTER_INFO_2W for the current printer handle, - * alloc the buffer, when needed - */ -static PRINTER_INFO_2W * get_printer_infoW(HANDLE hprn) -{ - PRINTER_INFO_2W *pi2 = NULL; - DWORD needed = 0; - BOOL res; - - res = GetPrinterW(hprn, 2, NULL, 0, &needed); - if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { - pi2 = malloc(needed); - res = GetPrinterW(hprn, 2, (LPBYTE)pi2, needed, &needed); - } - - if (res) - return pi2; - - TRACE("GetPrinterW failed with %lu\n", GetLastError()); - free(pi2); - return NULL; -} - -static PRINTER_INFO_2A * get_printer_infoA(HANDLE hprn) -{ - PRINTER_INFO_2A *pi2 = NULL; - DWORD needed = 0; - BOOL res; - - res = GetPrinterA(hprn, 2, NULL, 0, &needed); - if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { - pi2 = malloc(needed); - res = GetPrinterA(hprn, 2, (LPBYTE)pi2, needed, &needed); - } - - if (res) - return pi2; - - TRACE("GetPrinterA failed with %lu\n", GetLastError()); - free(pi2); - return NULL; -} - - -/*********************************************************************** - * update_devmode_handle [internal] - * - * update a devmode handle for the given DEVMODE, alloc the buffer, when needed - */ -static HGLOBAL update_devmode_handleW(HGLOBAL hdm, DEVMODEW *dm) -{ - SIZE_T size = GlobalSize(hdm); - LPVOID ptr; - - /* Increase / alloc the global memory block, when needed */ - if ((dm->dmSize + dm->dmDriverExtra) > size) { - if (hdm) - hdm = GlobalReAlloc(hdm, dm->dmSize + dm->dmDriverExtra, GMEM_MOVEABLE); - else - hdm = GlobalAlloc(GMEM_MOVEABLE, dm->dmSize + dm->dmDriverExtra); - } - - if (hdm) { - ptr = GlobalLock(hdm); - if (ptr) { - memcpy(ptr, dm, dm->dmSize + dm->dmDriverExtra); - GlobalUnlock(hdm); - } - else - { - GlobalFree(hdm); - hdm = NULL; - } - } - return hdm; -} - -static HGLOBAL update_devmode_handleA(HGLOBAL hdm, DEVMODEA *dm) -{ - SIZE_T size = GlobalSize(hdm); - LPVOID ptr; - - /* Increase / alloc the global memory block, when needed */ - if ((dm->dmSize + dm->dmDriverExtra) > size) { - if (hdm) - hdm = GlobalReAlloc(hdm, dm->dmSize + dm->dmDriverExtra, GMEM_MOVEABLE); - else - hdm = GlobalAlloc(GMEM_MOVEABLE, dm->dmSize + dm->dmDriverExtra); - } - - if (hdm) { - ptr = GlobalLock(hdm); - if (ptr) { - memcpy(ptr, dm, dm->dmSize + dm->dmDriverExtra); - GlobalUnlock(hdm); - } - else - { - GlobalFree(hdm); - hdm = NULL; - } - } - return hdm; -} - -/*********************************************************** - * convert_to_devmodeA - * - * Creates an ansi copy of supplied devmode - */ -static DEVMODEA *convert_to_devmodeA(const DEVMODEW *dmW) -{ - DEVMODEA *dmA; - DWORD size; - - if (!dmW) return NULL; - size = dmW->dmSize - CCHDEVICENAME - - ((dmW->dmSize > FIELD_OFFSET(DEVMODEW, dmFormName)) ? CCHFORMNAME : 0); - - dmA = malloc(size + dmW->dmDriverExtra); - if (!dmA) return NULL; - - WideCharToMultiByte(CP_ACP, 0, dmW->dmDeviceName, -1, - (LPSTR)dmA->dmDeviceName, CCHDEVICENAME, NULL, NULL); - - if (FIELD_OFFSET(DEVMODEW, dmFormName) >= dmW->dmSize) - { - memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion, - dmW->dmSize - FIELD_OFFSET(DEVMODEW, dmSpecVersion)); - } - else - { - memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion, - FIELD_OFFSET(DEVMODEW, dmFormName) - FIELD_OFFSET(DEVMODEW, dmSpecVersion)); - WideCharToMultiByte(CP_ACP, 0, dmW->dmFormName, -1, - (LPSTR)dmA->dmFormName, CCHFORMNAME, NULL, NULL); - - memcpy(&dmA->dmLogPixels, &dmW->dmLogPixels, dmW->dmSize - FIELD_OFFSET(DEVMODEW, dmLogPixels)); - } - - dmA->dmSize = size; - memcpy((char *)dmA + dmA->dmSize, (const char *)dmW + dmW->dmSize, dmW->dmDriverExtra); - return dmA; -} - -/*********************************************************************** - * PRINTDLG_OpenDefaultPrinter - * - * Returns a winspool printer handle to the default printer in *hprn - * Caller must call ClosePrinter on the handle - * - * Returns TRUE on success else FALSE - */ -static BOOL PRINTDLG_OpenDefaultPrinter(HANDLE *hprn) -{ - WCHAR buf[260]; - DWORD dwBufLen = ARRAY_SIZE(buf); - BOOL res; - if(!GetDefaultPrinterW(buf, &dwBufLen)) - return FALSE; - res = OpenPrinterW(buf, hprn, NULL); - if (!res) - WARN("Could not open printer %s\n", debugstr_w(buf)); - return res; -} - -/*********************************************************************** - * PRINTDLG_SetUpPrinterListCombo - * - * Initializes printer list combox. - * hDlg: HWND of dialog - * id: Control id of combo - * name: Name of printer to select - * - * Initializes combo with list of available printers. Selects printer 'name' - * If name is NULL or does not exist select the default printer. - * - * Returns number of printers added to list. - */ -static INT PRINTDLG_SetUpPrinterListComboA(HWND hDlg, UINT id, LPCSTR name) -{ - DWORD needed, num; - INT i; - LPPRINTER_INFO_2A pi; - EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num); - pi = malloc(needed); - EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pi, needed, &needed, - &num); - - SendDlgItemMessageA(hDlg, id, CB_RESETCONTENT, 0, 0); - - for(i = 0; i < num; i++) { - SendDlgItemMessageA(hDlg, id, CB_ADDSTRING, 0, - (LPARAM)pi[i].pPrinterName ); - } - free(pi); - if(!name || - (i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1, - (LPARAM)name)) == CB_ERR) { - - char buf[260]; - DWORD dwBufLen = ARRAY_SIZE(buf); - if (name != NULL) - WARN("Can't find %s in printer list so trying to find default\n", - debugstr_a(name)); - if(!GetDefaultPrinterA(buf, &dwBufLen)) - return num; - i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1, (LPARAM)buf); - if(i == CB_ERR) - FIXME("Can't find default printer in printer list\n"); - } - SendDlgItemMessageA(hDlg, id, CB_SETCURSEL, i, 0); - return num; -} - -static INT PRINTDLG_SetUpPrinterListComboW(HWND hDlg, UINT id, LPCWSTR name) -{ - DWORD needed, num; - INT i; - LPPRINTER_INFO_2W pi; - EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num); - pi = malloc(needed); - EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pi, needed, &needed, - &num); - - for(i = 0; i < num; i++) { - SendDlgItemMessageW(hDlg, id, CB_ADDSTRING, 0, - (LPARAM)pi[i].pPrinterName ); - } - free(pi); - if(!name || - (i = SendDlgItemMessageW(hDlg, id, CB_FINDSTRINGEXACT, -1, - (LPARAM)name)) == CB_ERR) { - WCHAR buf[260]; - DWORD dwBufLen = ARRAY_SIZE(buf); - if (name != NULL) - WARN("Can't find %s in printer list so trying to find default\n", - debugstr_w(name)); - if(!GetDefaultPrinterW(buf, &dwBufLen)) - return num; - i = SendDlgItemMessageW(hDlg, id, CB_FINDSTRINGEXACT, -1, (LPARAM)buf); - if(i == CB_ERR) - TRACE("Can't find default printer in printer list\n"); - } - SendDlgItemMessageW(hDlg, id, CB_SETCURSEL, i, 0); - return num; -} - -/*********************************************************************** - * PRINTDLG_CreateDevNames [internal] - * - * - * creates a DevNames structure. - * - * (NB. when we handle unicode the offsets will be in wchars). - */ -static BOOL PRINTDLG_CreateDevNames(HGLOBAL *hmem, const char* DeviceDriverName, - const char* DeviceName, const char* OutputPort) -{ - long size; - char* pDevNamesSpace; - char* pTempPtr; - LPDEVNAMES lpDevNames; - char buf[260]; - DWORD dwBufLen = ARRAY_SIZE(buf); - const char *p; - - p = strrchr( DeviceDriverName, '\\' ); - if (p) DeviceDriverName = p + 1; - - size = strlen(DeviceDriverName) + 1 - + strlen(DeviceName) + 1 - + strlen(OutputPort) + 1 - + sizeof(DEVNAMES); - - if(*hmem) - *hmem = GlobalReAlloc(*hmem, size, GMEM_MOVEABLE); - else - *hmem = GlobalAlloc(GMEM_MOVEABLE, size); - if (*hmem == 0) - return FALSE; - - pDevNamesSpace = GlobalLock(*hmem); - lpDevNames = (LPDEVNAMES) pDevNamesSpace; - - pTempPtr = pDevNamesSpace + sizeof(DEVNAMES); - strcpy(pTempPtr, DeviceDriverName); - lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace; - - pTempPtr += strlen(DeviceDriverName) + 1; - strcpy(pTempPtr, DeviceName); - lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace; - - pTempPtr += strlen(DeviceName) + 1; - strcpy(pTempPtr, OutputPort); - lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace; - - GetDefaultPrinterA(buf, &dwBufLen); - lpDevNames->wDefault = (strcmp(buf, DeviceName) == 0) ? 1 : 0; - GlobalUnlock(*hmem); - return TRUE; -} - -static BOOL PRINTDLG_CreateDevNamesW(HGLOBAL *hmem, LPCWSTR DeviceDriverName, - LPCWSTR DeviceName, LPCWSTR OutputPort) -{ - long size; - LPWSTR pDevNamesSpace; - LPWSTR pTempPtr; - LPDEVNAMES lpDevNames; - WCHAR bufW[260]; - DWORD dwBufLen = ARRAY_SIZE(bufW); - const WCHAR *p; - - p = wcsrchr( DeviceDriverName, '\\' ); - if (p) DeviceDriverName = p + 1; - - size = sizeof(WCHAR)*lstrlenW(DeviceDriverName) + 2 - + sizeof(WCHAR)*lstrlenW(DeviceName) + 2 - + sizeof(WCHAR)*lstrlenW(OutputPort) + 2 - + sizeof(DEVNAMES); - - if(*hmem) - *hmem = GlobalReAlloc(*hmem, size, GMEM_MOVEABLE); - else - *hmem = GlobalAlloc(GMEM_MOVEABLE, size); - if (*hmem == 0) - return FALSE; - - pDevNamesSpace = GlobalLock(*hmem); - lpDevNames = (LPDEVNAMES) pDevNamesSpace; - - pTempPtr = (LPWSTR)((LPDEVNAMES)pDevNamesSpace + 1); - lstrcpyW(pTempPtr, DeviceDriverName); - lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace; - - pTempPtr += lstrlenW(DeviceDriverName) + 1; - lstrcpyW(pTempPtr, DeviceName); - lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace; - - pTempPtr += lstrlenW(DeviceName) + 1; - lstrcpyW(pTempPtr, OutputPort); - lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace; - - GetDefaultPrinterW(bufW, &dwBufLen); - lpDevNames->wDefault = (lstrcmpW(bufW, DeviceName) == 0) ? 1 : 0; - GlobalUnlock(*hmem); - return TRUE; -} - -/*********************************************************************** - * PRINTDLG_UpdatePrintDlg [internal] - * - * - * updates the PrintDlg structure for return values. - * - * RETURNS - * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values) - * TRUE if successful. - */ -static BOOL PRINTDLG_UpdatePrintDlgA(HWND hDlg, - PRINT_PTRA* PrintStructures) -{ - LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; - PDEVMODEA lpdm = PrintStructures->lpDevMode; - LPPRINTER_INFO_2A pi = PrintStructures->lpPrinterInfo; - - - if(!lpdm) { - FIXME("No lpdm ptr?\n"); - return FALSE; - } - - - if(!(lppd->Flags & PD_PRINTSETUP)) { - /* check whether nFromPage and nToPage are within range defined by - * nMinPage and nMaxPage - */ - if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED) { /* Pages */ - WORD nToPage; - WORD nFromPage; - BOOL translated; - nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE); - nToPage = GetDlgItemInt(hDlg, edt2, &translated, FALSE); - - /* if no ToPage value is entered, use the FromPage value */ - if(!translated) nToPage = nFromPage; - - if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage || - nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage) { - WCHAR resourcestr[256]; - WCHAR resultstr[256]; - LoadStringW(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE, resourcestr, 255); - wsprintfW(resultstr,resourcestr, lppd->nMinPage, lppd->nMaxPage); - LoadStringW(COMDLG32_hInstance, PD32_PRINT_TITLE, resourcestr, 255); - MessageBoxW(hDlg, resultstr, resourcestr, MB_OK | MB_ICONWARNING); - return FALSE; - } - lppd->nFromPage = nFromPage; - lppd->nToPage = nToPage; - lppd->Flags |= PD_PAGENUMS; - } - else - lppd->Flags &= ~PD_PAGENUMS; - - if (IsDlgButtonChecked(hDlg, rad2) == BST_CHECKED) /* Selection */ - lppd->Flags |= PD_SELECTION; - else - lppd->Flags &= ~PD_SELECTION; - - if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED) {/* Print to file */ - static char file[] = "FILE:"; - lppd->Flags |= PD_PRINTTOFILE; - pi->pPortName = file; - } - - if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) { /* Collate */ - FIXME("Collate lppd not yet implemented as output\n"); - } - - /* set PD_Collate and nCopies */ - if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { - /* The application doesn't support multiple copies or collate... - */ - lppd->Flags &= ~PD_COLLATE; - lppd->nCopies = 1; - /* if the printer driver supports it... store info there - * otherwise no collate & multiple copies ! - */ - if (lpdm->dmFields & DM_COLLATE) - lpdm->dmCollate = - (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED); - if (lpdm->dmFields & DM_COPIES) - lpdm->dmCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); - } else { - /* Application is responsible for multiple copies */ - if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) - lppd->Flags |= PD_COLLATE; - else - lppd->Flags &= ~PD_COLLATE; - lppd->nCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); - /* multiple copies already included in the document. Driver must print only one copy */ - lpdm->dmCopies = 1; - } - - /* Print quality, PrintDlg16 */ - if(GetDlgItem(hDlg, cmb1)) - { - HWND hQuality = GetDlgItem(hDlg, cmb1); - int Sel = SendMessageA(hQuality, CB_GETCURSEL, 0, 0); - - if(Sel != CB_ERR) - { - LONG dpi = SendMessageA(hQuality, CB_GETITEMDATA, Sel, 0); - lpdm->dmFields |= DM_PRINTQUALITY | DM_YRESOLUTION; - lpdm->dmPrintQuality = LOWORD(dpi); - lpdm->dmYResolution = HIWORD(dpi); - } - } - } - return TRUE; -} - -static BOOL PRINTDLG_UpdatePrintDlgW(HWND hDlg, - PRINT_PTRW* PrintStructures) -{ - LPPRINTDLGW lppd = PrintStructures->lpPrintDlg; - PDEVMODEW lpdm = PrintStructures->lpDevMode; - LPPRINTER_INFO_2W pi = PrintStructures->lpPrinterInfo; - - - if(!lpdm) { - FIXME("No lpdm ptr?\n"); - return FALSE; - } - - - if(!(lppd->Flags & PD_PRINTSETUP)) { - /* check whether nFromPage and nToPage are within range defined by - * nMinPage and nMaxPage - */ - if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED) { /* Pages */ - WORD nToPage; - WORD nFromPage; - BOOL translated; - nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE); - nToPage = GetDlgItemInt(hDlg, edt2, &translated, FALSE); - - /* if no ToPage value is entered, use the FromPage value */ - if(!translated) nToPage = nFromPage; - - if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage || - nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage) { - WCHAR resourcestr[256]; - WCHAR resultstr[256]; - DWORD_PTR args[2]; - LoadStringW(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE, - resourcestr, 255); - args[0] = lppd->nMinPage; - args[1] = lppd->nMaxPage; - FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY, - resourcestr, 0, 0, resultstr, ARRAY_SIZE(resultstr), (va_list *)args); - LoadStringW(COMDLG32_hInstance, PD32_PRINT_TITLE, - resourcestr, 255); - MessageBoxW(hDlg, resultstr, resourcestr, - MB_OK | MB_ICONWARNING); - return FALSE; - } - lppd->nFromPage = nFromPage; - lppd->nToPage = nToPage; - lppd->Flags |= PD_PAGENUMS; - } - else - lppd->Flags &= ~PD_PAGENUMS; - - if (IsDlgButtonChecked(hDlg, rad2) == BST_CHECKED) /* Selection */ - lppd->Flags |= PD_SELECTION; - else - lppd->Flags &= ~PD_SELECTION; - - if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED) {/* Print to file */ - static WCHAR file[] = L"FILE:"; - lppd->Flags |= PD_PRINTTOFILE; - pi->pPortName = file; - } - - if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) { /* Collate */ - FIXME("Collate lppd not yet implemented as output\n"); - } - - /* set PD_Collate and nCopies */ - if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { - /* The application doesn't support multiple copies or collate... - */ - lppd->Flags &= ~PD_COLLATE; - lppd->nCopies = 1; - /* if the printer driver supports it... store info there - * otherwise no collate & multiple copies ! - */ - if (lpdm->dmFields & DM_COLLATE) - lpdm->dmCollate = - (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED); - if (lpdm->dmFields & DM_COPIES) - lpdm->dmCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); - } else { - if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) - lppd->Flags |= PD_COLLATE; - else - lppd->Flags &= ~PD_COLLATE; - lppd->nCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); - } - } - return TRUE; -} - -/************************************************************************ - * PRINTDLG_SetUpPaperComboBox - * - * Initialize either the papersize or inputslot combos of the Printer Setup - * dialog. We store the associated word (eg DMPAPER_A4) as the item data. - * We also try to re-select the old selection. - */ -static BOOL PRINTDLG_SetUpPaperComboBoxA(HWND hDlg, - int nIDComboBox, - char* PrinterName, - char* PortName, - LPDEVMODEA dm) -{ - int i; - int NrOfEntries; - char* Names; - WORD* Words; - DWORD Sel, old_Sel; - WORD oldWord = 0, newWord = 0; /* DMPAPER_ and DMBIN_ start at 1 */ - int NamesSize; - int fwCapability_Names; - int fwCapability_Words; - - TRACE(" Printer: %s, Port: %s, ComboID: %d\n",PrinterName,PortName,nIDComboBox); - - /* query the dialog box for the current selected value */ - Sel = SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETCURSEL, 0, 0); - if(Sel != CB_ERR) { - /* we enter here only if a different printer is selected after - * the Print Setup dialog is opened. The current settings are - * stored into the newly selected printer. - */ - oldWord = SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, - Sel, 0); - if(oldWord >= DMPAPER_USER) /* DMPAPER_USER == DMBIN_USER */ - oldWord = 0; /* There's no point in trying to keep custom - paper / bin sizes across printers */ - } - - if (dm) - newWord = (nIDComboBox == cmb2) ? dm->dmPaperSize : dm->dmDefaultSource; - - if (nIDComboBox == cmb2) { - NamesSize = 64; - fwCapability_Names = DC_PAPERNAMES; - fwCapability_Words = DC_PAPERS; - } else { - nIDComboBox = cmb3; - NamesSize = 24; - fwCapability_Names = DC_BINNAMES; - fwCapability_Words = DC_BINS; - } - - NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName, - fwCapability_Names, NULL, dm); - if (NrOfEntries == 0) - WARN("no Name Entries found!\n"); - else if (NrOfEntries < 0) - return FALSE; - - if(DeviceCapabilitiesA(PrinterName, PortName, fwCapability_Words, NULL, dm) - != NrOfEntries) { - ERR("Number of caps is different\n"); - NrOfEntries = 0; - } - - Names = malloc(NrOfEntries * sizeof(char) * NamesSize); - Words = malloc(NrOfEntries * sizeof(WORD)); - DeviceCapabilitiesA(PrinterName, PortName, fwCapability_Names, Names, dm); - NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName, - fwCapability_Words, (LPSTR)Words, dm); - - /* reset any current content in the combobox */ - SendDlgItemMessageA(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0); - - /* store new content */ - for (i = 0; i < NrOfEntries; i++) { - DWORD pos = SendDlgItemMessageA(hDlg, nIDComboBox, CB_ADDSTRING, 0, - (LPARAM)(&Names[i*NamesSize]) ); - SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETITEMDATA, pos, - Words[i]); - } - - /* Look for old selection or the new default. - Can't do this is previous loop since item order will change as more items are added */ - Sel = 0; - old_Sel = NrOfEntries; - for (i = 0; i < NrOfEntries; i++) { - if(SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) == - oldWord) { - old_Sel = i; - break; - } - if(SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) == newWord) - Sel = i; - } - - if(old_Sel < NrOfEntries) - { - if (dm) - { - if(nIDComboBox == cmb2) - dm->dmPaperSize = oldWord; - else - dm->dmDefaultSource = oldWord; - } - Sel = old_Sel; - } - - SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETCURSEL, Sel, 0); - - free(Words); - free(Names); - return TRUE; -} - -static BOOL PRINTDLG_SetUpPaperComboBoxW(HWND hDlg, - int nIDComboBox, - const WCHAR* PrinterName, - const WCHAR* PortName, - LPDEVMODEW dm) -{ - int i; - int NrOfEntries; - WCHAR* Names; - WORD* Words; - DWORD Sel, old_Sel; - WORD oldWord = 0, newWord = 0; /* DMPAPER_ and DMBIN_ start at 1 */ - int NamesSize; - int fwCapability_Names; - int fwCapability_Words; - - TRACE(" Printer: %s, Port: %s, ComboID: %d\n",debugstr_w(PrinterName),debugstr_w(PortName),nIDComboBox); - - /* query the dialog box for the current selected value */ - Sel = SendDlgItemMessageW(hDlg, nIDComboBox, CB_GETCURSEL, 0, 0); - if(Sel != CB_ERR) { - /* we enter here only if a different printer is selected after - * the Print Setup dialog is opened. The current settings are - * stored into the newly selected printer. - */ - oldWord = SendDlgItemMessageW(hDlg, nIDComboBox, CB_GETITEMDATA, - Sel, 0); - - if(oldWord >= DMPAPER_USER) /* DMPAPER_USER == DMBIN_USER */ - oldWord = 0; /* There's no point in trying to keep custom - paper / bin sizes across printers */ - } - - if (dm) - newWord = (nIDComboBox == cmb2) ? dm->dmPaperSize : dm->dmDefaultSource; - - if (nIDComboBox == cmb2) { - NamesSize = 64; - fwCapability_Names = DC_PAPERNAMES; - fwCapability_Words = DC_PAPERS; - } else { - nIDComboBox = cmb3; - NamesSize = 24; - fwCapability_Names = DC_BINNAMES; - fwCapability_Words = DC_BINS; - } - - NrOfEntries = DeviceCapabilitiesW(PrinterName, PortName, - fwCapability_Names, NULL, dm); - if (NrOfEntries == 0) - WARN("no Name Entries found!\n"); - else if (NrOfEntries < 0) - return FALSE; - - if(DeviceCapabilitiesW(PrinterName, PortName, fwCapability_Words, NULL, dm) - != NrOfEntries) { - ERR("Number of caps is different\n"); - NrOfEntries = 0; - } - - Names = malloc(NrOfEntries * sizeof(WCHAR) * NamesSize); - Words = malloc(NrOfEntries * sizeof(WORD)); - DeviceCapabilitiesW(PrinterName, PortName, fwCapability_Names, Names, dm); - NrOfEntries = DeviceCapabilitiesW(PrinterName, PortName, - fwCapability_Words, Words, dm); - - /* reset any current content in the combobox */ - SendDlgItemMessageW(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0); - - /* store new content */ - for (i = 0; i < NrOfEntries; i++) { - DWORD pos = SendDlgItemMessageW(hDlg, nIDComboBox, CB_ADDSTRING, 0, - (LPARAM)(&Names[i*NamesSize]) ); - SendDlgItemMessageW(hDlg, nIDComboBox, CB_SETITEMDATA, pos, - Words[i]); - } - - /* Look for old selection or the new default. - Can't do this is previous loop since item order will change as more items are added */ - Sel = 0; - old_Sel = NrOfEntries; - for (i = 0; i < NrOfEntries; i++) { - if(SendDlgItemMessageW(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) == - oldWord) { - old_Sel = i; - break; - } - if(SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) == newWord) - Sel = i; - } - - if(old_Sel < NrOfEntries) - { - if (dm) - { - if(nIDComboBox == cmb2) - dm->dmPaperSize = oldWord; - else - dm->dmDefaultSource = oldWord; - } - Sel = old_Sel; - } - - SendDlgItemMessageW(hDlg, nIDComboBox, CB_SETCURSEL, Sel, 0); - - free(Words); - free(Names); - return TRUE; -} - - -/*********************************************************************** - * PRINTDLG_UpdatePrinterInfoTexts [internal] - */ -static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg, const PRINTER_INFO_2A *pi) -{ - char StatusMsg[256]; - char ResourceString[256]; - int i; - - /* Status Message */ - StatusMsg[0]='\0'; - - /* add all status messages */ - for (i = 0; i < 25; i++) { - if (pi->Status & (1<pDriverName); - - if (pi->pLocation != NULL && pi->pLocation[0] != '\0') - SetDlgItemTextA(hDlg, stc14, pi->pLocation); - else - SetDlgItemTextA(hDlg, stc14, pi->pPortName); - SetDlgItemTextA(hDlg, stc13, pi->pComment ? pi->pComment : ""); - return; -} - -static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg, const PRINTER_INFO_2W *pi) -{ - WCHAR StatusMsg[256]; - WCHAR ResourceString[256]; - int i; - - /* Status Message */ - StatusMsg[0]='\0'; - - /* add all status messages */ - for (i = 0; i < 25; i++) { - if (pi->Status & (1<pDriverName); - if (pi->pLocation != NULL && pi->pLocation[0] != '\0') - SetDlgItemTextW(hDlg, stc14, pi->pLocation); - else - SetDlgItemTextW(hDlg, stc14, pi->pPortName); - SetDlgItemTextW(hDlg, stc13, pi->pComment ? pi->pComment : L""); -} - - -/******************************************************************* - * - * PRINTDLG_ChangePrinter - * - */ -static BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name, PRINT_PTRA *PrintStructures) -{ - LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; - LPDEVMODEA lpdm = NULL; - LONG dmSize; - DWORD needed; - HANDLE hprn; - - free(PrintStructures->lpPrinterInfo); - free(PrintStructures->lpDriverInfo); - if(!OpenPrinterA(name, &hprn, NULL)) { - ERR("Can't open printer %s\n", name); - return FALSE; - } - GetPrinterA(hprn, 2, NULL, 0, &needed); - PrintStructures->lpPrinterInfo = malloc(needed); - GetPrinterA(hprn, 2, (LPBYTE)PrintStructures->lpPrinterInfo, needed, - &needed); - GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed); - PrintStructures->lpDriverInfo = malloc(needed); - if (!GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)PrintStructures->lpDriverInfo, - needed, &needed)) { - ERR("GetPrinterDriverA failed for %s, fix your config!\n",PrintStructures->lpPrinterInfo->pPrinterName); - return FALSE; - } - ClosePrinter(hprn); - - PRINTDLG_UpdatePrinterInfoTextsA(hDlg, PrintStructures->lpPrinterInfo); - - free(PrintStructures->lpDevMode); - PrintStructures->lpDevMode = NULL; - - dmSize = DocumentPropertiesA(0, 0, name, NULL, NULL, 0); - if(dmSize == -1) { - ERR("DocumentProperties fails on %s\n", debugstr_a(name)); - return FALSE; - } - PrintStructures->lpDevMode = malloc(dmSize); - dmSize = DocumentPropertiesA(0, 0, name, PrintStructures->lpDevMode, NULL, - DM_OUT_BUFFER); - if(lppd->hDevMode && (lpdm = GlobalLock(lppd->hDevMode)) && - !lstrcmpA( (LPSTR) lpdm->dmDeviceName, - (LPSTR) PrintStructures->lpDevMode->dmDeviceName)) { - /* Supplied devicemode matches current printer so try to use it */ - DocumentPropertiesA(0, 0, name, PrintStructures->lpDevMode, lpdm, - DM_OUT_BUFFER | DM_IN_BUFFER); - } - if(lpdm) - GlobalUnlock(lppd->hDevMode); - - lpdm = PrintStructures->lpDevMode; /* use this as a shortcut */ - - if(!(lppd->Flags & PD_PRINTSETUP)) { - /* Print range (All/Range/Selection) */ - if(lppd->nFromPage != 0xffff) - SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE); - if(lppd->nToPage != 0xffff) - SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE); - - CheckRadioButton(hDlg, rad1, rad3, rad1); /* default */ - if (lppd->Flags & PD_NOSELECTION) - EnableWindow(GetDlgItem(hDlg, rad2), FALSE); - else - if (lppd->Flags & PD_SELECTION) - CheckRadioButton(hDlg, rad1, rad3, rad2); - if (lppd->Flags & PD_NOPAGENUMS) { - EnableWindow(GetDlgItem(hDlg, rad3), FALSE); - EnableWindow(GetDlgItem(hDlg, stc2),FALSE); - EnableWindow(GetDlgItem(hDlg, edt1), FALSE); - EnableWindow(GetDlgItem(hDlg, stc3),FALSE); - EnableWindow(GetDlgItem(hDlg, edt2), FALSE); - } else { - if (lppd->Flags & PD_PAGENUMS) - CheckRadioButton(hDlg, rad1, rad3, rad3); - } - - /* Collate pages - * - * FIXME: The ico3 is not displayed for some reason. I don't know why. - */ - if (lppd->Flags & PD_COLLATE) { - SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hCollateIcon); - CheckDlgButton(hDlg, chx2, 1); - } else { - SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hNoCollateIcon); - CheckDlgButton(hDlg, chx2, 0); - } - - if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { - /* if printer doesn't support it: no Collate */ - if (!(lpdm->dmFields & DM_COLLATE)) { - EnableWindow(GetDlgItem(hDlg, chx2), FALSE); - EnableWindow(GetDlgItem(hDlg, ico3), FALSE); - } - } - - /* nCopies */ - { - INT copies; - if (lppd->hDevMode == 0) - copies = lppd->nCopies; - else - copies = lpdm->dmCopies; - if(copies == 0) copies = 1; - else if(copies < 0) copies = MAX_COPIES; - SetDlgItemInt(hDlg, edt3, copies, FALSE); - } - - if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { - /* if printer doesn't support it: no nCopies */ - if (!(lpdm->dmFields & DM_COPIES)) { - EnableWindow(GetDlgItem(hDlg, edt3), FALSE); - EnableWindow(GetDlgItem(hDlg, stc5), FALSE); - } - } - - /* print to file */ - CheckDlgButton(hDlg, chx1, (lppd->Flags & PD_PRINTTOFILE) ? 1 : 0); - if (lppd->Flags & PD_DISABLEPRINTTOFILE) - EnableWindow(GetDlgItem(hDlg, chx1), FALSE); - if (lppd->Flags & PD_HIDEPRINTTOFILE) - ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE); - - /* Fill print quality combo, PrintDlg16 */ - if(GetDlgItem(hDlg, cmb1)) - { - DWORD numResolutions = DeviceCapabilitiesA(PrintStructures->lpPrinterInfo->pPrinterName, - PrintStructures->lpPrinterInfo->pPortName, - DC_ENUMRESOLUTIONS, NULL, lpdm); - - if(numResolutions != -1) - { - HWND hQuality = GetDlgItem(hDlg, cmb1); - LONG* Resolutions; - char buf[255]; - DWORD i; - int dpiX, dpiY; - HDC hPrinterDC = CreateDCA(PrintStructures->lpPrinterInfo->pDriverName, - PrintStructures->lpPrinterInfo->pPrinterName, - 0, lpdm); - - Resolutions = malloc(numResolutions * sizeof(LONG) * 2); - DeviceCapabilitiesA(PrintStructures->lpPrinterInfo->pPrinterName, - PrintStructures->lpPrinterInfo->pPortName, - DC_ENUMRESOLUTIONS, (LPSTR)Resolutions, lpdm); - - dpiX = GetDeviceCaps(hPrinterDC, LOGPIXELSX); - dpiY = GetDeviceCaps(hPrinterDC, LOGPIXELSY); - DeleteDC(hPrinterDC); - - SendMessageA(hQuality, CB_RESETCONTENT, 0, 0); - for(i = 0; i < (numResolutions * 2); i += 2) - { - BOOL IsDefault = FALSE; - LRESULT Index; - - if(Resolutions[i] == Resolutions[i+1]) - { - if(dpiX == Resolutions[i]) - IsDefault = TRUE; - sprintf(buf, "%ld dpi", Resolutions[i]); - } else - { - if(dpiX == Resolutions[i] && dpiY == Resolutions[i+1]) - IsDefault = TRUE; - sprintf(buf, "%ld dpi x %ld dpi", Resolutions[i], Resolutions[i+1]); - } - - Index = SendMessageA(hQuality, CB_ADDSTRING, 0, (LPARAM)buf); - - if(IsDefault) - SendMessageA(hQuality, CB_SETCURSEL, Index, 0); - - SendMessageA(hQuality, CB_SETITEMDATA, Index, MAKELONG(dpiX,dpiY)); - } - free(Resolutions); - } - } - } else { /* PD_PRINTSETUP */ - BOOL bPortrait = (lpdm->dmOrientation == DMORIENT_PORTRAIT); - - PRINTDLG_SetUpPaperComboBoxA(hDlg, cmb2, - PrintStructures->lpPrinterInfo->pPrinterName, - PrintStructures->lpPrinterInfo->pPortName, - lpdm); - PRINTDLG_SetUpPaperComboBoxA(hDlg, cmb3, - PrintStructures->lpPrinterInfo->pPrinterName, - PrintStructures->lpPrinterInfo->pPortName, - lpdm); - CheckRadioButton(hDlg, rad1, rad2, bPortrait ? rad1: rad2); - SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)(bPortrait ? PrintStructures->hPortraitIcon : - PrintStructures->hLandscapeIcon)); - - } - - /* help button */ - if ((lppd->Flags & PD_SHOWHELP)==0) { - /* hide if PD_SHOWHELP not specified */ - ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE); - } - return TRUE; -} - -static BOOL PRINTDLG_ChangePrinterW(HWND hDlg, WCHAR *name, - PRINT_PTRW *PrintStructures) -{ - LPPRINTDLGW lppd = PrintStructures->lpPrintDlg; - LPDEVMODEW lpdm = NULL; - LONG dmSize; - DWORD needed; - HANDLE hprn; - - free(PrintStructures->lpPrinterInfo); - free(PrintStructures->lpDriverInfo); - if(!OpenPrinterW(name, &hprn, NULL)) { - ERR("Can't open printer %s\n", debugstr_w(name)); - return FALSE; - } - GetPrinterW(hprn, 2, NULL, 0, &needed); - PrintStructures->lpPrinterInfo = malloc(needed); - GetPrinterW(hprn, 2, (LPBYTE)PrintStructures->lpPrinterInfo, needed, - &needed); - GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed); - PrintStructures->lpDriverInfo = malloc(needed); - if (!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)PrintStructures->lpDriverInfo, - needed, &needed)) { - ERR("GetPrinterDriverA failed for %s, fix your config!\n",debugstr_w(PrintStructures->lpPrinterInfo->pPrinterName)); - return FALSE; - } - ClosePrinter(hprn); - - PRINTDLG_UpdatePrinterInfoTextsW(hDlg, PrintStructures->lpPrinterInfo); - - free(PrintStructures->lpDevMode); - PrintStructures->lpDevMode = NULL; - - dmSize = DocumentPropertiesW(0, 0, name, NULL, NULL, 0); - if(dmSize == -1) { - ERR("DocumentProperties fails on %s\n", debugstr_w(name)); - return FALSE; - } - PrintStructures->lpDevMode = malloc(dmSize); - dmSize = DocumentPropertiesW(0, 0, name, PrintStructures->lpDevMode, NULL, - DM_OUT_BUFFER); - if(lppd->hDevMode && (lpdm = GlobalLock(lppd->hDevMode)) && - !lstrcmpW(lpdm->dmDeviceName, - PrintStructures->lpDevMode->dmDeviceName)) { - /* Supplied devicemode matches current printer so try to use it */ - DocumentPropertiesW(0, 0, name, PrintStructures->lpDevMode, lpdm, - DM_OUT_BUFFER | DM_IN_BUFFER); - } - if(lpdm) - GlobalUnlock(lppd->hDevMode); - - lpdm = PrintStructures->lpDevMode; /* use this as a shortcut */ - - if(!(lppd->Flags & PD_PRINTSETUP)) { - /* Print range (All/Range/Selection) */ - if(lppd->nFromPage != 0xffff) - SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE); - if(lppd->nToPage != 0xffff) - SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE); - - CheckRadioButton(hDlg, rad1, rad3, rad1); /* default */ - if (lppd->Flags & PD_NOSELECTION) - EnableWindow(GetDlgItem(hDlg, rad2), FALSE); - else - if (lppd->Flags & PD_SELECTION) - CheckRadioButton(hDlg, rad1, rad3, rad2); - if (lppd->Flags & PD_NOPAGENUMS) { - EnableWindow(GetDlgItem(hDlg, rad3), FALSE); - EnableWindow(GetDlgItem(hDlg, stc2),FALSE); - EnableWindow(GetDlgItem(hDlg, edt1), FALSE); - EnableWindow(GetDlgItem(hDlg, stc3),FALSE); - EnableWindow(GetDlgItem(hDlg, edt2), FALSE); - } else { - if (lppd->Flags & PD_PAGENUMS) - CheckRadioButton(hDlg, rad1, rad3, rad3); - } - - /* Collate pages - * - * FIXME: The ico3 is not displayed for some reason. I don't know why. - */ - if (lppd->Flags & PD_COLLATE) { - SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hCollateIcon); - CheckDlgButton(hDlg, chx2, 1); - } else { - SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hNoCollateIcon); - CheckDlgButton(hDlg, chx2, 0); - } - - if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { - /* if printer doesn't support it: no Collate */ - if (!(lpdm->dmFields & DM_COLLATE)) { - EnableWindow(GetDlgItem(hDlg, chx2), FALSE); - EnableWindow(GetDlgItem(hDlg, ico3), FALSE); - } - } - - /* nCopies */ - { - INT copies; - if (lppd->hDevMode == 0) - copies = lppd->nCopies; - else - copies = lpdm->dmCopies; - if(copies == 0) copies = 1; - else if(copies < 0) copies = MAX_COPIES; - SetDlgItemInt(hDlg, edt3, copies, FALSE); - } - - if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { - /* if printer doesn't support it: no nCopies */ - if (!(lpdm->dmFields & DM_COPIES)) { - EnableWindow(GetDlgItem(hDlg, edt3), FALSE); - EnableWindow(GetDlgItem(hDlg, stc5), FALSE); - } - } - - /* print to file */ - CheckDlgButton(hDlg, chx1, (lppd->Flags & PD_PRINTTOFILE) ? 1 : 0); - if (lppd->Flags & PD_DISABLEPRINTTOFILE) - EnableWindow(GetDlgItem(hDlg, chx1), FALSE); - if (lppd->Flags & PD_HIDEPRINTTOFILE) - ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE); - - } else { /* PD_PRINTSETUP */ - BOOL bPortrait = (lpdm->dmOrientation == DMORIENT_PORTRAIT); - - PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb2, - PrintStructures->lpPrinterInfo->pPrinterName, - PrintStructures->lpPrinterInfo->pPortName, - lpdm); - PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb3, - PrintStructures->lpPrinterInfo->pPrinterName, - PrintStructures->lpPrinterInfo->pPortName, - lpdm); - CheckRadioButton(hDlg, rad1, rad2, bPortrait ? rad1: rad2); - SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)(bPortrait ? PrintStructures->hPortraitIcon : - PrintStructures->hLandscapeIcon)); - - } - - /* help button */ - if ((lppd->Flags & PD_SHOWHELP)==0) { - /* hide if PD_SHOWHELP not specified */ - ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE); - } - return TRUE; -} - - /*********************************************************************** - * check_printer_setup [internal] - */ -static LRESULT check_printer_setup(HWND hDlg) -{ - DWORD needed,num; - WCHAR resourcestr[256],resultstr[256]; - - EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num); - if(needed == 0) - { - EnumPrintersW(PRINTER_ENUM_CONNECTIONS, NULL, 2, NULL, 0, &needed, &num); - } - if(needed > 0) - return TRUE; - else - { - LoadStringW(COMDLG32_hInstance, PD32_NO_DEVICES,resultstr, 255); - LoadStringW(COMDLG32_hInstance, PD32_PRINT_TITLE,resourcestr, 255); - MessageBoxW(hDlg, resultstr, resourcestr,MB_OK | MB_ICONWARNING); - return FALSE; - } -} - -/*********************************************************************** - * PRINTDLG_WMInitDialog [internal] - */ -static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, - PRINT_PTRA* PrintStructures) -{ - LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; - DEVNAMES *pdn; - DEVMODEA *pdm; - char *name = NULL; - UINT comboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; - - /* load Collate ICONs */ - /* We load these with LoadImage because they are not a standard - size and we don't want them rescaled */ - PrintStructures->hCollateIcon = - LoadImageA(COMDLG32_hInstance, "PD32_COLLATE", IMAGE_ICON, 0, 0, 0); - PrintStructures->hNoCollateIcon = - LoadImageA(COMDLG32_hInstance, "PD32_NOCOLLATE", IMAGE_ICON, 0, 0, 0); - - /* These can be done with LoadIcon */ - PrintStructures->hPortraitIcon = - LoadIconA(COMDLG32_hInstance, "PD32_PORTRAIT"); - PrintStructures->hLandscapeIcon = - LoadIconA(COMDLG32_hInstance, "PD32_LANDSCAPE"); - - /* display the collate/no_collate icon */ - SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hNoCollateIcon); - - if(PrintStructures->hCollateIcon == 0 || - PrintStructures->hNoCollateIcon == 0 || - PrintStructures->hPortraitIcon == 0 || - PrintStructures->hLandscapeIcon == 0) { - ERR("no icon in resource file\n"); - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - EndDialog(hDlg, FALSE); - } - - /* - * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message - * must be registered and the Help button must be shown. - */ - if (lppd->Flags & PD_SHOWHELP) { - if((PrintStructures->HelpMessageID = - RegisterWindowMessageA(HELPMSGSTRINGA)) == 0) { - COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL); - return FALSE; - } - } else - PrintStructures->HelpMessageID = 0; - - if(!(lppd->Flags &PD_PRINTSETUP)) { - PrintStructures->hwndUpDown = - CreateUpDownControl(WS_CHILD | WS_VISIBLE | WS_BORDER | - UDS_NOTHOUSANDS | UDS_ARROWKEYS | - UDS_ALIGNRIGHT | UDS_SETBUDDYINT, 0, 0, 0, 0, - hDlg, UPDOWN_ID, COMDLG32_hInstance, - GetDlgItem(hDlg, edt3), MAX_COPIES, 1, 1); - } - - /* FIXME: I allow more freedom than either Win95 or WinNT, - * which do not agree on what errors should be thrown or not - * in case nToPage or nFromPage is out-of-range. - */ - if (lppd->nMaxPage < lppd->nMinPage) - lppd->nMaxPage = lppd->nMinPage; - if (lppd->nMinPage == lppd->nMaxPage) - lppd->Flags |= PD_NOPAGENUMS; - if (lppd->nToPage < lppd->nMinPage) - lppd->nToPage = lppd->nMinPage; - if (lppd->nToPage > lppd->nMaxPage) - lppd->nToPage = lppd->nMaxPage; - if (lppd->nFromPage < lppd->nMinPage) - lppd->nFromPage = lppd->nMinPage; - if (lppd->nFromPage > lppd->nMaxPage) - lppd->nFromPage = lppd->nMaxPage; - - /* if we have the combo box, fill it */ - if (GetDlgItem(hDlg,comboID)) { - /* Fill Combobox - */ - pdn = GlobalLock(lppd->hDevNames); - pdm = GlobalLock(lppd->hDevMode); - if(pdn) - name = (char*)pdn + pdn->wDeviceOffset; - else if(pdm) - name = (char*)pdm->dmDeviceName; - PRINTDLG_SetUpPrinterListComboA(hDlg, comboID, name); - if(pdm) GlobalUnlock(lppd->hDevMode); - if(pdn) GlobalUnlock(lppd->hDevNames); - - /* Now find selected printer and update rest of dlg */ - name = malloc(256); - if (GetDlgItemTextA(hDlg, comboID, name, 255)) - PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); - free(name); - } else { - /* else use default printer */ - char name[200]; - DWORD dwBufLen = ARRAY_SIZE(name); - BOOL ret = GetDefaultPrinterA(name, &dwBufLen); - - if (ret) - PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); - else - FIXME("No default printer found, expect problems!\n"); - } - return TRUE; -} - -static LRESULT PRINTDLG_WMInitDialogW(HWND hDlg, - PRINT_PTRW* PrintStructures) -{ - LPPRINTDLGW lppd = PrintStructures->lpPrintDlg; - DEVNAMES *pdn; - DEVMODEW *pdm; - WCHAR *name = NULL; - UINT comboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; - - /* load Collate ICONs */ - /* We load these with LoadImage because they are not a standard - size and we don't want them rescaled */ - PrintStructures->hCollateIcon = - LoadImageW(COMDLG32_hInstance, L"PD32_COLLATE", IMAGE_ICON, 0, 0, 0); - PrintStructures->hNoCollateIcon = - LoadImageW(COMDLG32_hInstance, L"PD32_NOCOLLATE", IMAGE_ICON, 0, 0, 0); - - /* These can be done with LoadIcon */ - PrintStructures->hPortraitIcon = - LoadIconW(COMDLG32_hInstance, L"PD32_PORTRAIT"); - PrintStructures->hLandscapeIcon = - LoadIconW(COMDLG32_hInstance, L"PD32_LANDSCAPE"); - - /* display the collate/no_collate icon */ - SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hNoCollateIcon); - - if(PrintStructures->hCollateIcon == 0 || - PrintStructures->hNoCollateIcon == 0 || - PrintStructures->hPortraitIcon == 0 || - PrintStructures->hLandscapeIcon == 0) { - ERR("no icon in resource file\n"); - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - EndDialog(hDlg, FALSE); - } - - /* - * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message - * must be registered and the Help button must be shown. - */ - if (lppd->Flags & PD_SHOWHELP) { - if((PrintStructures->HelpMessageID = - RegisterWindowMessageW(HELPMSGSTRINGW)) == 0) { - COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL); - return FALSE; - } - } else - PrintStructures->HelpMessageID = 0; - - if(!(lppd->Flags &PD_PRINTSETUP)) { - PrintStructures->hwndUpDown = - CreateUpDownControl(WS_CHILD | WS_VISIBLE | WS_BORDER | - UDS_NOTHOUSANDS | UDS_ARROWKEYS | - UDS_ALIGNRIGHT | UDS_SETBUDDYINT, 0, 0, 0, 0, - hDlg, UPDOWN_ID, COMDLG32_hInstance, - GetDlgItem(hDlg, edt3), MAX_COPIES, 1, 1); - } - - /* FIXME: I allow more freedom than either Win95 or WinNT, - * which do not agree to what errors should be thrown or not - * in case nToPage or nFromPage is out-of-range. - */ - if (lppd->nMaxPage < lppd->nMinPage) - lppd->nMaxPage = lppd->nMinPage; - if (lppd->nMinPage == lppd->nMaxPage) - lppd->Flags |= PD_NOPAGENUMS; - if (lppd->nToPage < lppd->nMinPage) - lppd->nToPage = lppd->nMinPage; - if (lppd->nToPage > lppd->nMaxPage) - lppd->nToPage = lppd->nMaxPage; - if (lppd->nFromPage < lppd->nMinPage) - lppd->nFromPage = lppd->nMinPage; - if (lppd->nFromPage > lppd->nMaxPage) - lppd->nFromPage = lppd->nMaxPage; - - /* if we have the combo box, fill it */ - if (GetDlgItem(hDlg,comboID)) { - /* Fill Combobox - */ - pdn = GlobalLock(lppd->hDevNames); - pdm = GlobalLock(lppd->hDevMode); - if(pdn) - name = (WCHAR*)pdn + pdn->wDeviceOffset; - else if(pdm) - name = pdm->dmDeviceName; - PRINTDLG_SetUpPrinterListComboW(hDlg, comboID, name); - if(pdm) GlobalUnlock(lppd->hDevMode); - if(pdn) GlobalUnlock(lppd->hDevNames); - - /* Now find selected printer and update rest of dlg */ - /* ansi is ok here */ - name = malloc(256 * sizeof(WCHAR)); - if (GetDlgItemTextW(hDlg, comboID, name, 255)) - PRINTDLG_ChangePrinterW(hDlg, name, PrintStructures); - free(name); - } else { - /* else use default printer */ - WCHAR name[200]; - DWORD dwBufLen = ARRAY_SIZE(name); - BOOL ret = GetDefaultPrinterW(name, &dwBufLen); - - if (ret) - PRINTDLG_ChangePrinterW(hDlg, name, PrintStructures); - else - FIXME("No default printer found, expect problems!\n"); - } - return TRUE; -} - -/*********************************************************************** - * PRINTDLG_WMCommand [internal] - */ -static LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam, - PRINT_PTRA* PrintStructures) -{ - LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; - UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; - LPDEVMODEA lpdm = PrintStructures->lpDevMode; - - switch (LOWORD(wParam)) { - case IDOK: - TRACE(" OK button was hit\n"); - if (!PRINTDLG_UpdatePrintDlgA(hDlg, PrintStructures)) { - FIXME("Update printdlg was not successful!\n"); - return(FALSE); - } - EndDialog(hDlg, TRUE); - return(TRUE); - - case IDCANCEL: - TRACE(" CANCEL button was hit\n"); - EndDialog(hDlg, FALSE); - return(FALSE); - - case pshHelp: - TRACE(" HELP button was hit\n"); - SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID, - (WPARAM) hDlg, (LPARAM) lppd); - break; - - case chx2: /* collate pages checkbox */ - if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) - SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hCollateIcon); - else - SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hNoCollateIcon); - break; - case edt1: /* from page nr editbox */ - case edt2: /* to page nr editbox */ - if (HIWORD(wParam)==EN_CHANGE) { - WORD nToPage; - WORD nFromPage; - nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE); - nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE); - if (nFromPage != lppd->nFromPage || nToPage != lppd->nToPage) - CheckRadioButton(hDlg, rad1, rad3, rad3); - } - break; - - case edt3: - if(HIWORD(wParam) == EN_CHANGE) { - INT copies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); - if(copies <= 1) - EnableWindow(GetDlgItem(hDlg, chx2), FALSE); - else - EnableWindow(GetDlgItem(hDlg, chx2), TRUE); - } - break; - - case psh2: /* Properties button */ - { - HANDLE hPrinter; - char PrinterName[256]; - - GetDlgItemTextA(hDlg, PrinterComboID, PrinterName, 255); - if (!OpenPrinterA(PrinterName, &hPrinter, NULL)) { - FIXME(" Call to OpenPrinter did not succeed!\n"); - break; - } - DocumentPropertiesA(hDlg, hPrinter, PrinterName, - PrintStructures->lpDevMode, - PrintStructures->lpDevMode, - DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT); - ClosePrinter(hPrinter); - break; - } - - case rad1: /* Paperorientation */ - if (lppd->Flags & PD_PRINTSETUP) - { - lpdm->dmOrientation = DMORIENT_PORTRAIT; - SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)(PrintStructures->hPortraitIcon)); - } - break; - - case rad2: /* Paperorientation */ - if (lppd->Flags & PD_PRINTSETUP) - { - lpdm->dmOrientation = DMORIENT_LANDSCAPE; - SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)(PrintStructures->hLandscapeIcon)); - } - break; - - case cmb1: /* Printer Combobox in PRINT SETUP, quality combobox in PRINT16 */ - if (PrinterComboID != LOWORD(wParam)) { - break; - } - /* FALLTHROUGH */ - case cmb4: /* Printer combobox */ - if (HIWORD(wParam)==CBN_SELCHANGE) { - char *PrinterName; - INT index = SendDlgItemMessageW(hDlg, LOWORD(wParam), CB_GETCURSEL, 0, 0); - INT length = SendDlgItemMessageW(hDlg, LOWORD(wParam), CB_GETLBTEXTLEN, index, 0); - PrinterName = malloc(length + 1); - SendDlgItemMessageA(hDlg, LOWORD(wParam), CB_GETLBTEXT, index, (LPARAM)PrinterName); - PRINTDLG_ChangePrinterA(hDlg, PrinterName, PrintStructures); - free(PrinterName); - } - break; - - case cmb2: /* Papersize */ - { - DWORD Sel = SendDlgItemMessageA(hDlg, cmb2, CB_GETCURSEL, 0, 0); - if(Sel != CB_ERR) { - lpdm->dmPaperSize = SendDlgItemMessageA(hDlg, cmb2, CB_GETITEMDATA, Sel, 0); - GetDlgItemTextA(hDlg, cmb2, (char *)lpdm->dmFormName, CCHFORMNAME); - } - } - break; - - case cmb3: /* Bin */ - { - DWORD Sel = SendDlgItemMessageA(hDlg, cmb3, CB_GETCURSEL, 0, 0); - if(Sel != CB_ERR) - lpdm->dmDefaultSource = SendDlgItemMessageA(hDlg, cmb3, CB_GETITEMDATA, Sel, 0); - } - break; - } - if(lppd->Flags & PD_PRINTSETUP) { - switch (LOWORD(wParam)) { - case rad1: /* orientation */ - case rad2: - if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED) { - if(lpdm->dmOrientation != DMORIENT_PORTRAIT) { - lpdm->dmOrientation = DMORIENT_PORTRAIT; - SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hPortraitIcon); - SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hPortraitIcon); - } - } else { - if(lpdm->dmOrientation != DMORIENT_LANDSCAPE) { - lpdm->dmOrientation = DMORIENT_LANDSCAPE; - SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hLandscapeIcon); - SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hLandscapeIcon); - } - } - break; - } - } - return FALSE; -} - -static LRESULT PRINTDLG_WMCommandW(HWND hDlg, WPARAM wParam, - PRINT_PTRW* PrintStructures) -{ - LPPRINTDLGW lppd = PrintStructures->lpPrintDlg; - UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; - LPDEVMODEW lpdm = PrintStructures->lpDevMode; - - switch (LOWORD(wParam)) { - case IDOK: - TRACE(" OK button was hit\n"); - if (!PRINTDLG_UpdatePrintDlgW(hDlg, PrintStructures)) { - FIXME("Update printdlg was not successful!\n"); - return(FALSE); - } - EndDialog(hDlg, TRUE); - return(TRUE); - - case IDCANCEL: - TRACE(" CANCEL button was hit\n"); - EndDialog(hDlg, FALSE); - return(FALSE); - - case pshHelp: - TRACE(" HELP button was hit\n"); - SendMessageW(lppd->hwndOwner, PrintStructures->HelpMessageID, - (WPARAM) hDlg, (LPARAM) lppd); - break; - - case chx2: /* collate pages checkbox */ - if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) - SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hCollateIcon); - else - SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hNoCollateIcon); - break; - case edt1: /* from page nr editbox */ - case edt2: /* to page nr editbox */ - if (HIWORD(wParam)==EN_CHANGE) { - WORD nToPage; - WORD nFromPage; - nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE); - nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE); - if (nFromPage != lppd->nFromPage || nToPage != lppd->nToPage) - CheckRadioButton(hDlg, rad1, rad3, rad3); - } - break; - - case edt3: - if(HIWORD(wParam) == EN_CHANGE) { - INT copies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); - if(copies <= 1) - EnableWindow(GetDlgItem(hDlg, chx2), FALSE); - else - EnableWindow(GetDlgItem(hDlg, chx2), TRUE); - } - break; - - case psh2: /* Properties button */ - { - HANDLE hPrinter; - WCHAR PrinterName[256]; - - if (!GetDlgItemTextW(hDlg, PrinterComboID, PrinterName, 255)) break; - if (!OpenPrinterW(PrinterName, &hPrinter, NULL)) { - FIXME(" Call to OpenPrinter did not succeed!\n"); - break; - } - DocumentPropertiesW(hDlg, hPrinter, PrinterName, - PrintStructures->lpDevMode, - PrintStructures->lpDevMode, - DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT); - ClosePrinter(hPrinter); - break; - } - - case rad1: /* Paperorientation */ - if (lppd->Flags & PD_PRINTSETUP) - { - lpdm->dmOrientation = DMORIENT_PORTRAIT; - SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)(PrintStructures->hPortraitIcon)); - } - break; - - case rad2: /* Paperorientation */ - if (lppd->Flags & PD_PRINTSETUP) - { - lpdm->dmOrientation = DMORIENT_LANDSCAPE; - SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)(PrintStructures->hLandscapeIcon)); - } - break; - - case cmb1: /* Printer Combobox in PRINT SETUP */ - /* FALLTHROUGH */ - case cmb4: /* Printer combobox */ - if (HIWORD(wParam)==CBN_SELCHANGE) { - WCHAR *PrinterName; - INT index = SendDlgItemMessageW(hDlg, LOWORD(wParam), CB_GETCURSEL, 0, 0); - INT length = SendDlgItemMessageW(hDlg, LOWORD(wParam), CB_GETLBTEXTLEN, index, 0); - - PrinterName = malloc(sizeof(WCHAR) * (length + 1)); - SendDlgItemMessageW(hDlg, LOWORD(wParam), CB_GETLBTEXT, index, (LPARAM)PrinterName); - PRINTDLG_ChangePrinterW(hDlg, PrinterName, PrintStructures); - free(PrinterName); - } - break; - - case cmb2: /* Papersize */ - { - DWORD Sel = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0); - if(Sel != CB_ERR) { - lpdm->dmPaperSize = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, Sel, 0); - GetDlgItemTextW(hDlg, cmb2, lpdm->dmFormName, CCHFORMNAME); - } - } - break; - - case cmb3: /* Bin */ - { - DWORD Sel = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0); - if(Sel != CB_ERR) - lpdm->dmDefaultSource = SendDlgItemMessageW(hDlg, cmb3, CB_GETITEMDATA, Sel, 0); - } - break; - } - if(lppd->Flags & PD_PRINTSETUP) { - switch (LOWORD(wParam)) { - case rad1: /* orientation */ - case rad2: - if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED) { - if(lpdm->dmOrientation != DMORIENT_PORTRAIT) { - lpdm->dmOrientation = DMORIENT_PORTRAIT; - SendDlgItemMessageW(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hPortraitIcon); - SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hPortraitIcon); - } - } else { - if(lpdm->dmOrientation != DMORIENT_LANDSCAPE) { - lpdm->dmOrientation = DMORIENT_LANDSCAPE; - SendDlgItemMessageW(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hLandscapeIcon); - SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, - (LPARAM)PrintStructures->hLandscapeIcon); - } - } - break; - } - } - return FALSE; -} - -/*********************************************************************** - * PrintDlgProcA [internal] - */ -static INT_PTR CALLBACK PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, - LPARAM lParam) -{ - PRINT_PTRA* PrintStructures; - INT_PTR res = FALSE; - - if (uMsg!=WM_INITDIALOG) { - PrintStructures = GetPropW(hDlg, printdlg_prop); - if (!PrintStructures) - return FALSE; - } else { - PrintStructures = (PRINT_PTRA*) lParam; - SetPropW(hDlg, printdlg_prop, PrintStructures); - if(!check_printer_setup(hDlg)) - { - EndDialog(hDlg,FALSE); - return FALSE; - } - res = PRINTDLG_WMInitDialog(hDlg, PrintStructures); - - if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) - res = PrintStructures->lpPrintDlg->lpfnPrintHook( - hDlg, uMsg, wParam, (LPARAM)PrintStructures->lpPrintDlg - ); - return res; - } - - if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) { - res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg,uMsg,wParam, - lParam); - if(res) return res; - } - - switch (uMsg) { - case WM_COMMAND: - return PRINTDLG_WMCommandA(hDlg, wParam, PrintStructures); - - case WM_DESTROY: - DestroyIcon(PrintStructures->hCollateIcon); - DestroyIcon(PrintStructures->hNoCollateIcon); - DestroyIcon(PrintStructures->hPortraitIcon); - DestroyIcon(PrintStructures->hLandscapeIcon); - if(PrintStructures->hwndUpDown) - DestroyWindow(PrintStructures->hwndUpDown); - return FALSE; - } - return res; -} - -static INT_PTR CALLBACK PrintDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, - LPARAM lParam) -{ - PRINT_PTRW* PrintStructures; - INT_PTR res = FALSE; - - if (uMsg!=WM_INITDIALOG) { - PrintStructures = GetPropW(hDlg, printdlg_prop); - if (!PrintStructures) - return FALSE; - } else { - PrintStructures = (PRINT_PTRW*) lParam; - SetPropW(hDlg, printdlg_prop, PrintStructures); - if(!check_printer_setup(hDlg)) - { - EndDialog(hDlg,FALSE); - return FALSE; - } - res = PRINTDLG_WMInitDialogW(hDlg, PrintStructures); - - if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) - res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg, uMsg, wParam, (LPARAM)PrintStructures->lpPrintDlg); - return res; - } - - if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) { - res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg,uMsg,wParam, lParam); - if(res) return res; - } - - switch (uMsg) { - case WM_COMMAND: - return PRINTDLG_WMCommandW(hDlg, wParam, PrintStructures); - - case WM_DESTROY: - DestroyIcon(PrintStructures->hCollateIcon); - DestroyIcon(PrintStructures->hNoCollateIcon); - DestroyIcon(PrintStructures->hPortraitIcon); - DestroyIcon(PrintStructures->hLandscapeIcon); - if(PrintStructures->hwndUpDown) - DestroyWindow(PrintStructures->hwndUpDown); - return FALSE; - } - return res; -} - -/************************************************************ - * - * PRINTDLG_GetDlgTemplate - * - */ -static HGLOBAL PRINTDLG_GetDlgTemplateA(const PRINTDLGA *lppd) -{ - HRSRC hResInfo; - HGLOBAL hDlgTmpl; - - if (lppd->Flags & PD_PRINTSETUP) { - if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE) { - hDlgTmpl = lppd->hSetupTemplate; - } else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) { - hResInfo = FindResourceA(lppd->hInstance, - lppd->lpSetupTemplateName, (LPSTR)RT_DIALOG); - hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); - } else { - hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32_SETUP", - (LPSTR)RT_DIALOG); - hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); - } - } else { - if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE) { - hDlgTmpl = lppd->hPrintTemplate; - } else if(lppd->Flags & PD_ENABLEPRINTTEMPLATE) { - hResInfo = FindResourceA(lppd->hInstance, - lppd->lpPrintTemplateName, - (LPSTR)RT_DIALOG); - hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); - } else { - hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32", - (LPSTR)RT_DIALOG); - hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); - } - } - return hDlgTmpl; -} - -static HGLOBAL PRINTDLG_GetDlgTemplateW(const PRINTDLGW *lppd) -{ - HRSRC hResInfo; - HGLOBAL hDlgTmpl; - - if (lppd->Flags & PD_PRINTSETUP) { - if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE) { - hDlgTmpl = lppd->hSetupTemplate; - } else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) { - hResInfo = FindResourceW(lppd->hInstance, - lppd->lpSetupTemplateName, (LPWSTR)RT_DIALOG); - hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); - } else { - hResInfo = FindResourceW(COMDLG32_hInstance, L"PRINT32_SETUP", (LPWSTR)RT_DIALOG); - hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); - } - } else { - if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE) { - hDlgTmpl = lppd->hPrintTemplate; - } else if(lppd->Flags & PD_ENABLEPRINTTEMPLATE) { - hResInfo = FindResourceW(lppd->hInstance, - lppd->lpPrintTemplateName, - (LPWSTR)RT_DIALOG); - hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); - } else { - hResInfo = FindResourceW(COMDLG32_hInstance, L"PRINT32", (LPWSTR)RT_DIALOG); - hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); - } - } - return hDlgTmpl; -} - -/*********************************************************************** - * - * PRINTDLG_CreateDC - * - */ -static BOOL PRINTDLG_CreateDCA(LPPRINTDLGA lppd) -{ - DEVNAMES *pdn = GlobalLock(lppd->hDevNames); - DEVMODEA *pdm = GlobalLock(lppd->hDevMode); - - if(lppd->Flags & PD_RETURNDC) { - lppd->hDC = CreateDCA((char*)pdn + pdn->wDriverOffset, - (char*)pdn + pdn->wDeviceOffset, - (char*)pdn + pdn->wOutputOffset, - pdm ); - } else if(lppd->Flags & PD_RETURNIC) { - lppd->hDC = CreateICA((char*)pdn + pdn->wDriverOffset, - (char*)pdn + pdn->wDeviceOffset, - (char*)pdn + pdn->wOutputOffset, - pdm ); - } - GlobalUnlock(lppd->hDevNames); - GlobalUnlock(lppd->hDevMode); - return lppd->hDC != NULL; -} - -static BOOL PRINTDLG_CreateDCW(LPPRINTDLGW lppd) -{ - DEVNAMES *pdn = GlobalLock(lppd->hDevNames); - DEVMODEW *pdm = GlobalLock(lppd->hDevMode); - - if(lppd->Flags & PD_RETURNDC) { - lppd->hDC = CreateDCW((WCHAR*)pdn + pdn->wDriverOffset, - (WCHAR*)pdn + pdn->wDeviceOffset, - (WCHAR*)pdn + pdn->wOutputOffset, - pdm ); - } else if(lppd->Flags & PD_RETURNIC) { - lppd->hDC = CreateICW((WCHAR*)pdn + pdn->wDriverOffset, - (WCHAR*)pdn + pdn->wDeviceOffset, - (WCHAR*)pdn + pdn->wOutputOffset, - pdm ); - } - GlobalUnlock(lppd->hDevNames); - GlobalUnlock(lppd->hDevMode); - return lppd->hDC != NULL; -} - -/*********************************************************************** - * PrintDlgA (COMDLG32.@) - * - * Displays the PRINT dialog box, which enables the user to specify - * specific properties of the print job. - * - * PARAMS - * lppd [IO] ptr to PRINTDLG32 struct - * - * RETURNS - * nonzero if the user pressed the OK button - * zero if the user cancelled the window or an error occurred - * - * BUGS - * PrintDlg: - * * The Collate Icons do not display, even though they are in the code. - * * The Properties Button(s) should call DocumentPropertiesA(). - */ - -BOOL WINAPI PrintDlgA(LPPRINTDLGA lppd) -{ - BOOL bRet = FALSE; - LPVOID ptr; - HINSTANCE hInst; - - if (!lppd) - { - COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION); - return FALSE; - } - - if(TRACE_ON(commdlg)) { - char flagstr[1000] = ""; - const struct pd_flags *pflag = pd_flags; - for( ; pflag->name; pflag++) { - if(lppd->Flags & pflag->flag) - strcat(flagstr, pflag->name); - } - TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n" - "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n" - "flags %08lx (%s)\n", - lppd, lppd->hwndOwner, lppd->hDevMode, lppd->hDevNames, - lppd->nFromPage, lppd->nToPage, lppd->nMinPage, lppd->nMaxPage, - lppd->nCopies, lppd->hInstance, lppd->Flags, flagstr); - } - - if(lppd->lStructSize != sizeof(PRINTDLGA)) { - WARN("structure size failure!!!\n"); - COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); - return FALSE; - } - - if(lppd->Flags & PD_RETURNDEFAULT) { - PRINTER_INFO_2A *pbuf; - DRIVER_INFO_3A *dbuf; - HANDLE hprn; - DWORD needed; - - if(lppd->hDevMode || lppd->hDevNames) { - WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n"); - COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); - return FALSE; - } - if(!PRINTDLG_OpenDefaultPrinter(&hprn)) { - WARN("Can't find default printer\n"); - COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); - return FALSE; - } - - GetPrinterA(hprn, 2, NULL, 0, &needed); - pbuf = malloc(needed); - GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed); - - GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed); - dbuf = malloc(needed); - if (!GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed)) { - ERR("GetPrinterDriverA failed, le %ld, fix your config for printer %s!\n", - GetLastError(),pbuf->pPrinterName); - free(dbuf); - free(pbuf); - COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); - return FALSE; - } - ClosePrinter(hprn); - - PRINTDLG_CreateDevNames(&(lppd->hDevNames), - dbuf->pDriverPath, - pbuf->pPrinterName, - pbuf->pPortName); - lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize + - pbuf->pDevMode->dmDriverExtra); - ptr = GlobalLock(lppd->hDevMode); - memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize + - pbuf->pDevMode->dmDriverExtra); - GlobalUnlock(lppd->hDevMode); - free(pbuf); - free(dbuf); - bRet = TRUE; - } else { - HGLOBAL hDlgTmpl; - PRINT_PTRA *PrintStructures; - - /* load Dialog resources, - * depending on Flags indicates Print32 or Print32_setup dialog - */ - hDlgTmpl = PRINTDLG_GetDlgTemplateA(lppd); - if (!hDlgTmpl) { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return FALSE; - } - ptr = LockResource( hDlgTmpl ); - if (!ptr) { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return FALSE; - } - - PrintStructures = calloc(1, sizeof(PRINT_PTRA)); - PrintStructures->lpPrintDlg = lppd; - - /* and create & process the dialog . - * -1 is failure, 0 is broken hwnd, everything else is ok. - */ - hInst = COMDLG32_hInstance; - if (lppd->Flags & (PD_ENABLESETUPTEMPLATE | PD_ENABLEPRINTTEMPLATE)) hInst = lppd->hInstance; - bRet = (0hwndOwner, - PrintDlgProcA, - (LPARAM)PrintStructures)); - - if(bRet) { - DEVMODEA *lpdm = PrintStructures->lpDevMode, *lpdmReturn; - PRINTER_INFO_2A *pi = PrintStructures->lpPrinterInfo; - DRIVER_INFO_3A *di = PrintStructures->lpDriverInfo; - - if (lppd->hDevMode == 0) { - TRACE(" No hDevMode yet... Need to create my own\n"); - lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, - lpdm->dmSize + lpdm->dmDriverExtra); - } else { - lppd->hDevMode = GlobalReAlloc(lppd->hDevMode, - lpdm->dmSize + lpdm->dmDriverExtra, - GMEM_MOVEABLE); - } - lpdmReturn = GlobalLock(lppd->hDevMode); - memcpy(lpdmReturn, lpdm, lpdm->dmSize + lpdm->dmDriverExtra); - - PRINTDLG_CreateDevNames(&(lppd->hDevNames), - di->pDriverPath, - pi->pPrinterName, - pi->pPortName - ); - GlobalUnlock(lppd->hDevMode); - } - free(PrintStructures->lpDevMode); - free(PrintStructures->lpPrinterInfo); - free(PrintStructures->lpDriverInfo); - free(PrintStructures); - } - if(bRet && (lppd->Flags & PD_RETURNDC || lppd->Flags & PD_RETURNIC)) - bRet = PRINTDLG_CreateDCA(lppd); - - TRACE("exit! (%d)\n", bRet); - return bRet; -} - -/*********************************************************************** - * PrintDlgW (COMDLG32.@) - * - * See PrintDlgA. - */ -BOOL WINAPI PrintDlgW(LPPRINTDLGW lppd) -{ - BOOL bRet = FALSE; - LPVOID ptr; - HINSTANCE hInst; - - if (!lppd) - { - COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION); - return FALSE; - } - - if(TRACE_ON(commdlg)) { - char flagstr[1000] = ""; - const struct pd_flags *pflag = pd_flags; - for( ; pflag->name; pflag++) { - if(lppd->Flags & pflag->flag) - strcat(flagstr, pflag->name); - } - TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n" - "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n" - "flags %08lx (%s)\n", - lppd, lppd->hwndOwner, lppd->hDevMode, lppd->hDevNames, - lppd->nFromPage, lppd->nToPage, lppd->nMinPage, lppd->nMaxPage, - lppd->nCopies, lppd->hInstance, lppd->Flags, flagstr); - } - - if(lppd->lStructSize != sizeof(PRINTDLGW)) { - WARN("structure size failure!!!\n"); - COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); - return FALSE; - } - - if(lppd->Flags & PD_RETURNDEFAULT) { - PRINTER_INFO_2W *pbuf; - DRIVER_INFO_3W *dbuf; - HANDLE hprn; - DWORD needed; - - if(lppd->hDevMode || lppd->hDevNames) { - WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n"); - COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); - return FALSE; - } - if(!PRINTDLG_OpenDefaultPrinter(&hprn)) { - WARN("Can't find default printer\n"); - COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); - return FALSE; - } - - GetPrinterW(hprn, 2, NULL, 0, &needed); - pbuf = malloc(needed); - GetPrinterW(hprn, 2, (LPBYTE)pbuf, needed, &needed); - - GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed); - dbuf = malloc(needed); - if (!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed)) { - ERR("GetPrinterDriverA failed, le %ld, fix your config for printer %s!\n", - GetLastError(),debugstr_w(pbuf->pPrinterName)); - free(dbuf); - free(pbuf); - COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); - return FALSE; - } - ClosePrinter(hprn); - - PRINTDLG_CreateDevNamesW(&(lppd->hDevNames), - dbuf->pDriverPath, - pbuf->pPrinterName, - pbuf->pPortName); - lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize + - pbuf->pDevMode->dmDriverExtra); - ptr = GlobalLock(lppd->hDevMode); - memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize + - pbuf->pDevMode->dmDriverExtra); - GlobalUnlock(lppd->hDevMode); - free(pbuf); - free(dbuf); - bRet = TRUE; - } else { - HGLOBAL hDlgTmpl; - PRINT_PTRW *PrintStructures; - - /* load Dialog resources, - * depending on Flags indicates Print32 or Print32_setup dialog - */ - hDlgTmpl = PRINTDLG_GetDlgTemplateW(lppd); - if (!hDlgTmpl) { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return FALSE; - } - ptr = LockResource( hDlgTmpl ); - if (!ptr) { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return FALSE; - } - - PrintStructures = calloc(1, sizeof(PRINT_PTRW)); - PrintStructures->lpPrintDlg = lppd; - - /* and create & process the dialog . - * -1 is failure, 0 is broken hwnd, everything else is ok. - */ - hInst = COMDLG32_hInstance; - if (lppd->Flags & (PD_ENABLESETUPTEMPLATE | PD_ENABLEPRINTTEMPLATE)) hInst = lppd->hInstance; - bRet = (0hwndOwner, - PrintDlgProcW, - (LPARAM)PrintStructures)); - - if(bRet) { - DEVMODEW *lpdm = PrintStructures->lpDevMode, *lpdmReturn; - PRINTER_INFO_2W *pi = PrintStructures->lpPrinterInfo; - DRIVER_INFO_3W *di = PrintStructures->lpDriverInfo; - - if (lppd->hDevMode == 0) { - TRACE(" No hDevMode yet... Need to create my own\n"); - lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, - lpdm->dmSize + lpdm->dmDriverExtra); - } else { - WORD locks; - if((locks = (GlobalFlags(lppd->hDevMode) & GMEM_LOCKCOUNT))) { - WARN("hDevMode has %d locks on it. Unlocking it now\n", locks); - while(locks--) { - GlobalUnlock(lppd->hDevMode); - TRACE("Now got %d locks\n", locks); - } - } - lppd->hDevMode = GlobalReAlloc(lppd->hDevMode, - lpdm->dmSize + lpdm->dmDriverExtra, - GMEM_MOVEABLE); - } - lpdmReturn = GlobalLock(lppd->hDevMode); - memcpy(lpdmReturn, lpdm, lpdm->dmSize + lpdm->dmDriverExtra); - - if (lppd->hDevNames != 0) { - WORD locks; - if((locks = (GlobalFlags(lppd->hDevNames) & GMEM_LOCKCOUNT))) { - WARN("hDevNames has %d locks on it. Unlocking it now\n", locks); - while(locks--) - GlobalUnlock(lppd->hDevNames); - } - } - PRINTDLG_CreateDevNamesW(&(lppd->hDevNames), - di->pDriverPath, - pi->pPrinterName, - pi->pPortName - ); - GlobalUnlock(lppd->hDevMode); - } - free(PrintStructures->lpDevMode); - free(PrintStructures->lpPrinterInfo); - free(PrintStructures->lpDriverInfo); - free(PrintStructures); - } - if(bRet && (lppd->Flags & PD_RETURNDC || lppd->Flags & PD_RETURNIC)) - bRet = PRINTDLG_CreateDCW(lppd); - - TRACE("exit! (%d)\n", bRet); - return bRet; -} - -/*********************************************************************** - * - * PageSetupDlg - * rad1 - portrait - * rad2 - landscape - * cmb1 - printer select (not in standard dialog template) - * cmb2 - paper size - * cmb3 - source (tray?) - * edt4 - border left - * edt5 - border top - * edt6 - border right - * edt7 - border bottom - * psh3 - "Printer..." - */ - -typedef struct -{ - BOOL unicode; - union - { - LPPAGESETUPDLGA dlga; - LPPAGESETUPDLGW dlgw; - } u; - HWND hDlg; /* Page Setup dialog handle */ - RECT rtDrawRect; /* Drawing rect for page */ -} pagesetup_data; - -static inline DWORD pagesetup_get_flags(const pagesetup_data *data) -{ - return data->u.dlgw->Flags; -} - -static inline BOOL is_metric(const pagesetup_data *data) -{ - return pagesetup_get_flags(data) & PSD_INHUNDREDTHSOFMILLIMETERS; -} - -static inline LONG tenths_mm_to_size(const pagesetup_data *data, LONG size) -{ - if (is_metric(data)) - return 10 * size; - else - return 10 * size * 100 / 254; -} - -static inline LONG thousandths_inch_to_size(const pagesetup_data *data, LONG size) -{ - if (is_metric(data)) - return size * 254 / 100; - else - return size; -} - -static WCHAR get_decimal_sep(void) -{ - static WCHAR sep; - - if(!sep) - { - WCHAR buf[] = L"."; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buf, ARRAY_SIZE(buf)); - sep = buf[0]; - } - return sep; -} - -static void size2str(const pagesetup_data *data, DWORD size, LPWSTR strout) -{ - /* FIXME use LOCALE_SDECIMAL when the edit parsing code can cope */ - - if (is_metric(data)) - { - if(size % 100) - wsprintfW(strout, L"%d%c%02d", size / 100, get_decimal_sep(), size % 100); - else - wsprintfW(strout, L"%d", size / 100); - } - else - { - if(size % 1000) - wsprintfW(strout, L"%d%c%03d", size / 1000, get_decimal_sep(), size % 1000); - else - wsprintfW(strout, L"%d", size / 1000); - - } -} - -static inline BOOL is_default_metric(void) -{ - DWORD system; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IMEASURE | LOCALE_RETURN_NUMBER, - (LPWSTR)&system, sizeof(system)); - return system == 0; -} - -/********************************************** - * rotate_rect - * Cyclically permute the four members of rc - * If sense is TRUE l -> t -> r -> b - * otherwise l <- t <- r <- b - */ -static inline void rotate_rect(RECT *rc, BOOL sense) -{ - INT tmp; - if(sense) - { - tmp = rc->bottom; - rc->bottom = rc->right; - rc->right = rc->top; - rc->top = rc->left; - rc->left = tmp; - } - else - { - tmp = rc->left; - rc->left = rc->top; - rc->top = rc->right; - rc->right = rc->bottom; - rc->bottom = tmp; - } -} - -static void pagesetup_set_orientation(pagesetup_data *data, WORD orient) -{ - DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode); - - assert(orient == DMORIENT_PORTRAIT || orient == DMORIENT_LANDSCAPE); - - if(data->unicode) - dm->dmOrientation = orient; - else - { - DEVMODEA *dmA = (DEVMODEA *)dm; - dmA->dmOrientation = orient; - } - GlobalUnlock(data->u.dlgw->hDevMode); -} - -static WORD pagesetup_get_orientation(const pagesetup_data *data) -{ - DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode); - WORD orient; - - if(data->unicode) - orient = dm->dmOrientation; - else - { - DEVMODEA *dmA = (DEVMODEA *)dm; - orient = dmA->dmOrientation; - } - GlobalUnlock(data->u.dlgw->hDevMode); - return orient; -} - -static void pagesetup_set_papersize(pagesetup_data *data, WORD paper) -{ - DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode); - - if(data->unicode) - dm->dmPaperSize = paper; - else - { - DEVMODEA *dmA = (DEVMODEA *)dm; - dmA->dmPaperSize = paper; - } - GlobalUnlock(data->u.dlgw->hDevMode); -} - -static WORD pagesetup_get_papersize(const pagesetup_data *data) -{ - DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode); - WORD paper; - - if(data->unicode) - paper = dm->dmPaperSize; - else - { - DEVMODEA *dmA = (DEVMODEA *)dm; - paper = dmA->dmPaperSize; - } - GlobalUnlock(data->u.dlgw->hDevMode); - return paper; -} - -static void pagesetup_set_defaultsource(pagesetup_data *data, WORD source) -{ - DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode); - - if(data->unicode) - dm->dmDefaultSource = source; - else - { - DEVMODEA *dmA = (DEVMODEA *)dm; - dmA->dmDefaultSource = source; - } - GlobalUnlock(data->u.dlgw->hDevMode); -} - -typedef enum -{ - devnames_driver_name, - devnames_device_name, - devnames_output_name -} devnames_name; - - -static inline WORD get_devname_offset(const DEVNAMES *dn, devnames_name which) -{ - switch(which) - { - case devnames_driver_name: return dn->wDriverOffset; - case devnames_device_name: return dn->wDeviceOffset; - case devnames_output_name: return dn->wOutputOffset; - } - ERR("Shouldn't be here\n"); - return 0; -} - -static WCHAR *pagesetup_get_a_devname(const pagesetup_data *data, devnames_name which) -{ - DEVNAMES *dn; - WCHAR *name; - - dn = GlobalLock(data->u.dlgw->hDevNames); - if(data->unicode) - name = strdupW((WCHAR *)dn + get_devname_offset(dn, which)); - else - { - int len = MultiByteToWideChar(CP_ACP, 0, (char*)dn + get_devname_offset(dn, which), -1, NULL, 0); - name = malloc(len * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, (char*)dn + get_devname_offset(dn, which), -1, name, len); - } - GlobalUnlock(data->u.dlgw->hDevNames); - return name; -} - -static WCHAR *pagesetup_get_drvname(const pagesetup_data *data) -{ - return pagesetup_get_a_devname(data, devnames_driver_name); -} - -static WCHAR *pagesetup_get_devname(const pagesetup_data *data) -{ - return pagesetup_get_a_devname(data, devnames_device_name); -} - -static WCHAR *pagesetup_get_portname(const pagesetup_data *data) -{ - return pagesetup_get_a_devname(data, devnames_output_name); -} - -static void pagesetup_release_a_devname(const pagesetup_data *data, WCHAR *name) -{ - free(name); -} - -static void pagesetup_set_devnames(pagesetup_data *data, LPCWSTR drv, LPCWSTR devname, LPCWSTR port) -{ - DEVNAMES *dn; - WCHAR def[256]; - DWORD len = sizeof(DEVNAMES), drv_len, dev_len, port_len; - - if(data->unicode) - { - drv_len = (lstrlenW(drv) + 1) * sizeof(WCHAR); - dev_len = (lstrlenW(devname) + 1) * sizeof(WCHAR); - port_len = (lstrlenW(port) + 1) * sizeof(WCHAR); - } - else - { - drv_len = WideCharToMultiByte(CP_ACP, 0, drv, -1, NULL, 0, NULL, NULL); - dev_len = WideCharToMultiByte(CP_ACP, 0, devname, -1, NULL, 0, NULL, NULL); - port_len = WideCharToMultiByte(CP_ACP, 0, port, -1, NULL, 0, NULL, NULL); - } - len += drv_len + dev_len + port_len; - - if(data->u.dlgw->hDevNames) - data->u.dlgw->hDevNames = GlobalReAlloc(data->u.dlgw->hDevNames, len, GMEM_MOVEABLE); - else - data->u.dlgw->hDevNames = GlobalAlloc(GMEM_MOVEABLE, len); - - dn = GlobalLock(data->u.dlgw->hDevNames); - - if(data->unicode) - { - WCHAR *ptr = (WCHAR *)(dn + 1); - len = sizeof(DEVNAMES) / sizeof(WCHAR); - dn->wDriverOffset = len; - lstrcpyW(ptr, drv); - ptr += drv_len / sizeof(WCHAR); - len += drv_len / sizeof(WCHAR); - dn->wDeviceOffset = len; - lstrcpyW(ptr, devname); - ptr += dev_len / sizeof(WCHAR); - len += dev_len / sizeof(WCHAR); - dn->wOutputOffset = len; - lstrcpyW(ptr, port); - } - else - { - char *ptr = (char *)(dn + 1); - len = sizeof(DEVNAMES); - dn->wDriverOffset = len; - WideCharToMultiByte(CP_ACP, 0, drv, -1, ptr, drv_len, NULL, NULL); - ptr += drv_len; - len += drv_len; - dn->wDeviceOffset = len; - WideCharToMultiByte(CP_ACP, 0, devname, -1, ptr, dev_len, NULL, NULL); - ptr += dev_len; - len += dev_len; - dn->wOutputOffset = len; - WideCharToMultiByte(CP_ACP, 0, port, -1, ptr, port_len, NULL, NULL); - } - - dn->wDefault = 0; - len = ARRAY_SIZE(def); - GetDefaultPrinterW(def, &len); - if(!lstrcmpW(def, devname)) - dn->wDefault = 1; - - GlobalUnlock(data->u.dlgw->hDevNames); -} - -static DEVMODEW *pagesetup_get_devmode(const pagesetup_data *data) -{ - DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode); - DEVMODEW *ret; - - if(data->unicode) - { - /* We make a copy even in the unicode case because the ptr - may get passed back to us in pagesetup_set_devmode. */ - ret = malloc(dm->dmSize + dm->dmDriverExtra); - memcpy(ret, dm, dm->dmSize + dm->dmDriverExtra); - } - else - ret = GdiConvertToDevmodeW((DEVMODEA *)dm); - - GlobalUnlock(data->u.dlgw->hDevMode); - return ret; -} - -static void pagesetup_release_devmode(const pagesetup_data *data, DEVMODEW *dm) -{ - free(dm); -} - -static void pagesetup_set_devmode(pagesetup_data *data, DEVMODEW *dm) -{ - DEVMODEA *dmA = NULL; - void *src, *dst; - DWORD size; - - if(data->unicode) - { - size = dm->dmSize + dm->dmDriverExtra; - src = dm; - } - else - { - dmA = convert_to_devmodeA(dm); - size = dmA->dmSize + dmA->dmDriverExtra; - src = dmA; - } - - if(data->u.dlgw->hDevMode) - data->u.dlgw->hDevMode = GlobalReAlloc(data->u.dlgw->hDevMode, size, - GMEM_MOVEABLE); - else - data->u.dlgw->hDevMode = GlobalAlloc(GMEM_MOVEABLE, size); - - dst = GlobalLock(data->u.dlgw->hDevMode); - memcpy(dst, src, size); - GlobalUnlock(data->u.dlgw->hDevMode); - free(dmA); -} - -static inline POINT *pagesetup_get_papersize_pt(const pagesetup_data *data) -{ - return &data->u.dlgw->ptPaperSize; -} - -static inline RECT *pagesetup_get_margin_rect(const pagesetup_data *data) -{ - return &data->u.dlgw->rtMargin; -} - -typedef enum -{ - page_setup_hook, - page_paint_hook -} hook_type; - -static inline LPPAGESETUPHOOK pagesetup_get_hook(const pagesetup_data *data, hook_type which) -{ - switch(which) - { - case page_setup_hook: return data->u.dlgw->lpfnPageSetupHook; - case page_paint_hook: return data->u.dlgw->lpfnPagePaintHook; - } - return NULL; -} - -/* This should only be used in calls to hook procs so we return the ptr - already cast to LPARAM */ -static inline LPARAM pagesetup_get_dlg_struct(const pagesetup_data *data) -{ - return (LPARAM)data->u.dlgw; -} - -static inline void swap_point(POINT *pt) -{ - LONG tmp = pt->x; - pt->x = pt->y; - pt->y = tmp; -} - -static BOOL pagesetup_update_papersize(pagesetup_data *data) -{ - DEVMODEW *dm; - LPWSTR devname, portname; - int i, num; - WORD *words = NULL, paperword; - POINT *points = NULL; - BOOL retval = FALSE; - - dm = pagesetup_get_devmode(data); - devname = pagesetup_get_devname(data); - portname = pagesetup_get_portname(data); - - num = DeviceCapabilitiesW(devname, portname, DC_PAPERS, NULL, dm); - if (num <= 0) - { - FIXME("No papernames found for %s/%s\n", debugstr_w(devname), debugstr_w(portname)); - goto end; - } - - words = malloc(num * sizeof(WORD)); - points = malloc(num * sizeof(POINT)); - - if (num != DeviceCapabilitiesW(devname, portname, DC_PAPERS, (LPWSTR)words, dm)) - { - FIXME("Number of returned words is not %d\n", num); - goto end; - } - - if (num != DeviceCapabilitiesW(devname, portname, DC_PAPERSIZE, (LPWSTR)points, dm)) - { - FIXME("Number of returned sizes is not %d\n", num); - goto end; - } - - paperword = pagesetup_get_papersize(data); - - for (i = 0; i < num; i++) - if (words[i] == paperword) - break; - - if (i == num) - { - FIXME("Papersize %d not found in list?\n", paperword); - goto end; - } - - /* this is _10ths_ of a millimeter */ - pagesetup_get_papersize_pt(data)->x = tenths_mm_to_size(data, points[i].x); - pagesetup_get_papersize_pt(data)->y = tenths_mm_to_size(data, points[i].y); - - if(pagesetup_get_orientation(data) == DMORIENT_LANDSCAPE) - swap_point(pagesetup_get_papersize_pt(data)); - - retval = TRUE; - -end: - free(words); - free(points); - pagesetup_release_a_devname(data, portname); - pagesetup_release_a_devname(data, devname); - pagesetup_release_devmode(data, dm); - - return retval; -} - -/********************************************************************************************** - * pagesetup_change_printer - * - * Redefines hDevMode and hDevNames HANDLES and initialises it. - * - */ -static BOOL pagesetup_change_printer(LPWSTR name, pagesetup_data *data) -{ - HANDLE hprn; - DWORD needed; - PRINTER_INFO_2W *prn_info = NULL; - DRIVER_INFO_3W *drv_info = NULL; - DEVMODEW *dm = NULL; - BOOL retval = FALSE; - - if(!OpenPrinterW(name, &hprn, NULL)) - { - ERR("Can't open printer %s\n", debugstr_w(name)); - goto end; - } - - GetPrinterW(hprn, 2, NULL, 0, &needed); - prn_info = malloc(needed); - GetPrinterW(hprn, 2, (LPBYTE)prn_info, needed, &needed); - GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed); - drv_info = malloc(needed); - if(!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)drv_info, needed, &needed)) - { - ERR("GetPrinterDriverA failed for %s, fix your config!\n", debugstr_w(prn_info->pPrinterName)); - goto end; - } - ClosePrinter(hprn); - - needed = DocumentPropertiesW(0, 0, name, NULL, NULL, 0); - if(needed == -1) - { - ERR("DocumentProperties fails on %s\n", debugstr_w(name)); - goto end; - } - - dm = malloc(needed); - DocumentPropertiesW(0, 0, name, dm, NULL, DM_OUT_BUFFER); - - pagesetup_set_devmode(data, dm); - pagesetup_set_devnames(data, drv_info->pDriverPath, prn_info->pPrinterName, - prn_info->pPortName); - - retval = TRUE; -end: - free(dm); - free(prn_info); - free(drv_info); - return retval; -} - -/**************************************************************************************** - * pagesetup_init_combos - * - * Fills Printers, Paper and Source combos - * - */ -static void pagesetup_init_combos(HWND hDlg, pagesetup_data *data) -{ - DEVMODEW *dm; - LPWSTR devname, portname; - - dm = pagesetup_get_devmode(data); - devname = pagesetup_get_devname(data); - portname = pagesetup_get_portname(data); - - PRINTDLG_SetUpPrinterListComboW(hDlg, cmb1, devname); - PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb2, devname, portname, dm); - PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb3, devname, portname, dm); - - pagesetup_release_a_devname(data, portname); - pagesetup_release_a_devname(data, devname); - pagesetup_release_devmode(data, dm); -} - - -/**************************************************************************************** - * pagesetup_change_printer_dialog - * - * Pops up another dialog that lets the user pick another printer. - * - * For now we display the PrintDlg, this should display a striped down version of it. - */ -static void pagesetup_change_printer_dialog(HWND hDlg, pagesetup_data *data) -{ - PRINTDLGW prnt; - LPWSTR drvname, devname, portname; - DEVMODEW *tmp_dm, *dm; - - memset(&prnt, 0, sizeof(prnt)); - prnt.lStructSize = sizeof(prnt); - prnt.Flags = 0; - prnt.hwndOwner = hDlg; - - drvname = pagesetup_get_drvname(data); - devname = pagesetup_get_devname(data); - portname = pagesetup_get_portname(data); - prnt.hDevNames = 0; - PRINTDLG_CreateDevNamesW(&prnt.hDevNames, drvname, devname, portname); - pagesetup_release_a_devname(data, portname); - pagesetup_release_a_devname(data, devname); - pagesetup_release_a_devname(data, drvname); - - tmp_dm = pagesetup_get_devmode(data); - prnt.hDevMode = GlobalAlloc(GMEM_MOVEABLE, tmp_dm->dmSize + tmp_dm->dmDriverExtra); - dm = GlobalLock(prnt.hDevMode); - memcpy(dm, tmp_dm, tmp_dm->dmSize + tmp_dm->dmDriverExtra); - GlobalUnlock(prnt.hDevMode); - pagesetup_release_devmode(data, tmp_dm); - - if (PrintDlgW(&prnt)) - { - DEVMODEW *dm = GlobalLock(prnt.hDevMode); - DEVNAMES *dn = GlobalLock(prnt.hDevNames); - - pagesetup_set_devnames(data, (WCHAR*)dn + dn->wDriverOffset, - (WCHAR*)dn + dn->wDeviceOffset, (WCHAR *)dn + dn->wOutputOffset); - pagesetup_set_devmode(data, dm); - GlobalUnlock(prnt.hDevNames); - GlobalUnlock(prnt.hDevMode); - pagesetup_init_combos(hDlg, data); - } - - GlobalFree(prnt.hDevMode); - GlobalFree(prnt.hDevNames); - -} - -/****************************************************************************************** - * pagesetup_change_preview - * - * Changes paper preview size / position - * - */ -static void pagesetup_change_preview(const pagesetup_data *data) -{ - LONG width, height, x, y; - RECT tmp; - const int shadow = 4; - - if(pagesetup_get_orientation(data) == DMORIENT_LANDSCAPE) - { - width = data->rtDrawRect.right - data->rtDrawRect.left; - height = pagesetup_get_papersize_pt(data)->y * width / pagesetup_get_papersize_pt(data)->x; - } - else - { - height = data->rtDrawRect.bottom - data->rtDrawRect.top; - width = pagesetup_get_papersize_pt(data)->x * height / pagesetup_get_papersize_pt(data)->y; - } - x = (data->rtDrawRect.right + data->rtDrawRect.left - width) / 2; - y = (data->rtDrawRect.bottom + data->rtDrawRect.top - height) / 2; - TRACE("draw rect %s x=%ld, y=%ld, w=%ld, h=%ld\n", - wine_dbgstr_rect(&data->rtDrawRect), x, y, width, height); - - MoveWindow(GetDlgItem(data->hDlg, rct2), x + width, y + shadow, shadow, height, FALSE); - MoveWindow(GetDlgItem(data->hDlg, rct3), x + shadow, y + height, width, shadow, FALSE); - MoveWindow(GetDlgItem(data->hDlg, rct1), x, y, width, height, FALSE); - - tmp = data->rtDrawRect; - tmp.right += shadow; - tmp.bottom += shadow; - InvalidateRect(data->hDlg, &tmp, TRUE); -} - -static inline LONG *element_from_margin_id(RECT *rc, WORD id) -{ - switch(id) - { - case edt4: return &rc->left; - case edt5: return &rc->top; - case edt6: return &rc->right; - case edt7: return &rc->bottom; - } - return NULL; -} - -static void update_margin_edits(HWND hDlg, const pagesetup_data *data, WORD id) -{ - WCHAR str[100]; - WORD idx; - - for(idx = edt4; idx <= edt7; idx++) - { - if(id == 0 || id == idx) - { - size2str(data, *element_from_margin_id(pagesetup_get_margin_rect(data), idx), str); - SetDlgItemTextW(hDlg, idx, str); - } - } -} - -static void margin_edit_notification(HWND hDlg, const pagesetup_data *data, WORD msg, WORD id) -{ - switch (msg) - { - case EN_CHANGE: - { - WCHAR buf[10]; - LONG val = 0; - LONG *value = element_from_margin_id(pagesetup_get_margin_rect(data), id); - - if (GetDlgItemTextW(hDlg, id, buf, ARRAY_SIZE(buf)) != 0) - { - WCHAR *end; - WCHAR decimal = get_decimal_sep(); - - val = wcstol(buf, &end, 10); - if(end != buf || *end == decimal) - { - int mult = is_metric(data) ? 100 : 1000; - val *= mult; - if(*end == decimal) - { - while(mult > 1) - { - end++; - mult /= 10; - if(iswdigit(*end)) - val += (*end - '0') * mult; - else - break; - } - } - } - } - *value = val; - return; - } - - case EN_KILLFOCUS: - update_margin_edits(hDlg, data, id); - return; - } -} - -static void set_margin_groupbox_title(HWND hDlg, const pagesetup_data *data) -{ - WCHAR title[256]; - - if(LoadStringW(COMDLG32_hInstance, is_metric(data) ? PD32_MARGINS_IN_MILLIMETERS : PD32_MARGINS_IN_INCHES, - title, ARRAY_SIZE(title))) - SetDlgItemTextW(hDlg, grp4, title); -} - -static void pagesetup_update_orientation_buttons(HWND hDlg, const pagesetup_data *data) -{ - if (pagesetup_get_orientation(data) == DMORIENT_LANDSCAPE) - CheckRadioButton(hDlg, rad1, rad2, rad2); - else - CheckRadioButton(hDlg, rad1, rad2, rad1); -} - -/**************************************************************************************** - * pagesetup_printer_properties - * - * Handle invocation of the 'Properties' button (not present in the default template). - */ -static void pagesetup_printer_properties(HWND hDlg, pagesetup_data *data) -{ - HANDLE hprn; - LPWSTR devname; - DEVMODEW *dm; - LRESULT count; - int i; - - devname = pagesetup_get_devname(data); - - if (!OpenPrinterW(devname, &hprn, NULL)) - { - FIXME("Call to OpenPrinter did not succeed!\n"); - pagesetup_release_a_devname(data, devname); - return; - } - - dm = pagesetup_get_devmode(data); - DocumentPropertiesW(hDlg, hprn, devname, dm, dm, DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT); - pagesetup_set_devmode(data, dm); - pagesetup_release_devmode(data, dm); - pagesetup_release_a_devname(data, devname); - ClosePrinter(hprn); - - /* Changing paper */ - pagesetup_update_papersize(data); - pagesetup_update_orientation_buttons(hDlg, data); - - /* Changing paper preview */ - pagesetup_change_preview(data); - - /* Selecting paper in combo */ - count = SendDlgItemMessageW(hDlg, cmb2, CB_GETCOUNT, 0, 0); - if(count != CB_ERR) - { - WORD paperword = pagesetup_get_papersize(data); - for(i = 0; i < count; i++) - { - if(SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0) == paperword) { - SendDlgItemMessageW(hDlg, cmb2, CB_SETCURSEL, i, 0); - break; - } - } - } -} - -/******************************************************************************** - * pagesetup_wm_command - * process WM_COMMAND message for PageSetupDlg - * - * PARAMS - * hDlg [in] Main dialog HANDLE - * wParam [in] WM_COMMAND wParam - * lParam [in] WM_COMMAND lParam - * pda [in/out] ptr to PageSetupDataA - */ - -static BOOL pagesetup_wm_command(HWND hDlg, WPARAM wParam, LPARAM lParam, pagesetup_data *data) -{ - WORD msg = HIWORD(wParam); - WORD id = LOWORD(wParam); - - TRACE("loword (lparam) %d, wparam 0x%Ix, lparam %08Ix\n", - LOWORD(lParam),wParam,lParam); - switch (id) { - case IDOK: - EndDialog(hDlg, TRUE); - return TRUE ; - - case IDCANCEL: - EndDialog(hDlg, FALSE); - return FALSE ; - - case psh3: /* Printer... */ - pagesetup_change_printer_dialog(hDlg, data); - return TRUE; - - case rad1: /* Portrait */ - case rad2: /* Landscape */ - if((id == rad1 && pagesetup_get_orientation(data) == DMORIENT_LANDSCAPE) || - (id == rad2 && pagesetup_get_orientation(data) == DMORIENT_PORTRAIT)) - { - pagesetup_set_orientation(data, (id == rad1) ? DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE); - pagesetup_update_papersize(data); - rotate_rect(pagesetup_get_margin_rect(data), (id == rad2)); - update_margin_edits(hDlg, data, 0); - pagesetup_change_preview(data); - } - break; - case cmb1: /* Printer combo */ - if(msg == CBN_SELCHANGE) - { - WCHAR *name; - INT index = SendDlgItemMessageW(hDlg, id, CB_GETCURSEL, 0, 0); - INT length = SendDlgItemMessageW(hDlg, id, CB_GETLBTEXTLEN, index, 0); - name = malloc(sizeof(WCHAR) * (length + 1)); - SendDlgItemMessageW(hDlg, id, CB_GETLBTEXT, index, (LPARAM)name); - pagesetup_change_printer(name, data); - pagesetup_init_combos(hDlg, data); - free(name); - } - break; - case cmb2: /* Paper combo */ - if(msg == CBN_SELCHANGE) - { - DWORD paperword = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, - SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0), 0); - if (paperword != CB_ERR) - { - pagesetup_set_papersize(data, paperword); - pagesetup_update_papersize(data); - pagesetup_change_preview(data); - } else - FIXME("could not get dialog text for papersize cmbbox?\n"); - } - break; - case cmb3: /* Paper Source */ - if(msg == CBN_SELCHANGE) - { - WORD source = SendDlgItemMessageW(hDlg, cmb3, CB_GETITEMDATA, - SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0), 0); - pagesetup_set_defaultsource(data, source); - } - break; - case psh2: /* Printer Properties button */ - pagesetup_printer_properties(hDlg, data); - break; - case edt4: - case edt5: - case edt6: - case edt7: - margin_edit_notification(hDlg, data, msg, id); - break; - } - InvalidateRect(GetDlgItem(hDlg, rct1), NULL, TRUE); - return FALSE; -} - -/*********************************************************************** - * default_page_paint_hook - * Default hook paint procedure that receives WM_PSD_* messages from the dialog box - * whenever the sample page is redrawn. - */ -static UINT_PTR default_page_paint_hook(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam, - const pagesetup_data *data) -{ - LPRECT lprc = (LPRECT) lParam; - HDC hdc = (HDC) wParam; - HPEN hpen, holdpen; - LOGFONTW lf; - HFONT hfont, holdfont; - INT oldbkmode; - TRACE("uMsg: WM_USER+%d\n",uMsg-WM_USER); - /* Call user paint hook if enable */ - if (pagesetup_get_flags(data) & PSD_ENABLEPAGEPAINTHOOK) - if (pagesetup_get_hook(data, page_paint_hook)(hwndDlg, uMsg, wParam, lParam)) - return TRUE; - - switch (uMsg) { - /* LPPAGESETUPDLG in lParam */ - case WM_PSD_PAGESETUPDLG: - /* Inform about the sample page rectangle */ - case WM_PSD_FULLPAGERECT: - /* Inform about the margin rectangle */ - case WM_PSD_MINMARGINRECT: - return FALSE; - - /* Draw dashed rectangle showing margins */ - case WM_PSD_MARGINRECT: - hpen = CreatePen(PS_DASH, 1, GetSysColor(COLOR_3DSHADOW)); - holdpen = SelectObject(hdc, hpen); - Rectangle(hdc, lprc->left, lprc->top, lprc->right, lprc->bottom); - DeleteObject(SelectObject(hdc, holdpen)); - return TRUE; - /* Draw the fake document */ - case WM_PSD_GREEKTEXTRECT: - /* select a nice scalable font, because we want the text really small */ - SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0); - lf.lfHeight = 6; /* value chosen based on visual effect */ - hfont = CreateFontIndirectW(&lf); - holdfont = SelectObject(hdc, hfont); - - /* if text not loaded, then do so now */ - if (wszFakeDocumentText[0] == '\0') - LoadStringW(COMDLG32_hInstance, - IDS_FAKEDOCTEXT, - wszFakeDocumentText, - ARRAY_SIZE(wszFakeDocumentText)); - - oldbkmode = SetBkMode(hdc, TRANSPARENT); - DrawTextW(hdc, wszFakeDocumentText, -1, lprc, DT_TOP|DT_LEFT|DT_NOPREFIX|DT_WORDBREAK); - SetBkMode(hdc, oldbkmode); - - DeleteObject(SelectObject(hdc, holdfont)); - return TRUE; - - /* Envelope stamp */ - case WM_PSD_ENVSTAMPRECT: - /* Return address */ - case WM_PSD_YAFULLPAGERECT: - FIXME("envelope/stamp is not implemented\n"); - return FALSE; - default: - FIXME("Unknown message %x\n",uMsg); - return FALSE; - } - return TRUE; -} - -/*********************************************************************** - * PagePaintProc - * The main paint procedure for the PageSetupDlg function. - * The Page Setup dialog box includes an image of a sample page that shows how - * the user's selections affect the appearance of the printed output. - * The image consists of a rectangle that represents the selected paper - * or envelope type, with a dotted-line rectangle representing - * the current margins, and partial (Greek text) characters - * to show how text looks on the printed page. - * - * The following messages in the order sends to user hook procedure: - * WM_PSD_PAGESETUPDLG Draw the contents of the sample page - * WM_PSD_FULLPAGERECT Inform about the bounding rectangle - * WM_PSD_MINMARGINRECT Inform about the margin rectangle (min margin?) - * WM_PSD_MARGINRECT Draw the margin rectangle - * WM_PSD_GREEKTEXTRECT Draw the Greek text inside the margin rectangle - * If any of first three messages returns TRUE, painting done. - * - * PARAMS: - * hWnd [in] Handle to the Page Setup dialog box - * uMsg [in] Received message - * - * TODO: - * WM_PSD_ENVSTAMPRECT Draw in the envelope-stamp rectangle (for envelopes only) - * WM_PSD_YAFULLPAGERECT Draw the return address portion (for envelopes and other paper sizes) - * - * RETURNS: - * FALSE if all done correctly - * - */ - - -static LRESULT CALLBACK -PRINTDLG_PagePaintProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - PAINTSTRUCT ps; - RECT rcClient, rcMargin; - HPEN hpen, holdpen; - HDC hdc; - HBRUSH hbrush, holdbrush; - pagesetup_data *data; - int papersize=0, orientation=0; /* FIXME: set these values for the user paint hook */ - double scalx, scaly; - - if (uMsg != WM_PAINT) - return CallWindowProcA(lpfnStaticWndProc, hWnd, uMsg, wParam, lParam); - - /* Processing WM_PAINT message */ - data = GetPropW(hWnd, pagesetupdlg_prop); - if (!data) { - WARN("__WINE_PAGESETUPDLGDATA prop not set?\n"); - return FALSE; - } - if (default_page_paint_hook(hWnd, WM_PSD_PAGESETUPDLG, MAKELONG(papersize, orientation), - pagesetup_get_dlg_struct(data), data)) - return FALSE; - - hdc = BeginPaint(hWnd, &ps); - GetClientRect(hWnd, &rcClient); - - scalx = rcClient.right / (double)pagesetup_get_papersize_pt(data)->x; - scaly = rcClient.bottom / (double)pagesetup_get_papersize_pt(data)->y; - rcMargin = rcClient; - - rcMargin.left += pagesetup_get_margin_rect(data)->left * scalx; - rcMargin.top += pagesetup_get_margin_rect(data)->top * scaly; - rcMargin.right -= pagesetup_get_margin_rect(data)->right * scalx; - rcMargin.bottom -= pagesetup_get_margin_rect(data)->bottom * scaly; - - /* if the space is too small then we make sure to not draw anything */ - rcMargin.left = min(rcMargin.left, rcMargin.right); - rcMargin.top = min(rcMargin.top, rcMargin.bottom); - - if (!default_page_paint_hook(hWnd, WM_PSD_FULLPAGERECT, (WPARAM)hdc, (LPARAM)&rcClient, data) && - !default_page_paint_hook(hWnd, WM_PSD_MINMARGINRECT, (WPARAM)hdc, (LPARAM)&rcMargin, data) ) - { - /* fill background */ - hbrush = GetSysColorBrush(COLOR_3DHIGHLIGHT); - FillRect(hdc, &rcClient, hbrush); - holdbrush = SelectObject(hdc, hbrush); - - hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)); - holdpen = SelectObject(hdc, hpen); - - /* paint left edge */ - MoveToEx(hdc, rcClient.left, rcClient.top, NULL); - LineTo(hdc, rcClient.left, rcClient.bottom-1); - - /* paint top edge */ - MoveToEx(hdc, rcClient.left, rcClient.top, NULL); - LineTo(hdc, rcClient.right, rcClient.top); - - hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DDKSHADOW)); - DeleteObject(SelectObject(hdc, hpen)); - - /* paint right edge */ - MoveToEx(hdc, rcClient.right-1, rcClient.top, NULL); - LineTo(hdc, rcClient.right-1, rcClient.bottom); - - /* paint bottom edge */ - MoveToEx(hdc, rcClient.left, rcClient.bottom-1, NULL); - LineTo(hdc, rcClient.right, rcClient.bottom-1); - - DeleteObject(SelectObject(hdc, holdpen)); - DeleteObject(SelectObject(hdc, holdbrush)); - - default_page_paint_hook(hWnd, WM_PSD_MARGINRECT, (WPARAM)hdc, (LPARAM)&rcMargin, data); - - /* give text a bit of a space from the frame */ - InflateRect(&rcMargin, -2, -2); - - /* if the space is too small then we make sure to not draw anything */ - rcMargin.left = min(rcMargin.left, rcMargin.right); - rcMargin.top = min(rcMargin.top, rcMargin.bottom); - - default_page_paint_hook(hWnd, WM_PSD_GREEKTEXTRECT, (WPARAM)hdc, (LPARAM)&rcMargin, data); - } - - EndPaint(hWnd, &ps); - return FALSE; -} - -/******************************************************* - * The margin edit controls are subclassed to filter - * anything other than numbers and the decimal separator. - */ -static LRESULT CALLBACK pagesetup_margin_editproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -{ - if (msg == WM_CHAR) - { - WCHAR decimal = get_decimal_sep(); - WCHAR wc = (WCHAR)wparam; - if(!iswdigit(wc) && wc != decimal && wc != VK_BACK) return 0; - } - return CallWindowProcW(edit_wndproc, hwnd, msg, wparam, lparam); -} - -static void subclass_margin_edits(HWND hDlg) -{ - int id; - WNDPROC old_proc; - - for(id = edt4; id <= edt7; id++) - { - old_proc = (WNDPROC)SetWindowLongPtrW(GetDlgItem(hDlg, id), - GWLP_WNDPROC, - (ULONG_PTR)pagesetup_margin_editproc); - InterlockedCompareExchangePointer((void**)&edit_wndproc, old_proc, NULL); - } -} - -/*********************************************************************** - * pagesetup_dlg_proc - * - * Message handler for PageSetupDlg - */ -static INT_PTR CALLBACK pagesetup_dlg_proc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - pagesetup_data *data; - INT_PTR res = FALSE; - HWND hDrawWnd; - - if (uMsg == WM_INITDIALOG) { /*Init dialog*/ - data = (pagesetup_data *)lParam; - data->hDlg = hDlg; - - hDrawWnd = GetDlgItem(hDlg, rct1); - TRACE("set property to %p\n", data); - SetPropW(hDlg, pagesetupdlg_prop, data); - SetPropW(hDrawWnd, pagesetupdlg_prop, data); - GetWindowRect(hDrawWnd, &data->rtDrawRect); /* Calculating rect in client coordinates where paper draws */ - MapWindowPoints( 0, hDlg, (LPPOINT)&data->rtDrawRect, 2 ); - lpfnStaticWndProc = (WNDPROC)SetWindowLongPtrW( - hDrawWnd, - GWLP_WNDPROC, - (ULONG_PTR)PRINTDLG_PagePaintProc); - - /* FIXME: Paint hook. Must it be at begin of initialization or at end? */ - res = TRUE; - if (pagesetup_get_flags(data) & PSD_ENABLEPAGESETUPHOOK) - { - if (!pagesetup_get_hook(data, page_setup_hook)(hDlg, uMsg, wParam, - pagesetup_get_dlg_struct(data))) - FIXME("Setup page hook failed?\n"); - } - - /* if printer button disabled */ - if (pagesetup_get_flags(data) & PSD_DISABLEPRINTER) - EnableWindow(GetDlgItem(hDlg, psh3), FALSE); - /* if margin edit boxes disabled */ - if (pagesetup_get_flags(data) & PSD_DISABLEMARGINS) - { - EnableWindow(GetDlgItem(hDlg, edt4), FALSE); - EnableWindow(GetDlgItem(hDlg, edt5), FALSE); - EnableWindow(GetDlgItem(hDlg, edt6), FALSE); - EnableWindow(GetDlgItem(hDlg, edt7), FALSE); - } - - /* Set orientation radiobuttons properly */ - pagesetup_update_orientation_buttons(hDlg, data); - - /* if orientation disabled */ - if (pagesetup_get_flags(data) & PSD_DISABLEORIENTATION) - { - EnableWindow(GetDlgItem(hDlg,rad1),FALSE); - EnableWindow(GetDlgItem(hDlg,rad2),FALSE); - } - - /* We fill them out enabled or not */ - if (!(pagesetup_get_flags(data) & PSD_MARGINS)) - { - /* default is 1 inch */ - LONG size = thousandths_inch_to_size(data, 1000); - SetRect(pagesetup_get_margin_rect(data), size, size, size, size); - } - update_margin_edits(hDlg, data, 0); - subclass_margin_edits(hDlg); - set_margin_groupbox_title(hDlg, data); - - /* if paper disabled */ - if (pagesetup_get_flags(data) & PSD_DISABLEPAPER) - { - EnableWindow(GetDlgItem(hDlg,cmb2),FALSE); - EnableWindow(GetDlgItem(hDlg,cmb3),FALSE); - } - - /* filling combos: printer, paper, source. selecting current printer (from DEVMODEA) */ - pagesetup_init_combos(hDlg, data); - pagesetup_update_papersize(data); - pagesetup_set_defaultsource(data, DMBIN_FORMSOURCE); /* FIXME: This is the auto select bin. Is this correct? */ - - /* Drawing paper prev */ - pagesetup_change_preview(data); - return TRUE; - } else { - data = GetPropW(hDlg, pagesetupdlg_prop); - if (!data) - { - WARN("__WINE_PAGESETUPDLGDATA prop not set?\n"); - return FALSE; - } - if (pagesetup_get_flags(data) & PSD_ENABLEPAGESETUPHOOK) - { - res = pagesetup_get_hook(data, page_setup_hook)(hDlg, uMsg, wParam, lParam); - if (res) return res; - } - } - switch (uMsg) { - case WM_COMMAND: - return pagesetup_wm_command(hDlg, wParam, lParam, data); - } - return FALSE; -} - -static WCHAR *get_default_printer(void) -{ - WCHAR *name = NULL; - DWORD len = 0; - - GetDefaultPrinterW(NULL, &len); - if(len) - { - name = malloc(len * sizeof(WCHAR)); - GetDefaultPrinterW(name, &len); - } - return name; -} - -static void pagesetup_dump_dlg_struct(const pagesetup_data *data) -{ - if(TRACE_ON(commdlg)) - { - char flagstr[1000] = ""; - const struct pd_flags *pflag = psd_flags; - for( ; pflag->name; pflag++) - { - if(pagesetup_get_flags(data) & pflag->flag) - { - strcat(flagstr, pflag->name); - strcat(flagstr, "|"); - } - } - TRACE("%s: (%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n" - "hinst %p, flags %08lx (%s)\n", - data->unicode ? "unicode" : "ansi", - data->u.dlgw, data->u.dlgw->hwndOwner, data->u.dlgw->hDevMode, - data->u.dlgw->hDevNames, data->u.dlgw->hInstance, - pagesetup_get_flags(data), flagstr); - } -} - -static void *pagesetup_get_template(pagesetup_data *data) -{ - HRSRC res; - HGLOBAL tmpl_handle; - - if(pagesetup_get_flags(data) & PSD_ENABLEPAGESETUPTEMPLATEHANDLE) - { - tmpl_handle = data->u.dlgw->hPageSetupTemplate; - } - else if(pagesetup_get_flags(data) & PSD_ENABLEPAGESETUPTEMPLATE) - { - if(data->unicode) - res = FindResourceW(data->u.dlgw->hInstance, - data->u.dlgw->lpPageSetupTemplateName, (LPWSTR)RT_DIALOG); - else - res = FindResourceA(data->u.dlga->hInstance, - data->u.dlga->lpPageSetupTemplateName, (LPSTR)RT_DIALOG); - tmpl_handle = LoadResource(data->u.dlgw->hInstance, res); - } - else - { - res = FindResourceW(COMDLG32_hInstance, MAKEINTRESOURCEW(PAGESETUPDLGORD), - (LPWSTR)RT_DIALOG); - tmpl_handle = LoadResource(COMDLG32_hInstance, res); - } - return LockResource(tmpl_handle); -} - -static BOOL pagesetup_common(pagesetup_data *data) -{ - BOOL ret; - void *tmpl; - - if(!pagesetup_get_dlg_struct(data)) - { - COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION); - return FALSE; - } - - pagesetup_dump_dlg_struct(data); - - if(data->u.dlgw->lStructSize != sizeof(PAGESETUPDLGW)) - { - COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); - return FALSE; - } - - if ((pagesetup_get_flags(data) & PSD_ENABLEPAGEPAINTHOOK) && - (pagesetup_get_hook(data, page_paint_hook) == NULL)) - { - COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK); - return FALSE; - } - - if(!(pagesetup_get_flags(data) & (PSD_INTHOUSANDTHSOFINCHES | PSD_INHUNDREDTHSOFMILLIMETERS))) - data->u.dlgw->Flags |= is_default_metric() ? - PSD_INHUNDREDTHSOFMILLIMETERS : PSD_INTHOUSANDTHSOFINCHES; - - if (!data->u.dlgw->hDevMode || !data->u.dlgw->hDevNames) - { - WCHAR *def = get_default_printer(); - if(!def) - { - if (!(pagesetup_get_flags(data) & PSD_NOWARNING)) - { - WCHAR errstr[256]; - LoadStringW(COMDLG32_hInstance, PD32_NO_DEFAULT_PRINTER, errstr, 255); - MessageBoxW(data->u.dlgw->hwndOwner, errstr, 0, MB_OK | MB_ICONERROR); - } - COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); - return FALSE; - } - pagesetup_change_printer(def, data); - free(def); - } - - if (pagesetup_get_flags(data) & PSD_RETURNDEFAULT) - { - pagesetup_update_papersize(data); - return TRUE; - } - - tmpl = pagesetup_get_template(data); - - ret = DialogBoxIndirectParamW(data->u.dlgw->hInstance, tmpl, - data->u.dlgw->hwndOwner, - pagesetup_dlg_proc, (LPARAM)data) > 0; - return ret; -} - -/*********************************************************************** - * PageSetupDlgA (COMDLG32.@) - * - * Displays the PAGE SETUP dialog box, which enables the user to specify - * specific properties of a printed page such as - * size, source, orientation and the width of the page margins. - * - * PARAMS - * setupdlg [IO] PAGESETUPDLGA struct - * - * RETURNS - * TRUE if the user pressed the OK button - * FALSE if the user cancelled the window or an error occurred - * - * NOTES - * The values of hDevMode and hDevNames are filled on output and can be - * changed in PAGESETUPDLG when they are passed in PageSetupDlg. - * - */ -BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg) -{ - pagesetup_data data; - - data.unicode = FALSE; - data.u.dlga = setupdlg; - - return pagesetup_common(&data); -} - -/*********************************************************************** - * PageSetupDlgW (COMDLG32.@) - * - * See PageSetupDlgA. - */ -BOOL WINAPI PageSetupDlgW(LPPAGESETUPDLGW setupdlg) -{ - pagesetup_data data; - - data.unicode = TRUE; - data.u.dlgw = setupdlg; - - return pagesetup_common(&data); -} - -static void pdlgex_to_pdlg(const PRINTDLGEXW *pdlgex, PRINTDLGW *pdlg) -{ - pdlg->lStructSize = sizeof(*pdlg); - pdlg->hwndOwner = pdlgex->hwndOwner; - pdlg->hDevMode = pdlgex->hDevMode; - pdlg->hDevNames = pdlgex->hDevNames; - pdlg->hDC = pdlgex->hDC; - pdlg->Flags = pdlgex->Flags; - if ((pdlgex->Flags & PD_NOPAGENUMS) || !pdlgex->nPageRanges || !pdlgex->lpPageRanges) - { - pdlg->nFromPage = 0; - pdlg->nToPage = 65534; - } - else - { - pdlg->nFromPage = pdlgex->lpPageRanges[0].nFromPage; - pdlg->nToPage = pdlgex->lpPageRanges[0].nToPage; - } - pdlg->nMinPage = pdlgex->nMinPage; - pdlg->nMaxPage = pdlgex->nMaxPage; - pdlg->nCopies = pdlgex->nCopies; - pdlg->hInstance = pdlgex->hInstance; - pdlg->lCustData = 0; - pdlg->lpfnPrintHook = NULL; - pdlg->lpfnSetupHook = NULL; - pdlg->lpPrintTemplateName = pdlgex->lpPrintTemplateName; - pdlg->lpSetupTemplateName = NULL; - pdlg->hPrintTemplate = NULL; - pdlg->hSetupTemplate = NULL; -} - -/* Only copy fields that are supposed to be changed. */ -static void pdlg_to_pdlgex(const PRINTDLGW *pdlg, PRINTDLGEXW *pdlgex) -{ - pdlgex->hDevMode = pdlg->hDevMode; - pdlgex->hDevNames = pdlg->hDevNames; - pdlgex->hDC = pdlg->hDC; - if (!(pdlgex->Flags & PD_NOPAGENUMS) && pdlgex->nPageRanges && pdlgex->lpPageRanges) - { - pdlgex->lpPageRanges[0].nFromPage = pdlg->nFromPage; - pdlgex->lpPageRanges[0].nToPage = pdlg->nToPage; - } - pdlgex->nMinPage = pdlg->nMinPage; - pdlgex->nMaxPage = pdlg->nMaxPage; - pdlgex->nCopies = pdlg->nCopies; -} - -struct callback_data -{ - IPrintDialogCallback *callback; - IObjectWithSite *object; -}; - -static UINT_PTR CALLBACK pdlgex_hook_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) -{ - if (msg == WM_INITDIALOG) - { - PRINTDLGW *pd = (PRINTDLGW *)lp; - struct callback_data *cb = (struct callback_data *)pd->lCustData; - - if (cb->callback) - { - cb->callback->lpVtbl->SelectionChange(cb->callback); - cb->callback->lpVtbl->InitDone(cb->callback); - } - } - else - { -/* FIXME: store interface pointer somewhere in window properties and call it - HRESULT hres; - cb->callback->lpVtbl->HandleMessage(cb->callback, hwnd, msg, wp, lp, &hres); -*/ - } - - return 0; -} - -/*********************************************************************** - * PrintDlgExA (COMDLG32.@) - * - * See PrintDlgExW. - * - * BUGS - * Only a Stub - * - */ -HRESULT WINAPI PrintDlgExA(LPPRINTDLGEXA lppd) -{ - PRINTER_INFO_2A *pbuf; - DRIVER_INFO_3A *dbuf; - DEVMODEA *dm; - HRESULT hr = S_OK; - HANDLE hprn; - - if ((lppd == NULL) || (lppd->lStructSize != sizeof(PRINTDLGEXA))) - return E_INVALIDARG; - - if (!IsWindow(lppd->hwndOwner)) - return E_HANDLE; - - if (lppd->nStartPage != START_PAGE_GENERAL) - { - if (!lppd->nPropertyPages) - return E_INVALIDARG; - - FIXME("custom property sheets (%ld at %p) not supported\n", lppd->nPropertyPages, lppd->lphPropertyPages); - } - - /* Use PD_NOPAGENUMS or set nMaxPageRanges and lpPageRanges */ - if (!(lppd->Flags & PD_NOPAGENUMS) && (!lppd->nMaxPageRanges || !lppd->lpPageRanges)) - { - return E_INVALIDARG; - } - - if (lppd->Flags & PD_RETURNDEFAULT) - { - if (lppd->hDevMode || lppd->hDevNames) - { - WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n"); - COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); - return E_INVALIDARG; - } - if (!PRINTDLG_OpenDefaultPrinter(&hprn)) - { - WARN("Can't find default printer\n"); - COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); - return E_FAIL; - } - - pbuf = get_printer_infoA(hprn); - if (!pbuf) - { - ClosePrinter(hprn); - return E_FAIL; - } - - dbuf = get_driver_infoA(hprn); - if (!dbuf) - { - free(pbuf); - COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); - ClosePrinter(hprn); - return E_FAIL; - } - dm = pbuf->pDevMode; - } - else - { - PRINTDLGA pdlg; - struct callback_data cb_data = { 0 }; - - FIXME("(%p) semi-stub\n", lppd); - - if (lppd->lpCallback) - { - IUnknown_QueryInterface((IUnknown *)lppd->lpCallback, &IID_IPrintDialogCallback, (void **)&cb_data.callback); - IUnknown_QueryInterface((IUnknown *)lppd->lpCallback, &IID_IObjectWithSite, (void **)&cb_data.object); - } - - /* - * PRINTDLGEXA/W and PRINTDLGA/W layout is the same for A and W variants. - */ - pdlgex_to_pdlg((const PRINTDLGEXW *)lppd, (PRINTDLGW *)&pdlg); - pdlg.Flags |= PD_ENABLEPRINTHOOK; - pdlg.lpfnPrintHook = pdlgex_hook_proc; - pdlg.lCustData = (LPARAM)&cb_data; - - if (PrintDlgA(&pdlg)) - { - pdlg_to_pdlgex((const PRINTDLGW *)&pdlg, (PRINTDLGEXW *)lppd); - lppd->dwResultAction = PD_RESULT_PRINT; - } - else - lppd->dwResultAction = PD_RESULT_CANCEL; - - if (cb_data.callback) - cb_data.callback->lpVtbl->Release(cb_data.callback); - if (cb_data.object) - cb_data.object->lpVtbl->Release(cb_data.object); - - return S_OK; - } - - ClosePrinter(hprn); - - PRINTDLG_CreateDevNames(&(lppd->hDevNames), dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName); - if (!lppd->hDevNames) - hr = E_FAIL; - - lppd->hDevMode = update_devmode_handleA(lppd->hDevMode, dm); - if (hr == S_OK && lppd->hDevMode) { - if (lppd->Flags & PD_RETURNDC) { - lppd->hDC = CreateDCA(dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, dm); - if (!lppd->hDC) - hr = E_FAIL; - } - else if (lppd->Flags & PD_RETURNIC) { - lppd->hDC = CreateICA(dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, dm); - if (!lppd->hDC) - hr = E_FAIL; - } - } - else - hr = E_FAIL; - - free(pbuf); - free(dbuf); - - return hr; -} - -/*********************************************************************** - * PrintDlgExW (COMDLG32.@) - * - * Display the property sheet style PRINT dialog box - * - * PARAMS - * lppd [IO] ptr to PRINTDLGEX struct - * - * RETURNS - * Success: S_OK - * Failure: One of the following COM error codes: - * E_OUTOFMEMORY Insufficient memory. - * E_INVALIDARG One or more arguments are invalid. - * E_POINTER Invalid pointer. - * E_HANDLE Invalid handle. - * E_FAIL Unspecified error. - * - * NOTES - * This Dialog enables the user to specify specific properties of the print job. - * The property sheet can also have additional application-specific and - * driver-specific property pages. - * - * BUGS - * Not fully implemented - * - */ -HRESULT WINAPI PrintDlgExW(LPPRINTDLGEXW lppd) -{ - PRINTER_INFO_2W *pbuf; - DRIVER_INFO_3W *dbuf; - DEVMODEW *dm; - HRESULT hr = S_OK; - HANDLE hprn; - - if ((lppd == NULL) || (lppd->lStructSize != sizeof(PRINTDLGEXW))) { - return E_INVALIDARG; - } - - if (!IsWindow(lppd->hwndOwner)) { - return E_HANDLE; - } - - if (lppd->nStartPage != START_PAGE_GENERAL) - { - if (!lppd->nPropertyPages) - return E_INVALIDARG; - - FIXME("custom property sheets (%ld at %p) not supported\n", lppd->nPropertyPages, lppd->lphPropertyPages); - } - - /* Use PD_NOPAGENUMS or set nMaxPageRanges and lpPageRanges */ - if (!(lppd->Flags & PD_NOPAGENUMS) && (!lppd->nMaxPageRanges || !lppd->lpPageRanges)) - { - return E_INVALIDARG; - } - - if (lppd->Flags & PD_RETURNDEFAULT) { - - if (lppd->hDevMode || lppd->hDevNames) { - WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n"); - COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); - return E_INVALIDARG; - } - if (!PRINTDLG_OpenDefaultPrinter(&hprn)) { - WARN("Can't find default printer\n"); - COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); - return E_FAIL; - } - - pbuf = get_printer_infoW(hprn); - if (!pbuf) - { - ClosePrinter(hprn); - return E_FAIL; - } - - dbuf = get_driver_infoW(hprn); - if (!dbuf) - { - free(pbuf); - COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); - ClosePrinter(hprn); - return E_FAIL; - } - dm = pbuf->pDevMode; - } - else - { - PRINTDLGW pdlg; - struct callback_data cb_data = { 0 }; - - FIXME("(%p) semi-stub\n", lppd); - - if (lppd->lpCallback) - { - IUnknown_QueryInterface((IUnknown *)lppd->lpCallback, &IID_IPrintDialogCallback, (void **)&cb_data.callback); - IUnknown_QueryInterface((IUnknown *)lppd->lpCallback, &IID_IObjectWithSite, (void **)&cb_data.object); - } - - pdlgex_to_pdlg(lppd, &pdlg); - pdlg.Flags |= PD_ENABLEPRINTHOOK; - pdlg.lpfnPrintHook = pdlgex_hook_proc; - pdlg.lCustData = (LPARAM)&cb_data; - - if (PrintDlgW(&pdlg)) - { - pdlg_to_pdlgex(&pdlg, lppd); - lppd->dwResultAction = PD_RESULT_PRINT; - } - else - lppd->dwResultAction = PD_RESULT_CANCEL; - - if (cb_data.callback) - cb_data.callback->lpVtbl->Release(cb_data.callback); - if (cb_data.object) - cb_data.object->lpVtbl->Release(cb_data.object); - - return S_OK; - } - - ClosePrinter(hprn); - - PRINTDLG_CreateDevNamesW(&(lppd->hDevNames), dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName); - if (!lppd->hDevNames) - hr = E_FAIL; - - lppd->hDevMode = update_devmode_handleW(lppd->hDevMode, dm); - if (hr == S_OK && lppd->hDevMode) { - if (lppd->Flags & PD_RETURNDC) { - lppd->hDC = CreateDCW(dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, dm); - if (!lppd->hDC) - hr = E_FAIL; - } - else if (lppd->Flags & PD_RETURNIC) { - lppd->hDC = CreateICW(dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, dm); - if (!lppd->hDC) - hr = E_FAIL; - } - } - else - hr = E_FAIL; - - free(pbuf); - free(dbuf); - - return hr; -} diff --git a/wrappers/extensions/comdlgex/version.rc b/wrappers/extensions/comdlgex/version.rc deleted file mode 100644 index 25f9271a17..0000000000 --- a/wrappers/extensions/comdlgex/version.rc +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2011 Jacek Caban for CodeWeavers - * - * 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 - -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#define WINE_FILEDESCRIPTION_STR "Windows Performance Data Helper Wrapper for One-Core-API" -#define WINE_FILENAME_STR "pdh.dll" - -#include "common_wrappers_ver.rc" \ No newline at end of file diff --git a/wrappers/extensions/cryptex/cryptex.spec b/wrappers/extensions/cryptex/cryptex.spec index 2b435c8987..7dafb4e29d 100644 --- a/wrappers/extensions/cryptex/cryptex.spec +++ b/wrappers/extensions/cryptex/cryptex.spec @@ -119,7 +119,7 @@ @ stdcall CryptEncryptMessage(ptr long ptr ptr long ptr ptr) @ stdcall CryptEnumOIDFunction(long str str long ptr ptr) @ stdcall CryptEnumOIDInfo(long long ptr ptr) -@ stdcall CryptEnumProvidersU(long ptr long ptr wstr ptr) +@ stdcall -arch=i386 CryptEnumProvidersU(long ptr long ptr wstr ptr) @ stdcall CryptExportPKCS8(ptr long str long ptr ptr ptr) @ stdcall CryptExportPublicKeyInfo(long long long ptr ptr) @ stdcall CryptExportPublicKeyInfoEx(long long long str long ptr ptr ptr) @@ -182,11 +182,11 @@ @ stdcall CryptSetAsyncParam(ptr str ptr ptr) @ stdcall CryptSetKeyIdentifierProperty(ptr long long wstr ptr ptr) @ stdcall CryptSetOIDFunctionValue(long str str wstr long ptr long) -@ stdcall CryptSetProviderU(wstr long) +@ stdcall -arch=i386 CryptSetProviderU(wstr long) @ stdcall CryptSignAndEncodeCertificate(long long long str ptr ptr ptr ptr ptr) @ stdcall CryptSignAndEncryptMessage(ptr ptr long ptr ptr long ptr ptr) @ stdcall CryptSignCertificate(long long long ptr long ptr ptr ptr ptr) -@ stdcall CryptSignHashU(ptr long wstr long ptr ptr) +@ stdcall -arch=i386 CryptSignHashU(ptr long wstr long ptr ptr) @ stdcall CryptSignMessage(ptr long long ptr ptr ptr ptr) @ stdcall CryptSignMessageWithKey(ptr ptr long ptr ptr) @ stdcall CryptStringToBinaryA(str long long ptr ptr ptr ptr) @@ -203,7 +203,7 @@ @ stdcall CryptVerifyMessageHash(ptr ptr long ptr ptr ptr ptr) @ stdcall CryptVerifyMessageSignature(ptr long ptr long ptr ptr ptr) @ stdcall CryptVerifyMessageSignatureWithKey(ptr ptr ptr long ptr ptr) -@ stdcall CryptVerifySignatureU(ptr ptr long ptr wstr long) +@ stdcall -arch=i386 CryptVerifySignatureU(ptr ptr long ptr wstr long) @ stdcall I_CertUpdateStore(ptr ptr long long) @ stdcall I_CryptAllocTls() @ stdcall I_CryptCreateLruCache(ptr ptr) @@ -233,15 +233,15 @@ @ stdcall PFXImportCertStore(ptr ptr long) @ stdcall PFXIsPFXBlob(ptr) @ stdcall PFXVerifyPassword(ptr wstr long) -@ stdcall RegCreateHKCUKeyExU(ptr wstr long wstr long ptr ptr ptr ptr) -@ stdcall RegCreateKeyExU(ptr wstr long wstr long ptr ptr ptr ptr) -@ stdcall RegDeleteValueU(ptr wstr) -@ stdcall RegEnumValueU(ptr long wstr ptr ptr ptr ptr ptr) -@ stdcall RegOpenHKCUKeyExU(ptr wstr long ptr ptr) -@ stdcall RegOpenKeyExU(ptr wstr long ptr ptr) -@ stdcall RegQueryInfoKeyU(ptr wstr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) -@ stdcall RegQueryValueExU(ptr wstr ptr ptr ptr ptr) -@ stdcall RegSetValueExU(ptr wstr long long ptr long) +@ stdcall -arch=i386 RegCreateHKCUKeyExU(ptr wstr long wstr long ptr ptr ptr ptr) +@ stdcall -arch=i386 RegCreateKeyExU(ptr wstr long wstr long ptr ptr ptr ptr) +@ stdcall -arch=i386 RegDeleteValueU(ptr wstr) +@ stdcall -arch=i386 RegEnumValueU(ptr long wstr ptr ptr ptr ptr ptr) +@ stdcall -arch=i386 RegOpenHKCUKeyExU(ptr wstr long ptr ptr) +@ stdcall -arch=i386 RegOpenKeyExU(ptr wstr long ptr ptr) +@ stdcall -arch=i386 RegQueryInfoKeyU(ptr wstr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall -arch=i386 RegQueryValueExU(ptr wstr ptr ptr ptr ptr) +@ stdcall -arch=i386 RegSetValueExU(ptr wstr long long ptr long) ;Extension Functions (win7) @ stdcall CryptRetrieveTimeStamp(wstr long long str ptr ptr long ptr ptr ptr) diff --git a/wrappers/extensions/dnsapiext/version.rc b/wrappers/extensions/dnsapiext/version.rc index a76f267582..bd3709a49d 100644 --- a/wrappers/extensions/dnsapiext/version.rc +++ b/wrappers/extensions/dnsapiext/version.rc @@ -1,5 +1,5 @@ /* - * Copyright 2020 Austin English + * Copyright 2009 Henri Verbeet for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -15,12 +15,8 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ + +#define WINE_FILEDESCRIPTION_STR "DNS Client API DLL Library Wrapper for One-Core-API" +#define WINE_FILENAME_STR "dnsapiext.dll" -#define WINE_FILEDESCRIPTION_STR "Wine dcomp" -#define WINE_FILENAME_STR "dcomp.dll" -#define WINE_FILEVERSION 10,0,14393,0 -#define WINE_FILEVERSION_STR "10.0.14393.0" -#define WINE_PRODUCTVERSION 10,0,14393,0 -#define WINE_PRODUCTVERSION_STR "10.0.14393.0" - -#include "wine/wine_common_ver.rc" +#include "common_wrappers_ver.rc" \ No newline at end of file diff --git a/wrappers/extensions/dxgiext/version.rc b/wrappers/extensions/dxgiext/version.rc index c152ab6fae..4eb79aed36 100644 --- a/wrappers/extensions/dxgiext/version.rc +++ b/wrappers/extensions/dxgiext/version.rc @@ -18,9 +18,5 @@ #define WINE_FILEDESCRIPTION_STR "One-Core-API dxgi extension" #define WINE_FILENAME_STR "dxgiext.dll" -#define WINE_FILEVERSION 10,0,14393,0 -#define WINE_FILEVERSION_STR "10.0.14393.0" -#define WINE_PRODUCTVERSION 10,0,14393,0 -#define WINE_PRODUCTVERSION_STR "10.0.14393.0" -#include "wine/wine_common_ver.rc" +#include "common_wrappers_ver.rc" \ No newline at end of file diff --git a/wrappers/extensions/iphlpext/iphlpapi.c b/wrappers/extensions/iphlpext/iphlpapi.c index 220d806794..58090044e8 100644 --- a/wrappers/extensions/iphlpext/iphlpapi.c +++ b/wrappers/extensions/iphlpext/iphlpapi.c @@ -535,7 +535,13 @@ DWORD WINAPI CancelMibChangeNotify2(HANDLE handle) { - FIXME("(handle %p): stub\n", handle); + FIXME("(handle %p): stub\n", handle); + // NotifyIpInterfaceChange返回的句柄始终等于 2 + if (_hNotificationHandle != (HANDLE)2)) + { + return ERROR_INVALID_PARAMETER; + } + return NO_ERROR; } @@ -1794,4 +1800,16 @@ DWORD WINAPI ConvertInterfaceLuidToAlias( const NET_LUID *luid, WCHAR *alias, SI alias[name.Length / sizeof(WCHAR)] = '\0'; return err; -} \ No newline at end of file +} + +DWORD WINAPI GetAnycastIpAddressTable(ADDRESS_FAMILY family, MIB_ANYCASTIPADDRESS_TABLE **table) +{ + FIXME( "(%u, %p) stub\n", family, table ); + if (!table || (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC)) + return ERROR_INVALID_PARAMETER; + + *table = heap_alloc_zero(sizeof(MIB_ANYCASTIPADDRESS_TABLE)); + if (!*table) return ERROR_NOT_ENOUGH_MEMORY; + (*table)->NumEntries = 0; + return NO_ERROR; +} diff --git a/wrappers/extensions/iphlpext/iphlpext.spec b/wrappers/extensions/iphlpext/iphlpext.spec index 4adc3e1802..104d5700c2 100644 --- a/wrappers/extensions/iphlpext/iphlpext.spec +++ b/wrappers/extensions/iphlpext/iphlpext.spec @@ -174,6 +174,7 @@ @ stdcall ConvertStringToGuidW( ptr ptr ) @ stdcall CreateSortedAddressPairs(ptr long ptr long long ptr ptr) @ stdcall FreeMibTable(ptr) +@ stdcall GetAnycastIpAddressTable( long ptr ) @ stdcall GetBestRoute2(ptr long ptr ptr long ptr ptr) @ stdcall GetIfEntry2(ptr) @ stdcall GetIfTable2Ex(long ptr) diff --git a/wrappers/extensions/iphlpext/main.h b/wrappers/extensions/iphlpext/main.h index c35723f213..4ccaf9d8b4 100644 --- a/wrappers/extensions/iphlpext/main.h +++ b/wrappers/extensions/iphlpext/main.h @@ -162,6 +162,20 @@ typedef enum _IPHLPAddrType { IPAAddr, IPABcast, IPAMask, IFMtu, IFStatus } IPHLPAddrType; +typedef struct _MIB_ANYCASTIPADDRESS_ROW +{ + SOCKADDR_INET Address; + NET_LUID InterfaceLuid; + NET_IFINDEX InterfaceIndex; + SCOPE_ID ScopeId; +} MIB_ANYCASTIPADDRESS_ROW, *PMIB_ANYCASTIPADDRESS_ROW; + +typedef struct _MIB_ANYCASTIPADDRESS_TABLE +{ + ULONG NumEntries; + MIB_ANYCASTIPADDRESS_ROW Table[ANY_SIZE]; +} MIB_ANYCASTIPADDRESS_TABLE, *PMIB_ANYCASTIPADDRESS_TABLE; + typedef VOID (WINAPI *PIPINTERFACE_CHANGE_CALLBACK)(PVOID, PMIB_IPINTERFACE_ROW, MIB_NOTIFICATION_TYPE); diff --git a/wrappers/extensions/kernelex/appmodel.c b/wrappers/extensions/kernelex/appmodel.c index 94ac4ea2c5..c769c54f43 100644 --- a/wrappers/extensions/kernelex/appmodel.c +++ b/wrappers/extensions/kernelex/appmodel.c @@ -236,4 +236,13 @@ LONG WINAPI OpenPackageInfoByFullName( ) { return ERROR_NOT_FOUND; +} + +/*********************************************************************** + * GetCurrentPackageInfo (kernelbase.@) + */ +LONG WINAPI GetCurrentPackageInfo( const UINT32 flags, UINT32 *buffer_size, BYTE *buffer, UINT32 *count ) +{ + FIXME( "(%#x %p %p %p): stub\n", flags, buffer_size, buffer, count ); + return APPMODEL_ERROR_NO_PACKAGE; } \ No newline at end of file diff --git a/wrappers/extensions/kernelex/console.c b/wrappers/extensions/kernelex/console.c index 03c4721b20..c108601d37 100644 --- a/wrappers/extensions/kernelex/console.c +++ b/wrappers/extensions/kernelex/console.c @@ -216,4 +216,21 @@ SetCurrentConsoleFontEx( ) { return SetConsoleFont(hConsoleOutput, lpConsoleCurrentFontEx->nFont); +} + +/****************************************************************************** + * ClosePseudoConsole (kernelbase.@) + */ +void WINAPI ClosePseudoConsole( HPCON handle ) +{ + struct pseudo_console *pseudo_console = handle; + + if (!pseudo_console) return; + if (pseudo_console->signal) CloseHandle( pseudo_console->signal ); + if (pseudo_console->process) + { + WaitForSingleObject( pseudo_console->process, INFINITE ); + CloseHandle( pseudo_console->process ); + } + if (pseudo_console->reference) CloseHandle( pseudo_console->reference ); } \ No newline at end of file diff --git a/wrappers/extensions/kernelex/datetime.c b/wrappers/extensions/kernelex/datetime.c index cc7a7c7810..5a4ad12aff 100644 --- a/wrappers/extensions/kernelex/datetime.c +++ b/wrappers/extensions/kernelex/datetime.c @@ -1445,22 +1445,7 @@ GetTimeZoneInformationForYear( LPTIME_ZONE_INFORMATION ptzi ) { - DYNAMIC_TIME_ZONE_INFORMATION local_dtzi, result; - - if (!pdtzi) - { - if (GetDynamicTimeZoneInformation(&local_dtzi) == TIME_ZONE_ID_INVALID) - return FALSE; - pdtzi = &local_dtzi; - } - - if (!TIME_GetSpecificTimeZoneInfo(pdtzi->TimeZoneKeyName, wYear, - !pdtzi->DynamicDaylightTimeDisabled, &result)) - return FALSE; - - memcpy(ptzi, &result, sizeof(*ptzi)); - - return TRUE; + return GetTimeZoneInformation(ptzi) != TIME_ZONE_ID_INVALID; } BOOL diff --git a/wrappers/extensions/kernelex/dllatom.c b/wrappers/extensions/kernelex/dllatom.c index c7a79db923..8b57c6ef0e 100644 --- a/wrappers/extensions/kernelex/dllatom.c +++ b/wrappers/extensions/kernelex/dllatom.c @@ -22,7 +22,7 @@ Revision History: WINE_DEFAULT_DEBUG_CHANNEL(dllatom); -ATOM GlobalAddAtomExA( +ATOM WINAPI GlobalAddAtomExA( LPCSTR lpString, DWORD Flags //Ignored for now ) @@ -30,7 +30,7 @@ ATOM GlobalAddAtomExA( return GlobalAddAtomA(lpString); } -ATOM GlobalAddAtomExW( +ATOM WINAPI GlobalAddAtomExW( LPCWSTR lpString, DWORD Flags //Ignored for now ) diff --git a/wrappers/extensions/kernelex/dllmain.c b/wrappers/extensions/kernelex/dllmain.c index eafdee7174..38748561f8 100644 --- a/wrappers/extensions/kernelex/dllmain.c +++ b/wrappers/extensions/kernelex/dllmain.c @@ -40,6 +40,8 @@ BaseDllInitialize( { /* Cache the PEB and Session ID */ //Peb = NtCurrentPeb(); + DWORD bufferSize = 65535; + LPWSTR AppData; switch (dwReason) { @@ -75,7 +77,18 @@ BaseDllInitialize( lpHashTableEntry = &WaitOnAddressHashTable[i]; InitializeCriticalSection(&lpHashTableEntry->Lock); InitializeListHead(&lpHashTableEntry->Addresses); - } + } + AppData = (LPWSTR)HeapAlloc(GetProcessHeap(), 8, MAX_PATH * 2); + if (!AppData) + return E_OUTOFMEMORY; + + if(GetEnvironmentVariableW(L"HOMEPATH", AppData, bufferSize) > 0 || GetEnvironmentVariableW(L"LOCALAPPDATA", AppData, bufferSize) == 0){ + SetEnvironmentVariableW(L"LOCALAPPDATA", wcscat(AppData, L"\\Local Settings\\Application Data\\")); + } + + SetEnvironmentVariable("PROGRAMDATA", "%SYSTEMDRIVE%\\ProgramData"); + + HeapFree(GetProcessHeap(), 0, AppData); break; } diff --git a/wrappers/extensions/kernelex/filemap.c b/wrappers/extensions/kernelex/filemap.c index bbcfea7637..65a9bc005f 100644 --- a/wrappers/extensions/kernelex/filemap.c +++ b/wrappers/extensions/kernelex/filemap.c @@ -55,7 +55,7 @@ typedef BOOLEAN (WINAPI *pRtlGenRandomPtr)(PVOID RandomBuffer, ULONG RandomBuffe * @implemented */ HANDLE -NTAPI +WINAPI CreateFileMappingA(IN HANDLE hFile, IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes, IN DWORD flProtect, @@ -100,7 +100,7 @@ LPWSTR CreateNewFallbackMappingName() { * @implemented */ HANDLE -NTAPI +WINAPI CreateFileMappingW(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, @@ -230,7 +230,7 @@ CreateFileMappingW(HANDLE hFile, * @implemented */ HANDLE -NTAPI +WINAPI CreateFileMappingNumaW( HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, @@ -353,7 +353,7 @@ CreateFileMappingNumaW( * @implemented */ HANDLE -NTAPI +WINAPI CreateFileMappingNumaA( IN HANDLE hFile, IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes, @@ -400,7 +400,7 @@ CreateFileMappingNumaA( * @implemented */ LPVOID -NTAPI +WINAPI MapViewOfFileExNuma( HANDLE hFileMappingObject, DWORD dwDesiredAccess, @@ -512,4 +512,35 @@ OpenFileMappingFromApp( ) { return OpenFileMappingW(DesiredAccess, InheritHandle, Name); +} + +BOOL +WINAPI +UnmapViewOfFileEx( + _In_ PVOID BaseAddress, + _In_ ULONG UnmapFlags +) +{ + // if (const auto pUnmapViewOfFileEx = try_get_UnmapViewOfFileEx()) + // { + // return pUnmapViewOfFileEx(BaseAddress, UnmapFlags); + // } + + return UnmapViewOfFile(BaseAddress); +} + +BOOL +WINAPI +UnmapViewOfFile2( + _In_ HANDLE process, + _In_ PVOID BaseAddress, + _In_ ULONG UnmapFlags +) +{ + // if (const auto pUnmapViewOfFileEx = try_get_UnmapViewOfFileEx()) + // { + // return pUnmapViewOfFileEx(BaseAddress, UnmapFlags); + // } + + return UnmapViewOfFile(BaseAddress); } \ No newline at end of file diff --git a/wrappers/extensions/kernelex/filemisc.c b/wrappers/extensions/kernelex/filemisc.c index 654dad1561..80a53824ec 100644 --- a/wrappers/extensions/kernelex/filemisc.c +++ b/wrappers/extensions/kernelex/filemisc.c @@ -150,7 +150,7 @@ GetFileAttributesTransactedA( return GetFileAttributesExA(lpFileName, fInfoLevelId, lpFileInformation); } -HANDLE FindFirstFileNameW( +HANDLE WINAPI FindFirstFileNameW( LPCWSTR lpFileName, DWORD dwFlags, LPDWORD StringLength, @@ -160,7 +160,7 @@ HANDLE FindFirstFileNameW( return (HANDLE)-1; } -BOOL FindNextFileNameW( +BOOL WINAPI FindNextFileNameW( HANDLE hFindStream, LPDWORD StringLength, PWSTR LinkName @@ -201,3 +201,16 @@ GetFileBandwidthReservation(IN HANDLE hFile, UNIMPLEMENTED; return FALSE; } + +HANDLE +WINAPI +FindFirstFileNameTransactedW( + LPCWSTR lpFileName, + DWORD dwFlags, + LPDWORD StringLength, + PWSTR LinkName, + HANDLE hTransaction +) +{ + return (HANDLE)-1; +} \ No newline at end of file diff --git a/wrappers/extensions/kernelex/fileopcr.c b/wrappers/extensions/kernelex/fileopcr.c index 37fc795b05..14f2ad406d 100644 --- a/wrappers/extensions/kernelex/fileopcr.c +++ b/wrappers/extensions/kernelex/fileopcr.c @@ -229,29 +229,186 @@ CreateFileTransactedA( hTemplateFile); } -HANDLE -WINAPI -CreateFile2( - _In_ LPCWSTR lpFileName, - _In_ DWORD dwDesiredAccess, - _In_ DWORD dwShareMode, - _In_ DWORD dwCreationDisposition, - _In_opt_ LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams -) +HANDLE WINAPI CreateFile2( + IN PCWSTR FileName, + IN ULONG DesiredAccess, + IN ULONG ShareMode, + IN ULONG CreationDisposition, + IN PCREATEFILE2_EXTENDED_PARAMETERS ExtendedParameters OPTIONAL) { - if(!pCreateExParams) - return CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); - - return CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, pCreateExParams->lpSecurityAttributes, dwCreationDisposition, pCreateExParams->dwFileAttributes | pCreateExParams->dwFileFlags | pCreateExParams->dwSecurityQosFlags, pCreateExParams->hTemplateFile); + if (ExtendedParameters) { + ULONG FlagsAndAttributes; + + if (ExtendedParameters->dwSize < sizeof(CREATEFILE2_EXTENDED_PARAMETERS)) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return INVALID_HANDLE_VALUE; + } + + FlagsAndAttributes = ExtendedParameters->dwFileFlags | + ExtendedParameters->dwSecurityQosFlags | + ExtendedParameters->dwFileAttributes; + + return CreateFileW( + FileName, + DesiredAccess, + ShareMode, + ExtendedParameters->lpSecurityAttributes, + CreationDisposition, + FlagsAndAttributes, + ExtendedParameters->hTemplateFile); + } else { + return CreateFileW( + FileName, + DesiredAccess, + ShareMode, + NULL, + CreationDisposition, + 0, + NULL); + } } -HRESULT -WINAPI +#define COPY_FILE_COPY_SYMLINK 0x00000800 +#define COPY_FILE_NO_BUFFERING 0x00001000 +#define COPY_FILE_DIRECTORY 0x00000080 // Win10 +#define COPY_FILE_REQUEST_SECURITY_PRIVILEGES 0x00002000 // Win8 +#define COPY_FILE_RESUME_FROM_PAUSE 0x00004000 // Win8 +#define COPY_FILE_SKIP_ALTERNATE_STREAMS 0x00008000 // Win10 +#define COPY_FILE_NO_OFFLOAD 0x00040000 // Win8 +#define COPY_FILE_OPEN_AND_COPY_REPARSE_POINT 0x00200000 // Win10 +#define COPY_FILE_IGNORE_EDP_BLOCK 0x00400000 // Win10 +#define COPY_FILE_IGNORE_SOURCE_ENCRYPTION 0x00800000 // Win10 +#define COPY_FILE_DONT_REQUEST_DEST_WRITE_DAC 0x02000000 // Win10 +#define COPY_FILE_DISABLE_PRE_ALLOCATION 0x04000000 // Win10 +#define COPY_FILE_ENABLE_LOW_FREE_SPACE_MODE 0x08000000 // Win10 +#define COPY_FILE_REQUEST_COMPRESSED_TRAFFIC 0x10000000 // Win10 +#define COPY_FILE_ENABLE_SPARSE_COPY 0x20000000 // Win11 + +#define COPY_FILE_WIN7_VALID_FLAGS (COPY_FILE_FAIL_IF_EXISTS | COPY_FILE_RESTARTABLE | \ + COPY_FILE_OPEN_SOURCE_FOR_WRITE | COPY_FILE_ALLOW_DECRYPTED_DESTINATION | \ + COPY_FILE_COPY_SYMLINK | COPY_FILE_NO_BUFFERING) + +#define COPY_FILE_WIN8_VALID_FLAGS (COPY_FILE_WIN7_VALID_FLAGS | COPY_FILE_REQUEST_SECURITY_PRIVILEGES | \ + COPY_FILE_RESUME_FROM_PAUSE | COPY_FILE_NO_OFFLOAD) + +#define COPY_FILE_WIN10_VALID_FLAGS (COPY_FILE_WIN8_VALID_FLAGS | COPY_FILE_DIRECTORY | COPY_FILE_SKIP_ALTERNATE_STREAMS | \ + COPY_FILE_OPEN_AND_COPY_REPARSE_POINT | COPY_FILE_IGNORE_EDP_BLOCK | \ + COPY_FILE_IGNORE_SOURCE_ENCRYPTION | COPY_FILE_DONT_REQUEST_DEST_WRITE_DAC | \ + COPY_FILE_DISABLE_PRE_ALLOCATION | COPY_FILE_ENABLE_LOW_FREE_SPACE_MODE | \ + COPY_FILE_REQUEST_COMPRESSED_TRAFFIC) + +#define COPY_FILE_WIN11_VALID_FLAGS (COPY_FILE_WIN10_VALID_FLAGS | COPY_FILE_ENABLE_SPARSE_COPY) + +#define COPY_FILE_ALL_VALID_FLAGS (COPY_FILE_WIN11_VALID_FLAGS) + + +#ifndef _DEBUG +# define ASSUME __assume +# define NOT_REACHED ASSUME(FALSE) +#else +# define ASSUME ASSERT +# define NOT_REACHED ASSUME(("Execution should not have reached this point", FALSE)) +#endif + +static DWORD CALLBACK KxBasepCopyFile2ProgressRoutine( + IN LARGE_INTEGER TotalFileSize, + IN LARGE_INTEGER TotalBytesTransferred, + IN LARGE_INTEGER StreamSize, + IN LARGE_INTEGER StreamBytesTransferred, + IN DWORD StreamNumber, + IN DWORD CallbackReason, + IN HANDLE SourceFile, + IN HANDLE DestinationFile, + IN PVOID Context OPTIONAL) +{ + COPYFILE2_MESSAGE Message; + PCOPYFILE2_EXTENDED_PARAMETERS Copyfile2Parameters; + + ASSERT (Context != NULL); + + RtlZeroMemory(&Message, sizeof(Message)); + + switch (CallbackReason) { + case CALLBACK_CHUNK_FINISHED: + Message.Type = COPYFILE2_CALLBACK_CHUNK_FINISHED; + Message.Info.ChunkFinished.dwStreamNumber = StreamNumber; + Message.Info.ChunkFinished.uliTotalFileSize.QuadPart = TotalFileSize.QuadPart; + Message.Info.ChunkFinished.uliTotalBytesTransferred.QuadPart = TotalBytesTransferred.QuadPart; + Message.Info.ChunkFinished.uliStreamSize.QuadPart = StreamSize.QuadPart; + Message.Info.ChunkFinished.uliStreamBytesTransferred.QuadPart = StreamBytesTransferred.QuadPart; + break; + case CALLBACK_STREAM_SWITCH: + Message.Type = COPYFILE2_CALLBACK_STREAM_STARTED; + Message.Info.StreamStarted.dwStreamNumber = StreamNumber; + Message.Info.StreamStarted.hDestinationFile = DestinationFile; + Message.Info.StreamStarted.hSourceFile = SourceFile; + Message.Info.StreamStarted.uliStreamSize.QuadPart = StreamSize.QuadPart; + Message.Info.StreamStarted.uliTotalFileSize.QuadPart = TotalFileSize.QuadPart; + break; + default: + ASSUME (FALSE); + } + + Copyfile2Parameters = (PCOPYFILE2_EXTENDED_PARAMETERS) Context; + + return Copyfile2Parameters->pProgressRoutine( + &Message, + Copyfile2Parameters->pvCallbackContext); +} + +HRESULT +WINAPI CopyFile2( - _In_ PCWSTR pwszExistingFileName, - _In_ PCWSTR pwszNewFileName, - _In_opt_ COPYFILE2_EXTENDED_PARAMETERS *pExtendedParameters -) + IN PCWSTR ExistingFileName, + IN PCWSTR NewFileName, + IN PCOPYFILE2_EXTENDED_PARAMETERS ExtendedParameters OPTIONAL) { - return CopyFileW(pwszExistingFileName, pwszNewFileName, FALSE); + BOOL Success; + ULONG EffectiveCopyFlags; + + if (ExtendedParameters == NULL) { + Success = CopyFileW( + ExistingFileName, + NewFileName, + FALSE); + + if (Success) { + return S_OK; + } else { + return HRESULT_FROM_WIN32(GetLastError()); + } + } + + if (ExtendedParameters->dwSize != sizeof(COPYFILE2_EXTENDED_PARAMETERS)) { + // + // Windows 11 defines a COPYFILE2_EXTENDED_PARAMETERS_V2 struture. + // When apps start using it, we will support it too. + // + + DbgPrint( + "Unrecognized dwSize member of ExtendedParameters: %lu\n", + ExtendedParameters->dwSize); + + return E_INVALIDARG; + } + + if (ExtendedParameters->dwCopyFlags & ~COPY_FILE_ALL_VALID_FLAGS) { + return E_INVALIDARG; + } + + EffectiveCopyFlags = ExtendedParameters->dwCopyFlags & COPY_FILE_WIN7_VALID_FLAGS; + + Success = CopyFileExW( + ExistingFileName, + NewFileName, + ExtendedParameters->pProgressRoutine ? KxBasepCopyFile2ProgressRoutine : NULL, + ExtendedParameters, + ExtendedParameters->pfCancel, + EffectiveCopyFlags & ~(COPY_FILE_NO_BUFFERING + COPY_FILE_COPY_SYMLINK)); + + if (Success) { + return S_OK; + } else { + return HRESULT_FROM_WIN32(GetLastError()); + } } \ No newline at end of file diff --git a/wrappers/extensions/kernelex/firmware.c b/wrappers/extensions/kernelex/firmware.c index f3e56e816b..0087a0659e 100644 --- a/wrappers/extensions/kernelex/firmware.c +++ b/wrappers/extensions/kernelex/firmware.c @@ -20,7 +20,11 @@ Revision History: #include "main.h" -BOOL GetFirmwareType(WORD* firmwareType) +BOOL +WINAPI +GetFirmwareType( + WORD* firmwareType + ) { HKEY hKey; DWORD dwType = 0; diff --git a/wrappers/extensions/kernelex/kernelex.spec b/wrappers/extensions/kernelex/kernelex.spec index 054d991a7a..548aaf1db1 100644 --- a/wrappers/extensions/kernelex/kernelex.spec +++ b/wrappers/extensions/kernelex/kernelex.spec @@ -1003,10 +1003,10 @@ @ stdcall SetProcessDEPPolicy(long) #Own implementation only for support - hooks -@ stdcall CreateProcessA(str str ptr ptr long long ptr str ptr ptr) CreateProcessExA -@ stdcall CreateProcessInternalA(ptr str str ptr ptr long long ptr str ptr ptr long) CreateProcessInternalExA -@ stdcall CreateProcessInternalW(ptr wstr wstr ptr ptr long long ptr wstr ptr ptr long) CreateProcessInternalExW -@ stdcall CreateProcessW(wstr wstr ptr ptr long long ptr wstr ptr ptr) CreateProcessExW +@ stdcall CreateProcessA(str str ptr ptr long long ptr str ptr ptr) ;CreateProcessExA +@ stdcall CreateProcessInternalA(ptr str str ptr ptr long long ptr str ptr ptr long) ;CreateProcessInternalExA +@ stdcall CreateProcessInternalW(ptr wstr wstr ptr ptr long long ptr wstr ptr ptr long) ;CreateProcessInternalExW +@ stdcall CreateProcessW(wstr wstr ptr ptr long long ptr wstr ptr ptr) ;CreateProcessExW @ stdcall GetModuleHandleA(str) @ stdcall GetModuleHandleW(wstr) @ stdcall GetProcAddress(long str) @@ -1098,7 +1098,7 @@ @ stdcall FindFirstFileNameW(wstr long ptr wstr) @ stdcall FindFirstFileTransactedA(str long ptr long ptr long ptr) @ stdcall FindFirstFileTransactedW(wstr long ptr long ptr long ptr) -# @ stub FindFirstFileNameTransactedW +@ stdcall FindFirstFileNameTransactedW(wstr long ptr wstr ptr) @ stdcall FindFirstStreamTransactedW(wstr long ptr long ptr) @ stdcall FindNextFileNameW(long ptr wstr) @ stdcall FindNLSString(long long ptr long wstr long ptr) @@ -1160,7 +1160,6 @@ @ stdcall GetOverlappedResultEx(long ptr ptr long long) @ stdcall GetPhysicallyInstalledSystemMemory(ptr) @ stdcall GetProductInfo(long long long long ptr) -@ stub GetProductName @ stdcall GetQueuedCompletionStatusEx(ptr ptr long ptr long long) ;it doesn't work with Visual Code for now @ stdcall GetStringScripts(long wstr long wstr long) idndl.DownlevelGetStringScripts @ stdcall GetSystemDefaultLocaleName(ptr long) @@ -1392,6 +1391,7 @@ @ stdcall GetCurrentPackageId(ptr ptr) @ stdcall GetCurrentPackageFamilyName(ptr ptr) @ stdcall GetCurrentPackageFullName(ptr ptr) +@ stdcall GetCurrentPackageInfo(long ptr ptr ptr) @ stdcall GetCurrentPackagePath(ptr ptr) @ stdcall GetCurrentThreadStackLimits(ptr ptr) @ stdcall GetDynamicTimeZoneInformationEffectiveYears(ptr ptr ptr) @@ -1453,6 +1453,7 @@ @ stdcall SetProcessInformation(long long ptr long) @ stdcall SetProcessGroupAffinity(long ptr ptr) @ stdcall SetThreadInformation(long long ptr long) +@ stdcall UnmapViewOfFileEx(ptr long) #Win8.1 functions @ stdcall DiscardVirtualMemory(ptr long) @@ -1465,8 +1466,10 @@ #Win10 functions @ stdcall AppPolicyGetMediaFoundationCodecLoading(ptr ptr) +@ stdcall ClosePseudoConsole(ptr) @ stdcall GetSystemCpuSetInformation(ptr long ptr ptr long) @ stdcall GetThreadDescription(long ptr) +@ stdcall GetUserDefaultGeoName(ptr long) @ stdcall InitializeContext2(ptr long ptr ptr int64) @ stdcall IsWow64Process2(ptr ptr ptr) @ stdcall QueryInterruptTime(ptr) @@ -1477,51 +1480,53 @@ @ stdcall WaitForDebugEventEx(ptr long) #Windows 11 and Server 2022 functions -#@ stdcall GetTempPath2A(long str) -#@ stdcall GetTempPath2W(long wstr) +@ stdcall FlsGetValue2(long) +@ stdcall GetTempPath2A(long str) +@ stdcall GetTempPath2W(long wstr) @ stdcall SetProcessDefaultCpuSets(ptr ptr long) +@ stdcall TlsGetValue2(long) -#Import from advapibase or registry function -@ stdcall AccessCheck(ptr long long ptr ptr ptr ptr ptr) advapibase.AccessCheck -@ stdcall AccessCheckAndAuditAlarmW(wstr ptr wstr wstr ptr long ptr long ptr ptr ptr) advapibase.AccessCheckAndAuditAlarmW -@ stdcall AccessCheckByType(ptr ptr long long ptr long ptr ptr ptr ptr ptr) advapibase.AccessCheckByType -@ stdcall AccessCheckByTypeAndAuditAlarmW(wstr ptr wstr wstr ptr ptr long long long ptr long ptr long ptr ptr ptr) advapibase.AccessCheckByTypeAndAuditAlarmW +#Import from advapi32 or registry function +@ stdcall AccessCheck(ptr long long ptr ptr ptr ptr ptr) advapi32.AccessCheck +@ stdcall AccessCheckAndAuditAlarmW(wstr ptr wstr wstr ptr long ptr long ptr ptr ptr) advapi32.AccessCheckAndAuditAlarmW +@ stdcall AccessCheckByType(ptr ptr long long ptr long ptr ptr ptr ptr ptr) advapi32.AccessCheckByType +@ stdcall AccessCheckByTypeAndAuditAlarmW(wstr ptr wstr wstr ptr ptr long long long ptr long ptr long ptr ptr ptr) advapi32.AccessCheckByTypeAndAuditAlarmW @ stdcall AccessCheckByTypeResultList(ptr ptr ptr long ptr long ptr ptr ptr ptr ptr) -@ stdcall AccessCheckByTypeResultListAndAuditAlarmByHandleW(wstr ptr ptr wstr wstr ptr long long long long ptr long ptr long ptr ptr ptr) advapibase.AccessCheckByTypeResultListAndAuditAlarmByHandleW -@ stdcall AccessCheckByTypeResultListAndAuditAlarmW(wstr ptr wstr wstr ptr long long long long ptr long ptr long ptr ptr ptr) advapibase.AccessCheckByTypeResultListAndAuditAlarmW -@ stdcall AddAccessAllowedAce(ptr long long ptr) advapibase.AddAccessAllowedAce -@ stdcall AddAccessAllowedAceEx(ptr long long long ptr) advapibase.AddAccessAllowedAceEx -@ stdcall AddAccessAllowedObjectAce(ptr long long long ptr ptr ptr) advapibase.AddAccessAllowedObjectAce -@ stdcall AddAccessDeniedAce(ptr long long ptr) advapibase.AddAccessDeniedAce -@ stdcall AddAccessDeniedAceEx(ptr long long long ptr) advapibase.AddAccessDeniedAceEx -@ stdcall AddAccessDeniedObjectAce(ptr long long long ptr ptr ptr) advapibase.AddAccessDeniedObjectAce -@ stdcall AddAce(ptr long long ptr long) advapibase.AddAce -@ stdcall AddAuditAccessAce(ptr long long ptr long long) advapibase.AddAuditAccessAce -@ stdcall AddAuditAccessAceEx(ptr long long long ptr long long) advapibase.AddAuditAccessAceEx -@ stdcall AddAuditAccessObjectAce(ptr long long long ptr ptr ptr long long) advapibase.AddAuditAccessObjectAce +@ stdcall AccessCheckByTypeResultListAndAuditAlarmByHandleW(wstr ptr ptr wstr wstr ptr long long long long ptr long ptr long ptr ptr ptr) advapi32.AccessCheckByTypeResultListAndAuditAlarmByHandleW +@ stdcall AccessCheckByTypeResultListAndAuditAlarmW(wstr ptr wstr wstr ptr long long long long ptr long ptr long ptr ptr ptr) advapi32.AccessCheckByTypeResultListAndAuditAlarmW +@ stdcall AddAccessAllowedAce(ptr long long ptr) advapi32.AddAccessAllowedAce +@ stdcall AddAccessAllowedAceEx(ptr long long long ptr) advapi32.AddAccessAllowedAceEx +@ stdcall AddAccessAllowedObjectAce(ptr long long long ptr ptr ptr) advapi32.AddAccessAllowedObjectAce +@ stdcall AddAccessDeniedAce(ptr long long ptr) advapi32.AddAccessDeniedAce +@ stdcall AddAccessDeniedAceEx(ptr long long long ptr) advapi32.AddAccessDeniedAceEx +@ stdcall AddAccessDeniedObjectAce(ptr long long long ptr ptr ptr) advapi32.AddAccessDeniedObjectAce +@ stdcall AddAce(ptr long long ptr long) advapi32.AddAce +@ stdcall AddAuditAccessAce(ptr long long ptr long long) advapi32.AddAuditAccessAce +@ stdcall AddAuditAccessAceEx(ptr long long long ptr long long) advapi32.AddAuditAccessAceEx +@ stdcall AddAuditAccessObjectAce(ptr long long long ptr ptr ptr long long) advapi32.AddAuditAccessObjectAce @ stdcall AddMandatoryAce(ptr long long long ptr) -@ stdcall AdjustTokenGroups(long long ptr long ptr ptr) advapibase.AdjustTokenGroups -@ stdcall AdjustTokenPrivileges(long long ptr long ptr ptr) advapibase.AdjustTokenPrivileges -@ stdcall AllocateAndInitializeSid(ptr long long long long long long long long long ptr) advapibase.AllocateAndInitializeSid -@ stdcall AllocateLocallyUniqueId(ptr) advapibase.AllocateLocallyUniqueId -@ stdcall AreAllAccessesGranted(long long) advapibase.AreAllAccessesGranted -@ stdcall AreAnyAccessesGranted(long long) advapibase.AreAnyAccessesGranted -@ stdcall CheckTokenMembership(long ptr ptr) advapibase.CheckTokenMembership -@ stdcall ConvertToAutoInheritPrivateObjectSecurity(ptr ptr ptr ptr long ptr) advapibase.ConvertToAutoInheritPrivateObjectSecurity -@ stdcall CopySid(long ptr ptr) advapibase.CopySid -@ stdcall CreatePrivateObjectSecurity(ptr ptr ptr long long ptr) advapibase.CreatePrivateObjectSecurity -@ stdcall CreatePrivateObjectSecurityEx(ptr ptr ptr ptr long long long ptr) advapibase.CreatePrivateObjectSecurityEx -@ stdcall CreatePrivateObjectSecurityWithMultipleInheritance(ptr ptr ptr ptr long long long long ptr) advapibase.CreatePrivateObjectSecurityWithMultipleInheritance -@ stdcall CreateRestrictedToken(long long long ptr long ptr long ptr ptr) advapibase.CreateRestrictedToken -@ stdcall CreateProcessAsUserA(long str str ptr ptr long long ptr str ptr ptr) advapibase.CreateProcessAsUserA -@ stdcall CreateProcessAsUserW(long wstr wstr ptr ptr long long ptr wstr ptr ptr) advapibase.CreateProcessAsUserW -@ stdcall CreateWellKnownSid(long ptr ptr ptr) advapibase.CreateWellKnownSid -@ stdcall DeleteAce(ptr long) advapibase.DeleteAce -@ stdcall DestroyPrivateObjectSecurity(ptr) advapibase.DestroyPrivateObjectSecurity -@ stdcall DuplicateToken(long long ptr) advapibase.DuplicateToken -@ stdcall DuplicateTokenEx(long long ptr long long ptr) advapibase.DuplicateTokenEx -@ stdcall EqualPrefixSid(ptr ptr) advapibase.EqualPrefixSid -@ stdcall EqualSid(ptr ptr) advapibase.EqualSid +@ stdcall AdjustTokenGroups(long long ptr long ptr ptr) advapi32.AdjustTokenGroups +@ stdcall AdjustTokenPrivileges(long long ptr long ptr ptr) advapi32.AdjustTokenPrivileges +@ stdcall AllocateAndInitializeSid(ptr long long long long long long long long long ptr) advapi32.AllocateAndInitializeSid +@ stdcall AllocateLocallyUniqueId(ptr) advapi32.AllocateLocallyUniqueId +@ stdcall AreAllAccessesGranted(long long) advapi32.AreAllAccessesGranted +@ stdcall AreAnyAccessesGranted(long long) advapi32.AreAnyAccessesGranted +@ stdcall CheckTokenMembership(long ptr ptr) advapi32.CheckTokenMembership +@ stdcall ConvertToAutoInheritPrivateObjectSecurity(ptr ptr ptr ptr long ptr) advapi32.ConvertToAutoInheritPrivateObjectSecurity +@ stdcall CopySid(long ptr ptr) advapi32.CopySid +@ stdcall CreatePrivateObjectSecurity(ptr ptr ptr long long ptr) advapi32.CreatePrivateObjectSecurity +@ stdcall CreatePrivateObjectSecurityEx(ptr ptr ptr ptr long long long ptr) advapi32.CreatePrivateObjectSecurityEx +@ stdcall CreatePrivateObjectSecurityWithMultipleInheritance(ptr ptr ptr ptr long long long long ptr) advapi32.CreatePrivateObjectSecurityWithMultipleInheritance +@ stdcall CreateRestrictedToken(long long long ptr long ptr long ptr ptr) advapi32.CreateRestrictedToken +@ stdcall CreateProcessAsUserA(long str str ptr ptr long long ptr str ptr ptr) advapi32.CreateProcessAsUserA +@ stdcall CreateProcessAsUserW(long wstr wstr ptr ptr long long ptr wstr ptr ptr) advapi32.CreateProcessAsUserW +@ stdcall CreateWellKnownSid(long ptr ptr ptr) advapi32.CreateWellKnownSid +@ stdcall DeleteAce(ptr long) advapi32.DeleteAce +@ stdcall DestroyPrivateObjectSecurity(ptr) advapi32.DestroyPrivateObjectSecurity +@ stdcall DuplicateToken(long long ptr) advapi32.DuplicateToken +@ stdcall DuplicateTokenEx(long long ptr long long ptr) advapi32.DuplicateTokenEx +@ stdcall EqualPrefixSid(ptr ptr) advapi32.EqualPrefixSid +@ stdcall EqualSid(ptr ptr) advapi32.EqualSid @ stdcall EventActivityIdControl(long ptr) ntext.EtwEventActivityIdControl @ stdcall EventEnabled(int64 ptr) ntext.EtwEventEnabled @ stdcall EventProviderEnabled(int64 long int64) ntext.EtwEventProviderEnabled @@ -1530,57 +1535,57 @@ @ stdcall EventWrite(int64 ptr long ptr) ntext.EtwEventWrite @ stdcall EventWriteString(int64 long int64 ptr) ntext.EtwEventWriteString @ stdcall EventWriteTransfer(int64 ptr ptr ptr long ptr) ntext.EtwEventWriteTransfer -@ stdcall FindFirstFreeAce(ptr ptr) advapibase.FindFirstFreeAce -@ stdcall FreeSid(ptr) advapibase.FreeSid -@ stdcall GetAce(ptr long ptr) advapibase.GetAce -@ stdcall GetAclInformation(ptr ptr long long) advapibase.GetAclInformation -@ stdcall GetFileSecurityA(str long ptr long ptr) advapibase.GetFileSecurityA -@ stdcall GetFileSecurityW(wstr long ptr long ptr) advapibase.GetFileSecurityW -@ stdcall GetLengthSid(ptr) advapibase.GetLengthSid -@ stdcall GetPrivateObjectSecurity(ptr long ptr long ptr) advapibase.GetPrivateObjectSecurity -@ stdcall GetSecurityDescriptorControl(ptr ptr ptr) advapibase.GetSecurityDescriptorControl -@ stdcall GetSecurityDescriptorDacl(ptr ptr ptr ptr) advapibase.GetSecurityDescriptorDacl +@ stdcall FindFirstFreeAce(ptr ptr) advapi32.FindFirstFreeAce +@ stdcall FreeSid(ptr) advapi32.FreeSid +@ stdcall GetAce(ptr long ptr) advapi32.GetAce +@ stdcall GetAclInformation(ptr ptr long long) advapi32.GetAclInformation +@ stdcall GetFileSecurityA(str long ptr long ptr) advapi32.GetFileSecurityA +@ stdcall GetFileSecurityW(wstr long ptr long ptr) advapi32.GetFileSecurityW +@ stdcall GetLengthSid(ptr) advapi32.GetLengthSid +@ stdcall GetPrivateObjectSecurity(ptr long ptr long ptr) advapi32.GetPrivateObjectSecurity +@ stdcall GetSecurityDescriptorControl(ptr ptr ptr) advapi32.GetSecurityDescriptorControl +@ stdcall GetSecurityDescriptorDacl(ptr ptr ptr ptr) advapi32.GetSecurityDescriptorDacl @ stdcall GetSecurityDescriptorLength(ptr) ntext.RtlLengthSecurityDescriptor -@ stdcall GetSecurityDescriptorOwner(ptr ptr ptr) advapibase.GetSecurityDescriptorOwner -@ stdcall GetSecurityDescriptorSacl(ptr ptr ptr ptr) advapibase.GetSecurityDescriptorSacl -@ stdcall GetSidIdentifierAuthority(ptr) advapibase.GetSidIdentifierAuthority -@ stdcall GetSidLengthRequired(long) advapibase.GetSidLengthRequired -@ stdcall GetSidSubAuthority(ptr long) advapibase.GetSidSubAuthority -@ stdcall GetSidSubAuthorityCount(ptr) advapibase.GetSidSubAuthorityCount -@ stdcall GetTokenInformation(long long ptr long ptr) advapibase.GetTokenInformation -@ stdcall GetTraceEnableFlags(int64) advapibase.GetTraceEnableFlags -@ stdcall GetTraceEnableLevel(int64) advapibase.GetTraceEnableLevel -@ stdcall -ret64 GetTraceLoggerHandle(ptr) advapibase.GetTraceLoggerHandle -@ stdcall GetWindowsAccountDomainSid(ptr ptr ptr) advapibase.GetWindowsAccountDomainSid -@ stdcall ImpersonateAnonymousToken(long) advapibase.ImpersonateAnonymousToken -@ stdcall ImpersonateLoggedOnUser(long) advapibase.ImpersonateLoggedOnUser -@ stdcall ImpersonateNamedPipeClient(long) advapibase.ImpersonateNamedPipeClient -@ stdcall ImpersonateSelf(long) advapibase.ImpersonateSelf -@ stdcall InitializeAcl(ptr long long) advapibase.InitializeAcl -@ stdcall InitializeSid(ptr ptr long) advapibase.InitializeSid -@ stdcall IsTokenRestricted(long) advapibase.IsTokenRestricted -@ stdcall IsValidAcl(ptr) advapibase.IsValidAcl -@ stdcall InitializeSecurityDescriptor(ptr long) advapibase.InitializeSecurityDescriptor -@ stdcall IsWellKnownSid(ptr long) advapibase.IsWellKnownSid -@ stdcall IsValidSecurityDescriptor(ptr) advapibase.IsValidSecurityDescriptor -@ stdcall IsValidSid(ptr) advapibase.IsValidSid -@ stdcall MakeAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) advapibase.MakeAbsoluteSD -@ stdcall MakeSelfRelativeSD(ptr ptr ptr) advapibase.MakeSelfRelativeSD -@ stdcall MapGenericMask(ptr ptr) advapibase.MapGenericMask -@ stdcall ObjectCloseAuditAlarmW(wstr ptr long) advapibase.ObjectCloseAuditAlarmW -@ stdcall ObjectDeleteAuditAlarmW(wstr ptr long) advapibase.ObjectDeleteAuditAlarmW -@ stdcall ObjectOpenAuditAlarmW(wstr ptr wstr wstr ptr long long long ptr long long ptr) advapibase.ObjectOpenAuditAlarmW -@ stdcall ObjectPrivilegeAuditAlarmW(wstr ptr long long ptr long) advapibase.ObjectPrivilegeAuditAlarmW -@ stdcall PrivilegeCheck(ptr ptr ptr) advapibase.PrivilegeCheck -@ stdcall PrivilegedServiceAuditAlarmW(wstr wstr long ptr long) advapibase.PrivilegedServiceAuditAlarmW -@ stdcall OpenProcessToken(ptr long ptr) advapibase.OpenProcessToken -@ stdcall OpenThreadToken(ptr long long ptr) advapibase.OpenThreadToken -@ stdcall RegCloseKey(ptr) advapibase.RegCloseKey +@ stdcall GetSecurityDescriptorOwner(ptr ptr ptr) advapi32.GetSecurityDescriptorOwner +@ stdcall GetSecurityDescriptorSacl(ptr ptr ptr ptr) advapi32.GetSecurityDescriptorSacl +@ stdcall GetSidIdentifierAuthority(ptr) advapi32.GetSidIdentifierAuthority +@ stdcall GetSidLengthRequired(long) advapi32.GetSidLengthRequired +@ stdcall GetSidSubAuthority(ptr long) advapi32.GetSidSubAuthority +@ stdcall GetSidSubAuthorityCount(ptr) advapi32.GetSidSubAuthorityCount +@ stdcall GetTokenInformation(long long ptr long ptr) advapi32.GetTokenInformation +@ stdcall GetTraceEnableFlags(int64) advapi32.GetTraceEnableFlags +@ stdcall GetTraceEnableLevel(int64) advapi32.GetTraceEnableLevel +@ stdcall -ret64 GetTraceLoggerHandle(ptr) advapi32.GetTraceLoggerHandle +@ stdcall GetWindowsAccountDomainSid(ptr ptr ptr) advapi32.GetWindowsAccountDomainSid +@ stdcall ImpersonateAnonymousToken(long) advapi32.ImpersonateAnonymousToken +@ stdcall ImpersonateLoggedOnUser(long) advapi32.ImpersonateLoggedOnUser +@ stdcall ImpersonateNamedPipeClient(long) advapi32.ImpersonateNamedPipeClient +@ stdcall ImpersonateSelf(long) advapi32.ImpersonateSelf +@ stdcall InitializeAcl(ptr long long) advapi32.InitializeAcl +@ stdcall InitializeSid(ptr ptr long) advapi32.InitializeSid +@ stdcall IsTokenRestricted(long) advapi32.IsTokenRestricted +@ stdcall IsValidAcl(ptr) advapi32.IsValidAcl +@ stdcall InitializeSecurityDescriptor(ptr long) advapi32.InitializeSecurityDescriptor +@ stdcall IsWellKnownSid(ptr long) advapi32.IsWellKnownSid +@ stdcall IsValidSecurityDescriptor(ptr) advapi32.IsValidSecurityDescriptor +@ stdcall IsValidSid(ptr) advapi32.IsValidSid +@ stdcall MakeAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) advapi32.MakeAbsoluteSD +@ stdcall MakeSelfRelativeSD(ptr ptr ptr) advapi32.MakeSelfRelativeSD +@ stdcall MapGenericMask(ptr ptr) advapi32.MapGenericMask +@ stdcall ObjectCloseAuditAlarmW(wstr ptr long) advapi32.ObjectCloseAuditAlarmW +@ stdcall ObjectDeleteAuditAlarmW(wstr ptr long) advapi32.ObjectDeleteAuditAlarmW +@ stdcall ObjectOpenAuditAlarmW(wstr ptr wstr wstr ptr long long long ptr long long ptr) advapi32.ObjectOpenAuditAlarmW +@ stdcall ObjectPrivilegeAuditAlarmW(wstr ptr long long ptr long) advapi32.ObjectPrivilegeAuditAlarmW +@ stdcall PrivilegeCheck(ptr ptr ptr) advapi32.PrivilegeCheck +@ stdcall PrivilegedServiceAuditAlarmW(wstr wstr long ptr long) advapi32.PrivilegedServiceAuditAlarmW +@ stdcall OpenProcessToken(ptr long ptr) advapi32.OpenProcessToken +@ stdcall OpenThreadToken(ptr long long ptr) advapi32.OpenThreadToken +@ stdcall RegCloseKey(ptr) advapi32.RegCloseKey @ stdcall RegCopyTreeW(ptr str ptr) @ stdcall RegCreateKeyExA(long str long ptr long long ptr ptr ptr) @ stdcall RegCreateKeyExW(long wstr long ptr long long ptr ptr ptr) @ stdcall RegDeleteKeyValueA(long str str) -@ stdcall RegDeleteKeyValueW(long wstr wstr) advapibase.RegDeleteKeyValueW +@ stdcall RegDeleteKeyValueW(long wstr wstr) advapi32.RegDeleteKeyValueW @ stdcall RegDeleteKeyExA(long str long long) @ stdcall RegDeleteKeyExW(long wstr long long) @ stdcall RegDeleteTreeA(long str) @@ -1592,55 +1597,55 @@ @ stdcall RegEnumKeyExW(long long ptr ptr ptr ptr ptr ptr) @ stdcall RegEnumValueA(long long ptr ptr ptr ptr ptr ptr) @ stdcall RegEnumValueW(long long ptr ptr ptr ptr ptr ptr) -@ stdcall RegFlushKey(long) advapibase.RegFlushKey -@ stdcall RegGetKeySecurity(long long ptr ptr) advapibase.RegGetKeySecurity -@ stdcall RegGetValueA(long str str long ptr ptr ptr) advapibase.RegGetValueA +@ stdcall RegFlushKey(long) advapi32.RegFlushKey +@ stdcall RegGetKeySecurity(long long ptr ptr) advapi32.RegGetKeySecurity +@ stdcall RegGetValueA(long str str long ptr ptr ptr) advapi32.RegGetValueA @ stdcall RegGetValueW(long wstr wstr long ptr ptr ptr) advapi32.RegGetValueW @ stdcall RegLoadAppKeyA(str ptr long long long) @ stdcall RegLoadAppKeyW(wstr ptr long long long) -@ stdcall RegLoadKeyA(long str str) advapibase.RegLoadKeyA -@ stdcall RegLoadKeyW(long wstr wstr) advapibase.RegLoadKeyW +@ stdcall RegLoadKeyA(long str str) advapi32.RegLoadKeyA +@ stdcall RegLoadKeyW(long wstr wstr) advapi32.RegLoadKeyW @ stdcall RegLoadMUIStringA(long str str long ptr long str) @ stdcall RegLoadMUIStringW(long wstr wstr long ptr long wstr) -@ stdcall RegNotifyChangeKeyValue(long long long long long) advapibase.RegNotifyChangeKeyValue -@ stdcall RegOpenCurrentUser(long ptr) advapibase.RegOpenCurrentUser +@ stdcall RegNotifyChangeKeyValue(long long long long long) advapi32.RegNotifyChangeKeyValue +@ stdcall RegOpenCurrentUser(long ptr) advapi32.RegOpenCurrentUser @ stdcall RegOpenKeyExA(long str long long ptr) @ stdcall RegOpenKeyExW(long wstr long long ptr) -@ stdcall RegOpenUserClassesRoot(ptr long long ptr) advapibase.RegOpenUserClassesRoot +@ stdcall RegOpenUserClassesRoot(ptr long long ptr) advapi32.RegOpenUserClassesRoot @ stdcall RegQueryInfoKeyA(long ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) @ stdcall RegQueryInfoKeyW(long ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) @ stdcall RegQueryValueExA(long str ptr ptr ptr ptr) @ stdcall RegQueryValueExW(long wstr ptr ptr ptr ptr) -@ stdcall RegRestoreKeyA(long str long) advapibase.RegRestoreKeyA -@ stdcall RegRestoreKeyW(long wstr long) advapibase.RegRestoreKeyW -@ stdcall RegSaveKeyExA(ptr str ptr long) advapibase.RegSaveKeyExA -@ stdcall RegSaveKeyExW(ptr str ptr long) advapibase.RegSaveKeyExW -@ stdcall RegSetKeySecurity(long long ptr) advapibase.RegSetKeySecurity +@ stdcall RegRestoreKeyA(long str long) advapi32.RegRestoreKeyA +@ stdcall RegRestoreKeyW(long wstr long) advapi32.RegRestoreKeyW +@ stdcall RegSaveKeyExA(ptr str ptr long) advapi32.RegSaveKeyExA +@ stdcall RegSaveKeyExW(ptr str ptr long) advapi32.RegSaveKeyExW +@ stdcall RegSetKeySecurity(long long ptr) advapi32.RegSetKeySecurity @ stdcall RegSetKeyValueA(long str str long ptr long) @ stdcall RegSetKeyValueW(long wstr wstr long ptr long) -@ stdcall RegSetValueExA(long str long long ptr long) advapibase.RegSetValueExA ;Need use native Windows RegSetValueExA from advapi32. Reactos and wine's version may corrupt and cause error on .Net Framework 4.5.1+. Error on .Net Framework: Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.at System.AddIn.Hosting.Program.Main(String[] args) -@ stdcall RegSetValueExW(long wstr long long ptr long) advapibase.RegSetValueExW -@ stdcall RegUnLoadKeyA(long str) advapibase.RegUnLoadKeyA -@ stdcall RegUnLoadKeyW(long wstr) advapibase.RegUnLoadKeyW -@ stdcall RevertToSelf() advapibase.RevertToSelf -@ stdcall RegisterTraceGuidsW(ptr ptr ptr long ptr wstr wstr ptr) advapibase.RegisterTraceGuidsW -@ stdcall SetAclInformation(ptr ptr long long) advapibase.SetAclInformation -@ stdcall SetFileSecurityA(str long ptr) advapibase.SetFileSecurityA -@ stdcall SetFileSecurityW(wstr long ptr) advapibase.SetFileSecurityW -@ stdcall SetKernelObjectSecurity(long long ptr) advapibase.SetKernelObjectSecurity -@ stdcall SetPrivateObjectSecurity(long ptr ptr ptr long) advapibase.SetPrivateObjectSecurity -@ stdcall SetSecurityDescriptorControl(ptr long long) advapibase.SetSecurityDescriptorControl -@ stdcall SetSecurityDescriptorDacl(ptr long ptr long) advapibase.SetSecurityDescriptorDacl -@ stdcall SetSecurityDescriptorGroup(ptr ptr long) advapibase.SetSecurityDescriptorGroup -@ stdcall SetSecurityDescriptorOwner(ptr ptr long) advapibase.SetSecurityDescriptorOwner -@ stdcall SetSecurityDescriptorSacl(ptr long ptr long) advapibase.SetSecurityDescriptorSacl -@ stdcall SetThreadToken(ptr ptr) advapibase.SetThreadToken -@ stdcall SetTokenInformation(long long ptr long) advapibase.SetTokenInformation +@ stdcall RegSetValueExA(long str long long ptr long) advapi32.RegSetValueExA ;Need use native Windows RegSetValueExA from advapi32. Reactos and wine's version may corrupt and cause error on .Net Framework 4.5.1+. Error on .Net Framework: Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.at System.AddIn.Hosting.Program.Main(String[] args) +@ stdcall RegSetValueExW(long wstr long long ptr long) advapi32.RegSetValueExW +@ stdcall RegUnLoadKeyA(long str) advapi32.RegUnLoadKeyA +@ stdcall RegUnLoadKeyW(long wstr) advapi32.RegUnLoadKeyW +@ stdcall RevertToSelf() advapi32.RevertToSelf +@ stdcall RegisterTraceGuidsW(ptr ptr ptr long ptr wstr wstr ptr) advapi32.RegisterTraceGuidsW +@ stdcall SetAclInformation(ptr ptr long long) advapi32.SetAclInformation +@ stdcall SetFileSecurityA(str long ptr) advapi32.SetFileSecurityA +@ stdcall SetFileSecurityW(wstr long ptr) advapi32.SetFileSecurityW +@ stdcall SetKernelObjectSecurity(long long ptr) advapi32.SetKernelObjectSecurity +@ stdcall SetPrivateObjectSecurity(long ptr ptr ptr long) advapi32.SetPrivateObjectSecurity +@ stdcall SetSecurityDescriptorControl(ptr long long) advapi32.SetSecurityDescriptorControl +@ stdcall SetSecurityDescriptorDacl(ptr long ptr long) advapi32.SetSecurityDescriptorDacl +@ stdcall SetSecurityDescriptorGroup(ptr ptr long) advapi32.SetSecurityDescriptorGroup +@ stdcall SetSecurityDescriptorOwner(ptr ptr long) advapi32.SetSecurityDescriptorOwner +@ stdcall SetSecurityDescriptorSacl(ptr long ptr long) advapi32.SetSecurityDescriptorSacl +@ stdcall SetThreadToken(ptr ptr) advapi32.SetThreadToken +@ stdcall SetTokenInformation(long long ptr long) advapi32.SetTokenInformation @ stdcall SystemFunction036(ptr long) -@ stdcall TraceEvent(int64 ptr) advapibase.TraceEvent -@ varargs TraceMessage(int64 long ptr long) advapibase.TraceMessage -@ stdcall TraceMessageVa(int64 long ptr long ptr) advapibase.TraceMessageVa -@ stdcall UnregisterTraceGuids(int64) advapibase.UnregisterTraceGuids +@ stdcall TraceEvent(int64 ptr) advapi32.TraceEvent +@ varargs TraceMessage(int64 long ptr long) advapi32.TraceMessage +@ stdcall TraceMessageVa(int64 long ptr long ptr) advapi32.TraceMessageVa +@ stdcall UnregisterTraceGuids(int64) advapi32.UnregisterTraceGuids #Import from Version @ stdcall VerQueryValueA(ptr str ptr ptr) diff --git a/wrappers/extensions/kernelex/locale.c b/wrappers/extensions/kernelex/locale.c index b8fc21796a..4771007bfd 100644 --- a/wrappers/extensions/kernelex/locale.c +++ b/wrappers/extensions/kernelex/locale.c @@ -3862,76 +3862,42 @@ INT WINAPI DECLSPEC_HOTPATCH WideCharToMultiByteInternal( UINT codepage, DWORD f return ret; } +// based on VxKex 1.1.2 +INT WINAPI GetUserDefaultGeoName( + OUT PWSTR Buffer, + IN INT BufferCch) +{ + GEOID GeoId; -// static const struct geo_id *find_geo_id_entry( GEOID id ) -// { - // int min = 0, max = geo_ids_count - 1; + // + // Validate parameters. + // - // while (min <= max) - // { - // int pos = (min + max) / 2; - // if (id < geo_ids[pos].id) max = pos - 1; - // else if (id > geo_ids[pos].id) min = pos + 1; - // else return &geo_ids[pos]; - // } - // return NULL; -// } + if (Buffer == NULL && BufferCch != 0) { + RtlSetLastWin32Error(ERROR_INVALID_PARAMETER); + return 0; + } -// INT WINAPI GetUserDefaultGeoName(LPWSTR geo_name, int count) -// { - // // const struct geoinfo *geoinfo; - // // WCHAR buffer[32]; - // // LSTATUS status; - // // DWORD size; - // // HKEY key; - - // // TRACE( "geo_name %p, count %d.\n", geo_name, count ); - - // // if (count && !geo_name) - // // { - // // SetLastError( ERROR_INVALID_PARAMETER ); - // // return 0; - // // } - // // if (!(status = RegOpenKeyExW( intl_key, L"Geo", 0, KEY_ALL_ACCESS, &key ))) - // // { - // // size = sizeof(buffer); - // // status = RegQueryValueExW( key, L"Name", NULL, NULL, (BYTE *)buffer, &size ); - // // RegCloseKey( key ); - // // } - // // if (status) - // // { - // // const struct geo_id *geo = find_geo_id_entry( GetUserGeoID( GEOCLASS_NATION )); - // // if (geo && geo->id != 39070) - // // lstrcpyW( buffer, geo->iso2 ); - // // else - // // lstrcpyW( buffer, L"001" ); - // // } - // // size = lstrlenW( buffer ) + 1; - // // if (count < size) - // // { - // // if (!count) - // // return size; - // // SetLastError( ERROR_INSUFFICIENT_BUFFER ); - // // return 0; - // // } - // // lstrcpyW( geo_name, buffer ); - // // return size; - // int i; - // int count = 0; - - // if (Locale == 0 || (lpName == NULL && cchName > 0) || cchName < 0) - // { - // SetLastError(ERROR_INVALID_PARAMETER); - // return 0; - // } - // for(i=0;i #include +#include WINE_DEFAULT_DEBUG_CHANNEL(kernel32file); @@ -487,6 +488,7 @@ GetDllList() } VOID +WINAPI LoadAppInitDlls() { szAppInit[0] = UNICODE_NULL; @@ -751,33 +753,130 @@ BOOL WINAPI K32EnumProcessModulesEx( HANDLE process, HMODULE *module, DWORD coun BOOL WINAPI GetWsChangesEx( - HANDLE process, - PPSAPI_WS_WATCH_INFORMATION_EX info, - PDWORD size + _In_ HANDLE hProcess, + _Out_writes_bytes_to_(*cb, *cb) PPSAPI_WS_WATCH_INFORMATION_EX lpWatchInfoEx, + _Inout_ PDWORD cb ) { - FIXME( "(%p, %p, %p)\n", process, info, size ); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; - // NTSTATUS Status; - - // Status = NtQueryInformationProcess( - // hProcess, - // ProcessWorkingSetWatchEx, - // (PVOID *)lpWatchInfo, - // cb, - // NULL - // ); - // if ( NT_SUCCESS(Status) ) { - // return TRUE; + // // FIXME( "(%p, %p, %p)\n", process, info, size ); + // // SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); + // // return FALSE; + + // PPSAPI_WS_WATCH_INFORMATION pWatchInfo = NULL; + // PPSAPI_WS_WATCH_INFORMATION pWatchInfoTerminated; + // PPSAPI_WS_WATCH_INFORMATION pWatchInfoMax; + // PPSAPI_WS_WATCH_INFORMATION pNewWatchInfo; + // DWORD cbWatchInfo = 1024 * sizeof(pWatchInfo[0]); + // HANDLE ProcessHeap = ((TEB*)NtCurrentTeb())->ProcessEnvironmentBlock->ProcessHeap; + // LSTATUS lStatus = ERROR_SUCCESS; + // int i ; + // DWORD ccWatchInfo; + // DWORD cbWatchInfoExRequest; + // DWORD cbBuffer; + + // for (;;) + // { + // if (pWatchInfo) + // { + // cbWatchInfo *= 2; + + // pNewWatchInfo = (PPSAPI_WS_WATCH_INFORMATION)HeapReAlloc(ProcessHeap, 0, pWatchInfo, cbWatchInfo); + + // if (!pNewWatchInfo) + // { + // lStatus = ERROR_OUTOFMEMORY; + // break; + // } + + // pWatchInfo = pNewWatchInfo; + // } + // else + // { + // pWatchInfo = (PPSAPI_WS_WATCH_INFORMATION)HeapAlloc(ProcessHeap, 0, cbWatchInfo); + // if (!pWatchInfo) + // { + // lStatus = ERROR_OUTOFMEMORY; + // break; + // } + // } + + // if (!GetWsChanges(hProcess, pWatchInfo, cbWatchInfo)) + // { + // lStatus = GetLastError(); + + // if (lStatus == ERROR_INSUFFICIENT_BUFFER) + // { + // continue; + + // } + // else + // { + // break; + // } + // } + + // //确定实际个数 + // pWatchInfoMax = (PPSAPI_WS_WATCH_INFORMATION)((byte*)pWatchInfo + cbWatchInfo); + // pWatchInfoTerminated = pWatchInfo; + // for (; pWatchInfoTerminated < pWatchInfoMax && pWatchInfoTerminated->FaultingPc != NULL; ++pWatchInfoTerminated); + + // ccWatchInfo = pWatchInfoTerminated - pWatchInfo; + + // cbWatchInfoExRequest = (ccWatchInfo + 1) * sizeof(lpWatchInfoEx[0]); + // if (cbWatchInfoExRequest > UINT32_MAX) + // { + // lStatus = ERROR_FUNCTION_FAILED; + // break; + // } + + // cbBuffer = *cb; + // *cb = (cbWatchInfoExRequest); + + // if (cbBuffer < cbWatchInfoExRequest) + // { + // lStatus = ERROR_INSUFFICIENT_BUFFER; + // break; + // } + + + // //复制到新缓冲区 + // for (i = 0; i != ccWatchInfo; ++i) + // { + // lpWatchInfoEx[i].BasicInfo = pWatchInfo[i]; + // lpWatchInfoEx[i].FaultingThreadId = 0; + // lpWatchInfoEx[i].Flags = 0; + // } + + // //插入终止标记 + // memset(&lpWatchInfoEx[ccWatchInfo], 0, sizeof(PSAPI_WS_WATCH_INFORMATION_EX));//lpWatchInfoEx[ccWatchInfo] = {0}; + + // lStatus = ERROR_SUCCESS; + // break; + // } + + // if (pWatchInfo) + // { + // HeapFree(ProcessHeap, 0, pWatchInfo); // } - // else { - // SetLastError( RtlNtStatusToDosError( Status ) ); - // return FALSE; + + // if (lStatus == ERROR_SUCCESS) + // { + // return TRUE; // } + // else + // { + // SetLastError(lStatus); + // return FALSE; + // } + NTSTATUS Status; + + Status = NtQueryInformationProcess(hProcess, ProcessWorkingSetWatchEx, lpWatchInfoEx, *cb, cb); //class is number 0x2A + if ( Status >= 0 ) //Also new to XP/2003. + return TRUE; + RtlSetLastWin32Error(RtlNtStatusToDosError(Status)); + return FALSE; } - int WINAPI LoadStringBaseExW( HINSTANCE hInstance, UINT uID, LPWSTR lpBuffer, int nBufferMax, INT unknown ) { if (unknown) { diff --git a/wrappers/extensions/kernelex/nls.c b/wrappers/extensions/kernelex/nls.c index f602481e84..ee504921b7 100644 --- a/wrappers/extensions/kernelex/nls.c +++ b/wrappers/extensions/kernelex/nls.c @@ -136,96 +136,6 @@ static inline WORD get_char_type( DWORD type, WCHAR ch ) return sort.ctypes[*ptr * 3 + type / 2]; } -// static void load_locale_nls(void) -// { - // struct - // { - // UINT ctypes; - // UINT unknown1; - // UINT unknown2; - // UINT unknown3; - // UINT locales; - // UINT charmaps; - // UINT geoids; - // UINT scripts; - // } *header; - // struct geo_header - // { - // WCHAR signature[4]; /* L"geo" */ - // UINT total_size; - // UINT ids_offset; - // UINT ids_count; - // UINT index_offset; - // UINT index_count; - // } *geo_header; - - // LARGE_INTEGER dummy; - // const USHORT *map_ptr; - // unsigned int i; - - // RtlGetLocaleFileMappingAddress( (void **)&header, &system_lcid, &dummy ); - // locale_table = (const NLS_LOCALE_HEADER *)((char *)header + header->locales); - // lcids_index = (const NLS_LOCALE_LCID_INDEX *)((char *)locale_table + locale_table->lcids_offset); - // lcnames_index = (const NLS_LOCALE_LCNAME_INDEX *)((char *)locale_table + locale_table->lcnames_offset); - // locale_strings = (const WCHAR *)((char *)locale_table + locale_table->strings_offset); - // geo_header = (struct geo_header *)((char *)header + header->geoids); - // geo_ids = (const struct geo_id *)((char *)geo_header + geo_header->ids_offset); - // geo_index = (const struct geo_index *)((char *)geo_header + geo_header->index_offset); - // geo_ids_count = geo_header->ids_count; - // geo_index_count = geo_header->index_count; - // map_ptr = (const USHORT *)((char *)header + header->charmaps); - // for (i = 0; i < NB_CHARMAPS; i++, map_ptr += *map_ptr) charmaps[i] = map_ptr + 1; -// } - -// static void load_sortdefault_nls(void) -// { - // const struct - // { - // UINT sortkeys; - // UINT casemaps; - // UINT ctypes; - // UINT sortids; - // } *header; - - // const WORD *ctype; - // const UINT *table; - // UINT i; - // SIZE_T size; - // const struct sort_compression *last_compr; - - // NtGetNlsSectionPtr( 9, 0, NULL, (void **)&header, &size ); - - // sort.keys = (UINT *)((char *)header + header->sortkeys); - // sort.casemap = (USHORT *)((char *)header + header->casemaps); - - // ctype = (WORD *)((char *)header + header->ctypes); - // sort.ctypes = ctype + 2; - // sort.ctype_idx = (BYTE *)ctype + ctype[1] + 2; - - // table = (UINT *)((char *)header + header->sortids); - // sort.version = table[0]; - // sort.guid_count = table[1]; - // sort.guids = (struct sortguid *)(table + 2); - - // table = (UINT *)(sort.guids + sort.guid_count); - // sort.exp_count = table[0]; - // sort.expansions = (struct sort_expansion *)(table + 1); - - // table = (UINT *)(sort.expansions + sort.exp_count); - // sort.compr_count = table[0]; - // sort.compressions = (struct sort_compression *)(table + 1); - // sort.compr_data = (WCHAR *)(sort.compressions + sort.compr_count); - - // last_compr = sort.compressions + sort.compr_count - 1; - // table = (UINT *)(sort.compr_data + last_compr->offset); - // for (i = 0; i < 7; i++) table += last_compr->len[i] * ((i + 5) / 2); - // table += 1 + table[0] / 2; /* skip multiple weights */ - // sort.jamo = (struct jamo_sort *)(table + 1); - - // locale_sorts = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, - // locale_table->nb_lcnames * sizeof(*locale_sorts) ); -// } - /************************************************************************** * NLS_GetLocaleNumber * diff --git a/wrappers/extensions/kernelex/path.c b/wrappers/extensions/kernelex/path.c index 2dbbda28a2..8fbf2d92eb 100644 --- a/wrappers/extensions/kernelex/path.c +++ b/wrappers/extensions/kernelex/path.c @@ -4918,7 +4918,7 @@ HRESULT WINAPI HashData(const unsigned char *src, DWORD src_len, unsigned char * return S_OK; } -DWORD GetTempPath2A( +DWORD WINAPI GetTempPath2A( DWORD BufferLength, LPSTR Buffer ) @@ -4926,7 +4926,7 @@ DWORD GetTempPath2A( return GetTempPathA(BufferLength, Buffer); } -DWORD GetTempPath2W( +DWORD WINAPI GetTempPath2W( DWORD BufferLength, LPWSTR Buffer ) diff --git a/wrappers/extensions/kernelex/powrmgmt.c b/wrappers/extensions/kernelex/powrmgmt.c index 9105541776..02f3ef2bfb 100644 --- a/wrappers/extensions/kernelex/powrmgmt.c +++ b/wrappers/extensions/kernelex/powrmgmt.c @@ -20,72 +20,83 @@ Revision History: #include +EXECUTION_STATE +WINAPI +SetThreadExecutionState(EXECUTION_STATE esFlags); + +#define ES_SYSTEM_REQUIRED ((DWORD)0x00000001) +#define ES_DISPLAY_REQUIRED ((DWORD)0x00000002) +#define ES_USER_PRESENT ((DWORD)0x00000004) +#define ES_AWAYMODE_REQUIRED ((DWORD)0x00000040) +#define ES_CONTINUOUS ((DWORD)0x80000000) + BOOL WINAPI PowerSetRequest( - HANDLE PowerRequest, + HANDLE PowerRequest, POWER_REQUEST_TYPE RequestType ) { - NTSTATUS status; // eax@1 - BOOL result; // eax@2 - HANDLE InputBuffer; // [sp+0h] [bp-Ch]@1 - - status = NtPowerInformation(PowerRequestAction, &InputBuffer, 0xCu, &RequestType, 0); - if ( !NT_SUCCESS(status) ) - { - BaseSetLastNTError(status); - result = FALSE; - } - else - { - result = TRUE; - } - return result; + //LONG dwQuantity; + //DWORD dwSize; + ULONG PreviousRequest; + + switch (RequestType) + { + case PowerRequestDisplayRequired: + PreviousRequest = SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED); + SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED | PreviousRequest); + return TRUE; + case PowerRequestSystemRequired: + PreviousRequest = SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); + SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | PreviousRequest); + return TRUE; + case PowerRequestAwayModeRequired: + PreviousRequest = SetThreadExecutionState(ES_CONTINUOUS | ES_AWAYMODE_REQUIRED); + SetThreadExecutionState(ES_CONTINUOUS | ES_AWAYMODE_REQUIRED | PreviousRequest); + return TRUE; + case PowerRequestExecutionRequired: + PreviousRequest = SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); + SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | PreviousRequest); + return TRUE; + } + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; } BOOL WINAPI PowerClearRequest( - HANDLE PowerRequest, + HANDLE PowerRequest, POWER_REQUEST_TYPE RequestType ) { - NTSTATUS status; // eax@1 - BOOL result; // eax@2 - HANDLE InputBuffer; // [sp+0h] [bp-Ch]@1 - - status = NtPowerInformation(PowerRequestAction, &InputBuffer, 0xCu, &RequestType, 0); - if ( !NT_SUCCESS(status) ) - { - BaseSetLastNTError(status); - result = FALSE; - } - else - { - result = TRUE; - } - return result; + // LONG dwQuantity; + // DWORD dwSize; + switch (RequestType) + { + case PowerRequestDisplayRequired: + SetThreadExecutionState(SetThreadExecutionState(ES_CONTINUOUS) & ~ES_DISPLAY_REQUIRED); + return TRUE; + case PowerRequestSystemRequired: + SetThreadExecutionState(SetThreadExecutionState(ES_CONTINUOUS) & ~ES_SYSTEM_REQUIRED); + return TRUE; + case PowerRequestAwayModeRequired: + SetThreadExecutionState(SetThreadExecutionState(ES_CONTINUOUS) & ~ES_AWAYMODE_REQUIRED); + return TRUE; + case PowerRequestExecutionRequired: + SetThreadExecutionState(SetThreadExecutionState(ES_CONTINUOUS) & ~ES_SYSTEM_REQUIRED); + return TRUE; + } + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; } HANDLE WINAPI PowerCreateRequest( - REASON_CONTEXT *context + PREASON_CONTEXT Context ) { - NTSTATUS status; // eax@1 - PVOID address = NULL; // ST10_4@4 - HANDLE proAddress; // eax@4 - HANDLE OutputBuffer; // [sp+0h] [bp-8h]@1 - - OutputBuffer = (HANDLE)-1; - if(status = NtPowerInformation(PowerRequestCreate, address, 0x1Cu, &OutputBuffer, 4u), status < 0) - BaseSetLastNTError(status); - if ( address ) - { - proAddress = GetProcessHeap(); - HeapFree(proAddress, 0, address); - } - return OutputBuffer; + return CreateSemaphoreA(NULL, 0, 1, NULL); } \ No newline at end of file diff --git a/wrappers/extensions/kernelex/process.c b/wrappers/extensions/kernelex/process.c index 9fccf1bd60..4ba54a572d 100644 --- a/wrappers/extensions/kernelex/process.c +++ b/wrappers/extensions/kernelex/process.c @@ -1657,327 +1657,6 @@ IsProcessorFeaturePresentInternal ( return resp; } -BOOL -WINAPI -CreateProcessInternalExW( - HANDLE hUserToken, - LPCWSTR lpApplicationName, - LPWSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation, - PHANDLE hRestrictedUserToken - ) -{ - BOOL resp; - static const WCHAR chromeexeW[] = {'c','h','r','o','m','e','.','e','x','e',0}; - static const WCHAR nosandboxW[] = {' ','-','-','n','o','-','s','a','n','d','b','o','x',0}; - //LPWSTR new_command_line; - - // // if(lpStartupInfo->cb == sizeof(STARTUPINFOEX)) - // if(dwCreationFlags & EXTENDED_STARTUPINFO_PRESENT) - // { - - // // LPSTARTUPINFOEX startupInfoEx = (LPSTARTUPINFOEX)lpStartupInfo; - - // // startupInfo.cb = sizeof(STARTUPINFOEX); - // // startupInfo.lpReserved = startupInfoEx->StartupInfo.lpReserved; - // // startupInfo.lpDesktop = startupInfoEx->StartupInfo.lpDesktop; - // // startupInfo.lpTitle = startupInfoEx->StartupInfo.lpTitle; - // // startupInfo.dwX = startupInfoEx->StartupInfo.dwX; - // // startupInfo.dwY = startupInfoEx->StartupInfo.dwY; - // // startupInfo.dwXSize = startupInfoEx->StartupInfo.dwXSize; - // // startupInfo.dwYSize = startupInfoEx->StartupInfo.dwYSize; - // // startupInfo.dwXCountChars = startupInfoEx->StartupInfo.dwXCountChars; - // // startupInfo.dwYCountChars = startupInfoEx->StartupInfo.dwYCountChars; - // // startupInfo.dwFillAttribute = startupInfoEx->StartupInfo.dwFillAttribute; - // // startupInfo.dwFlags = startupInfoEx->StartupInfo.dwFlags; - // // startupInfo.wShowWindow = startupInfoEx->StartupInfo.wShowWindow; - // // startupInfo.cbReserved2 = startupInfoEx->StartupInfo.cbReserved2; - // // startupInfo.lpReserved2 = startupInfoEx->StartupInfo.lpReserved2; - // // startupInfo.hStdInput = startupInfoEx->StartupInfo.hStdInput; - // // startupInfo.hStdOutput = startupInfoEx->StartupInfo.hStdOutput; - // // startupInfo.hStdError = startupInfoEx->StartupInfo.hStdError; - - // dwCreationFlags = DEBUG_PROCESS; - - // DbgPrint("CreateProcessInternalExW :: lpStartupInfo is STARTUPINFOEX structure\n"); - // }; - - // if (strstrW(lpApplicationName, chromeexeW)) - // { - // LPWSTR new_command_line; - - // new_command_line = HeapAlloc(GetProcessHeap(), 0, - // sizeof(WCHAR) * (strlenW(lpCommandLine) + strlenW(nosandboxW) + 1)); - - // if (!new_command_line) return FALSE; - - // strcpyW(new_command_line, lpCommandLine); - // strcatW(new_command_line, nosandboxW); - - // // TRACE("CrossOver hack changing command line to %s\n", debugstr_w(new_command_line)); - - // //if (tidy_cmdline != cmd_line) HeapFree( GetProcessHeap(), 0, tidy_cmdline ); - // lpCommandLine = new_command_line; - // } - - // if (strstrW(lpApplicationName, chromeexeW)) - // { - // new_command_line = lpCommandLine; - - // strcatW(new_command_line, nosandboxW); - - // lpCommandLine = new_command_line; - // } - - resp = CreateProcessInternalW(hUserToken, - lpApplicationName, - lpCommandLine, - lpProcessAttributes, - lpThreadAttributes, - bInheritHandles, - dwCreationFlags, - lpEnvironment, - lpCurrentDirectory, - lpStartupInfo,//&startupInfo, - lpProcessInformation, - hRestrictedUserToken); - - DbgPrint("CreateProcessInternalW :: returned value is %d\n", resp); - - return resp; - -} - -BOOL -WINAPI -CreateProcessExW( - LPCWSTR lpApplicationName, - LPWSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation -) -{ - STARTUPINFOW startupInfo; - BOOL resp; - //STARTUPINFO si; - //PROCESS_INFORMATION pi; - - startupInfo = *lpStartupInfo; - - // // if(lpStartupInfo->cb == sizeof(STARTUPINFOEX)) - // if(dwCreationFlags & EXTENDED_STARTUPINFO_PRESENT) - // { - // ZeroMemory(&si, sizeof(si)); // inspected - // si.cb = sizeof(si); - - // // The default ShowWindow flag is SW_SHOWDEFAULT which is what NT's CMD.EXE - // // uses. However, everything else uses SW_SHOWNORMAL, such as the shell, - // // task manager, VC's debugger, and 9x's COMMAND.COM. Since SW_SHOWNORMAL - // // is more common, that is what we want to simulate. - // si.dwFlags = STARTF_USESHOWWINDOW; - // si.wShowWindow = SW_SHOWNORMAL; - - // ZeroMemory(&pi, sizeof(pi)); // inspected - // // LPSTARTUPINFOEX startupInfoEx = (LPSTARTUPINFOEX)lpStartupInfo; - - // // startupInfo.cb = sizeof(STARTUPINFOEX); - // // startupInfo.lpReserved = startupInfoEx->StartupInfo.lpReserved; - // // startupInfo.lpDesktop = startupInfoEx->StartupInfo.lpDesktop; - // // startupInfo.lpTitle = startupInfoEx->StartupInfo.lpTitle; - // // startupInfo.dwX = startupInfoEx->StartupInfo.dwX; - // // startupInfo.dwY = startupInfoEx->StartupInfo.dwY; - // // startupInfo.dwXSize = startupInfoEx->StartupInfo.dwXSize; - // // startupInfo.dwYSize = startupInfoEx->StartupInfo.dwYSize; - // // startupInfo.dwXCountChars = startupInfoEx->StartupInfo.dwXCountChars; - // // startupInfo.dwYCountChars = startupInfoEx->StartupInfo.dwYCountChars; - // // startupInfo.dwFillAttribute = startupInfoEx->StartupInfo.dwFillAttribute; - // // startupInfo.dwFlags = startupInfoEx->StartupInfo.dwFlags; - // // startupInfo.wShowWindow = startupInfoEx->StartupInfo.wShowWindow; - // // startupInfo.cbReserved2 = startupInfoEx->StartupInfo.cbReserved2; - // // startupInfo.lpReserved2 = startupInfoEx->StartupInfo.lpReserved2; - // // startupInfo.hStdInput = startupInfoEx->StartupInfo.hStdInput; - // // startupInfo.hStdOutput = startupInfoEx->StartupInfo.hStdOutput; - // // startupInfo.hStdError = startupInfoEx->StartupInfo.hStdError; - - // // dwCreationFlags = DEBUG_PROCESS; - - // return CreateProcessW(NULL, - // lpCommandLine, - // NULL, - // NULL, - // FALSE, - // DEBUG_PROCESS, - // NULL, - // lpCurrentDirectory, - // &si, - // &pi); - - // DbgPrint("CreateProcessExW :: lpStartupInfo is STARTUPINFOEX structure\n"); - // } - - resp = CreateProcessW(lpApplicationName, - lpCommandLine, - lpProcessAttributes, - lpThreadAttributes, - bInheritHandles, - dwCreationFlags, - lpEnvironment, - lpCurrentDirectory, - lpStartupInfo,//&startupInfo, - lpProcessInformation); - - DbgPrint("CreateProcessW :: returned value is %d\n", resp); - - return resp; - -} - -BOOL -WINAPI -CreateProcessInternalExA( - HANDLE hUserToken, - LPCSTR lpApplicationName, - LPSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCSTR lpCurrentDirectory, - LPSTARTUPINFOA lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation, - PHANDLE hRestrictedUserToken -) -{ - // STARTUPINFOA startupInfo; - - BOOL resp; - - // // if(lpStartupInfo->cb == sizeof(STARTUPINFOEX)) - // if(dwCreationFlags & EXTENDED_STARTUPINFO_PRESENT) - // { - - // // LPSTARTUPINFOEX startupInfoEx = (LPSTARTUPINFOEX)lpStartupInfo; - - // // startupInfo.cb = sizeof(STARTUPINFOEX); - // // startupInfo.lpReserved = startupInfoEx->StartupInfo.lpReserved; - // // startupInfo.lpDesktop = startupInfoEx->StartupInfo.lpDesktop; - // // startupInfo.lpTitle = startupInfoEx->StartupInfo.lpTitle; - // // startupInfo.dwX = startupInfoEx->StartupInfo.dwX; - // // startupInfo.dwY = startupInfoEx->StartupInfo.dwY; - // // startupInfo.dwXSize = startupInfoEx->StartupInfo.dwXSize; - // // startupInfo.dwYSize = startupInfoEx->StartupInfo.dwYSize; - // // startupInfo.dwXCountChars = startupInfoEx->StartupInfo.dwXCountChars; - // // startupInfo.dwYCountChars = startupInfoEx->StartupInfo.dwYCountChars; - // // startupInfo.dwFillAttribute = startupInfoEx->StartupInfo.dwFillAttribute; - // // startupInfo.dwFlags = startupInfoEx->StartupInfo.dwFlags; - // // startupInfo.wShowWindow = startupInfoEx->StartupInfo.wShowWindow; - // // startupInfo.cbReserved2 = startupInfoEx->StartupInfo.cbReserved2; - // // startupInfo.lpReserved2 = startupInfoEx->StartupInfo.lpReserved2; - // // startupInfo.hStdInput = startupInfoEx->StartupInfo.hStdInput; - // // startupInfo.hStdOutput = startupInfoEx->StartupInfo.hStdOutput; - // // startupInfo.hStdError = startupInfoEx->StartupInfo.hStdError; - - // dwCreationFlags = DEBUG_PROCESS; - - // DbgPrint("CreateProcessInternalExA :: lpStartupInfo is STARTUPINFOEX structure\n"); - // } - - resp = CreateProcessInternalA(hUserToken, - lpApplicationName, - lpCommandLine, - lpProcessAttributes, - lpThreadAttributes, - bInheritHandles, - dwCreationFlags, - lpEnvironment, - lpCurrentDirectory, - lpStartupInfo,//&startupInfo, - lpProcessInformation, - hRestrictedUserToken); - - DbgPrint("CreateProcessInternalA :: returned value is %d\n", resp); - return resp; -} - -BOOL -WINAPI -CreateProcessExA( - LPCSTR lpApplicationName, - LPSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCSTR lpCurrentDirectory, - LPSTARTUPINFOA lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation -) -{ - // STARTUPINFOA startupInfo; - - BOOL resp; - - // if(lpStartupInfo->cb == sizeof(STARTUPINFOEX)) - //if(dwCreationFlags & EXTENDED_STARTUPINFO_PRESENT) - //{ - - // LPSTARTUPINFOEX startupInfoEx = (LPSTARTUPINFOEX)lpStartupInfo; - - // startupInfo.cb = sizeof(STARTUPINFOEX); - // startupInfo.lpReserved = startupInfoEx->StartupInfo.lpReserved; - // startupInfo.lpDesktop = startupInfoEx->StartupInfo.lpDesktop; - // startupInfo.lpTitle = startupInfoEx->StartupInfo.lpTitle; - // startupInfo.dwX = startupInfoEx->StartupInfo.dwX; - // startupInfo.dwY = startupInfoEx->StartupInfo.dwY; - // startupInfo.dwXSize = startupInfoEx->StartupInfo.dwXSize; - // startupInfo.dwYSize = startupInfoEx->StartupInfo.dwYSize; - // startupInfo.dwXCountChars = startupInfoEx->StartupInfo.dwXCountChars; - // startupInfo.dwYCountChars = startupInfoEx->StartupInfo.dwYCountChars; - // startupInfo.dwFillAttribute = startupInfoEx->StartupInfo.dwFillAttribute; - // startupInfo.dwFlags = startupInfoEx->StartupInfo.dwFlags; - // startupInfo.wShowWindow = startupInfoEx->StartupInfo.wShowWindow; - // startupInfo.cbReserved2 = startupInfoEx->StartupInfo.cbReserved2; - // startupInfo.lpReserved2 = startupInfoEx->StartupInfo.lpReserved2; - // startupInfo.hStdInput = startupInfoEx->StartupInfo.hStdInput; - // startupInfo.hStdOutput = startupInfoEx->StartupInfo.hStdOutput; - // startupInfo.hStdError = startupInfoEx->StartupInfo.hStdError; - - //dwCreationFlags = DEBUG_PROCESS; - - // DbgPrint("CreateProcessExA :: lpStartupInfo is STARTUPINFOEX structure\n"); - //} - - return CreateProcessA(lpApplicationName, - lpCommandLine, - lpProcessAttributes, - lpThreadAttributes, - bInheritHandles, - dwCreationFlags, - lpEnvironment, - lpCurrentDirectory, - lpStartupInfo,//&startupInfo, - lpProcessInformation); - - DbgPrint("CreateProcessA :: returned value is %d\n", resp); - - return resp; -} - /*********************************************************************** * CreateUmsCompletionList (KERNEL32.@) */ @@ -2177,48 +1856,38 @@ BOOL WINAPI IsWow64Process2(HANDLE hProcess, PUSHORT pProcessMachine, PUSHORT pN WOW64 and native platforms. */ { - BOOL Wow64Process; - - if(!pProcessMachine) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - if(!IsWow64Process(hProcess, &Wow64Process)) - { - return FALSE; - } - - if(!Wow64Process) - { - *pProcessMachine = IMAGE_FILE_MACHINE_UNKNOWN; - } - else - { - #ifdef _X86_ || _AMD64_ || _IA64_ - *pProcessMachine = IMAGE_FILE_MACHINE_I386; - #elif _ARM64_ || _ARM_ - *pProcessMachine = IMAGE_FILE_MACHINE_ARM; - #endif - // No other Windows architecture has WOW64. - - } - + BOOL Wow64Process; + BOOL Wow64CurrentProcess; + + if(!pProcessMachine) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if(!IsWow64Process(hProcess, &Wow64Process) || !IsWow64Process(GetCurrentProcess(), &Wow64CurrentProcess)) + return FALSE; + + #ifdef _AMD64_ + *pProcessMachine = Wow64Process ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386; // Yeaa.... + #else + if (Wow64CurrentProcess) + { + *pProcessMachine = Wow64CurrentProcess ? IMAGE_FILE_MACHINE_I386 : IMAGE_FILE_MACHINE_AMD64; // This is on a 64 bit system + } else { + *pProcessMachine = IMAGE_FILE_MACHINE_I386; // TODO: look at 16-bit process behavior (NTVDM) + } + #endif if(pNativeMachine) { - #ifdef _X86_ - *pNativeMachine = IMAGE_FILE_MACHINE_I386; - #elif _AMD64_ - *pNativeMachine = IMAGE_FILE_MACHINE_AMD64; - #elif _ARM_ - *pNativeMachine = IMAGE_FILE_MACHINE_ARM; - #elif _ARM64_ - *pNativeMachine = IMAGE_FILE_MACHINE_ARM64; - #endif - } - - return TRUE; + #ifdef _AMD64_ + *pNativeMachine = IMAGE_FILE_MACHINE_AMD64; // The true successor to IsWow64Process can only return AMD64. + #else + *pNativeMachine = Wow64CurrentProcess ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386; + #endif + } + + return TRUE; } int GetProcessUserModeExceptionPolicy(int a1) @@ -2323,24 +1992,6 @@ GetProcessInformation(HANDLE ProcessHandle, PROCESS_INFORMATION_CLASS ProcessInf } } -/*********************************************************************** - * GetSystemCpuSetInformation (kernelbase.@) - */ -BOOL WINAPI GetSystemCpuSetInformation(SYSTEM_CPU_SET_INFORMATION *info, ULONG buffer_length, ULONG *return_length, - HANDLE process, ULONG flags) -{ - //To implement - // if (flags) - // FIXME("Unsupported flags %#lx.\n", flags); - - // *return_length = 0; - - // return set_ntstatus( NtQuerySystemInformationEx( SystemCpuSetInformation, &process, sizeof(process), info, - // buffer_length, return_length )); - SetLastError(0); - return FALSE; -} - /*********************************************************************** * SetProcessDefaultCpuSets (kernelbase.@) */ diff --git a/wrappers/extensions/kernelex/psapi.c b/wrappers/extensions/kernelex/psapi.c index bcd82ea025..10a4015a96 100644 --- a/wrappers/extensions/kernelex/psapi.c +++ b/wrappers/extensions/kernelex/psapi.c @@ -20,25 +20,6 @@ Revision History: #include -// #include - -// #define WIN32_NO_STATUS -// #include -// #include -// #include -// #define NTOS_MODE_USER -// #include -// #include -// #include -// #include - -// #include - -// #include - -// #define NDEBUG -// #include - #define MAX_MODULES 0x2710 // Matches 10.000 modules #define INIT_MEMORY_SIZE 0x1000 // Matches 4kB @@ -138,7 +119,7 @@ FindDeviceDriver(IN PVOID ImageBase, /* * @implemented */ -static BOOL NTAPI +static BOOL WINAPI FindModule(IN HANDLE hProcess, IN HMODULE hModule OPTIONAL, OUT PLDR_DATA_TABLE_ENTRY Module) diff --git a/wrappers/extensions/kernelex/security.c b/wrappers/extensions/kernelex/security.c index ed0af17e0e..53c928a8f3 100644 --- a/wrappers/extensions/kernelex/security.c +++ b/wrappers/extensions/kernelex/security.c @@ -34,7 +34,7 @@ VOID BaseRestoreImpersonation(HANDLE ThreadInformation) } } -NTSTATUS __stdcall BaseRevertToSelf(void **a1) +NTSTATUS WINAPI BaseRevertToSelf(void **a1) { struct _TEB *Teb; // eax NTSTATUS Status; // ebx @@ -186,6 +186,7 @@ CreateBoundaryDescriptorA( } HANDLE +WINAPI CreatePrivateNamespaceW( LPSECURITY_ATTRIBUTES lpPrivateNamespaceAttributes, LPVOID lpBoundaryDescriptor, @@ -195,7 +196,8 @@ CreatePrivateNamespaceW( return NULL; } -HANDLE +HANDLE +WINAPI OpenPrivateNamespaceW( LPVOID lpBoundaryDescriptor, LPCWSTR lpAliasPrefix @@ -205,6 +207,7 @@ OpenPrivateNamespaceW( } BOOLEAN +WINAPI ClosePrivateNamespace( HANDLE Handle, ULONG Flags diff --git a/wrappers/extensions/kernelex/synch.c b/wrappers/extensions/kernelex/synch.c index 51d68a64a9..a27d20e9e5 100644 --- a/wrappers/extensions/kernelex/synch.c +++ b/wrappers/extensions/kernelex/synch.c @@ -144,49 +144,10 @@ CreateEventExW( ACCESS_MASK DesiredAccess ) { - return CreateEventW(lpEventAttributes, - dwFlags & CREATE_EVENT_MANUAL_RESET ? NotificationEvent : SynchronizationEvent, - (dwFlags & CREATE_EVENT_INITIAL_SET) != 0, - lpName); - // HANDLE Handle; // esi - // NTSTATUS Status; // eax - // OBJECT_ATTRIBUTES Obja; // [esp+4h] [ebp-20h] - // POBJECT_ATTRIBUTES pObja; - // LSA_UNICODE_STRING ObjectName; // [esp+1Ch] [ebp-8h] - - // if ( dwFlags & 0xFFFFFFFC ) - // { - // BaseSetLastNTError(STATUS_INVALID_PARAMETER_3); - // return NULL; - // } - // if ( ARGUMENT_PRESENT(lpName) ) - // { - // RtlInitUnicodeString(&ObjectName, lpName); - // pObja = BaseFormatObjectAttributes(&Obja, lpEventAttributes, &ObjectName); - // } - // else - // { - // pObja = BaseFormatObjectAttributes(&Obja, lpEventAttributes, NULL); - // } - // Status = NtCreateEvent( - // &Handle, - // DesiredAccess, - // pObja, - // dwFlags & CREATE_EVENT_MANUAL_RESET ? NotificationEvent : SynchronizationEvent, - // (BOOLEAN)dwFlags & CREATE_EVENT_INITIAL_SET); - // if ( NT_SUCCESS(Status) ) { - // if ( Status == STATUS_OBJECT_NAME_EXISTS ) { - // SetLastError(ERROR_ALREADY_EXISTS); - // } - // else { - // SetLastError(0); - // } - // return Handle; - // } - // else { - // BaseSetLastNTError(Status); - // return NULL; - // } + return CreateEventW(lpEventAttributes, + (dwFlags & CREATE_EVENT_MANUAL_RESET) != 0, + (dwFlags & CREATE_EVENT_INITIAL_SET) != 0, + lpName); } /*********************************************************************** @@ -232,34 +193,7 @@ CreateSemaphoreExW( return CreateSemaphoreW(sa, initial, max, - name); - // HANDLE ret = 0; - // UNICODE_STRING nameW; - // OBJECT_ATTRIBUTES attr; - // NTSTATUS status; - - // attr.Length = sizeof(attr); - // attr.RootDirectory = 0; - // attr.ObjectName = NULL; - // attr.Attributes = OBJ_OPENIF | ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0); - // attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL; - // attr.SecurityQualityOfService = NULL; - // if (name) - // { - // RtlInitUnicodeString( &nameW, name ); - // attr.ObjectName = &nameW; - // attr.RootDirectory = get_BaseNamedObjects_handle(); - // } - - // status = NtCreateSemaphore( &ret, access, &attr, initial, max ); - - // DbgPrint("CreateSemaphoreExW :: NtCreateSemaphore Status: %0x%08x\n", status); - - // if (status == STATUS_OBJECT_NAME_EXISTS) - // SetLastError( ERROR_ALREADY_EXISTS ); - // else - // SetLastError( RtlNtStatusToDosError(status) ); - // return ret; + name); } /*********************************************************************** @@ -319,41 +253,7 @@ CreateMutexExW( ) { // forward to CreateMutexW. - return CreateMutexW(lpMutexAttributes, (dwFlags & CREATE_MUTEX_INITIAL_OWNER) != 0, lpName); - // NTSTATUS Status; - // OBJECT_ATTRIBUTES Obja; - // POBJECT_ATTRIBUTES pObja; - // HANDLE Handle; - // UNICODE_STRING ObjectName; - - // if ( ARGUMENT_PRESENT(lpName) ) { - // RtlInitUnicodeString(&ObjectName,lpName); - // pObja = BaseFormatObjectAttributes(&Obja,lpMutexAttributes,&ObjectName); - // } - // else { - // pObja = BaseFormatObjectAttributes(&Obja,lpMutexAttributes,NULL); - // } - - // Status = NtCreateMutant( - // &Handle, - // dwDesiredAccess, - // pObja, - // (dwFlags & CREATE_MUTEX_INITIAL_OWNER) != 0 - // ); - - // if ( NT_SUCCESS(Status) ) { - // if ( Status == STATUS_OBJECT_NAME_EXISTS ) { - // SetLastError(ERROR_ALREADY_EXISTS); - // } - // else { - // SetLastError(0); - // } - // return Handle; - // } - // else { - // BaseSetLastNTError(Status); - // return NULL; - // } + return CreateMutexW(lpMutexAttributes, (dwFlags & CREATE_MUTEX_INITIAL_OWNER) != 0, lpName); } HANDLE @@ -690,70 +590,355 @@ BOOL getQueuedCompletionStatus( &lpEnt->lpOverlapped, dwMilliseconds); } -BOOL -WINAPI -GetQueuedCompletionStatusEx( - HANDLE CompletionPort, - LPOVERLAPPED_ENTRY lpCompletionPortEntries, - ULONG ulCount, - PULONG ulNumEntriesRemoved, - DWORD dwMilliseconds, - BOOL fAlertable -) -{ - int i = 0; - LPOVERLAPPED_ENTRY currentEntry; - NTSTATUS status; - DWORD ret; - LARGE_INTEGER TimeOut; - PLARGE_INTEGER pTimeOut; +void ConvertOverlappedToEntry(ULONG_PTR lpCompletionKey, LPOVERLAPPED src, LPOVERLAPPED_ENTRY dst) { + dst->lpOverlapped = src; + dst->dwNumberOfBytesTransferred = src->InternalHigh; + dst->lpCompletionKey = lpCompletionKey; + dst->Internal = 0; // we can use the 'Internal' for OCA purposes, but right now we don't do anything. +} + +//Generated by ChatGPT. Thank you AI +BOOL WINAPI GetQueuedCompletionStatusEx( + HANDLE hCompletionPort, + LPOVERLAPPED_ENTRY lpCompletionPortEntries, + ULONG ulCount, + PULONG ulNumEntriesRemoved, + DWORD dwMilliseconds, + BOOL bAlertable +) { + DWORD dwBytesTransferred; + ULONG_PTR lpCompletionKey; + LPOVERLAPPED lpOverlapped; + ULONG i; + BOOL _bRet; + DWORD _uStartTick; + DWORD _uResult; + DWORD _uTickSpan; + //OVERLAPPED_ENTRY _Entry; + DWORD kMaxSleepTime; - pTimeOut = BaseFormatTimeOut(&TimeOut, dwMilliseconds); + if (!lpCompletionPortEntries || ulCount == 0 || !ulNumEntriesRemoved) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + *ulNumEntriesRemoved = 0; - // validate arguments - if(!lpCompletionPortEntries - || !ulCount || !ulNumEntriesRemoved) { - RtlSetLastWin32Error(ERROR_INVALID_PARAMETER); - return FALSE; - } - - //DbgPrint("GetQueuedCompletionStatusEx: fAlertable"); - - // retrieve multiple entries - for(i = 0;i < ulCount; i++) - { - currentEntry = lpCompletionPortEntries+i; - status = currentEntry->Internal; - if (status == STATUS_PENDING) - { - if (!dwMilliseconds) - { - SetLastError( ERROR_IO_INCOMPLETE ); - return FALSE; - } - ret = WaitForSingleObjectEx( currentEntry->lpOverlapped->hEvent ? currentEntry->lpOverlapped->hEvent : CompletionPort, dwMilliseconds, fAlertable ); - if (ret == WAIT_FAILED) - return FALSE; - else if (ret) - { - SetLastError( ret ); - return FALSE; + //_Entry = lpCompletionPortEntries[0]; + + if (bAlertable) + { + kMaxSleepTime = 10; + // 使用 SleepEx 进行等待触发 APC + if (dwMilliseconds == INFINITE) + { + for (;;) + { + _bRet = GetQueuedCompletionStatus( + hCompletionPort, + &dwBytesTransferred, + &lpCompletionKey, + &lpOverlapped, + 0); + + if (_bRet) + { + lpCompletionPortEntries[*ulNumEntriesRemoved].lpCompletionKey = lpCompletionKey; + lpCompletionPortEntries[*ulNumEntriesRemoved].lpOverlapped = lpOverlapped; + lpCompletionPortEntries[*ulNumEntriesRemoved].dwNumberOfBytesTransferred = dwBytesTransferred; + (*ulNumEntriesRemoved)++; + break; + } + + if (GetLastError() != WAIT_TIMEOUT) + { + return FALSE; + } + + if (SleepEx(kMaxSleepTime, TRUE) == WAIT_IO_COMPLETION) + { + SetLastError(WAIT_IO_COMPLETION); + return FALSE; + } + } + } + else + { + // 使用 WaitForSingleObjectEx 进行等待触发 APC + _uStartTick = GetTickCount(); + for (;;) + { + _uResult = WaitForSingleObjectEx(hCompletionPort, dwMilliseconds, TRUE); + if (_uResult == WAIT_OBJECT_0) + { + _bRet = GetQueuedCompletionStatus( + hCompletionPort, + &dwBytesTransferred, + &lpCompletionKey, + &lpOverlapped, + dwMilliseconds + ); + // 完成端口有数据了 + // _bRet = GetQueuedCompletionStatus(CompletionPort, &_Entry.dwNumberOfBytesTransferred, &_Entry.lpCompletionKey, &_Entry.lpOverlapped, 0); + // if (_bRet) + // { + // *ulNumEntriesRemoved = 1; + // break; + // } + if (_bRet || lpOverlapped) { + lpCompletionPortEntries[*ulNumEntriesRemoved].lpCompletionKey = lpCompletionKey; + lpCompletionPortEntries[*ulNumEntriesRemoved].lpOverlapped = lpOverlapped; + lpCompletionPortEntries[*ulNumEntriesRemoved].dwNumberOfBytesTransferred = dwBytesTransferred; + (*ulNumEntriesRemoved)++; + + // Continue collecting if we haven't hit the desired count yet + if (*ulNumEntriesRemoved < ulCount) { + dwMilliseconds = 0; // Set timeout to zero after the first iteration + continue; + } + } + + if (GetLastError() != WAIT_TIMEOUT) + { + return FALSE; + } + + // 无限等待时无脑继续等即可。 + if (dwMilliseconds == INFINITE) + { + continue; + } + + // 计算剩余等待时间,如果剩余等待时间归零则返回 + _uTickSpan = GetTickCount() - _uStartTick; + if (_uTickSpan >= dwMilliseconds) + { + SetLastError(WAIT_TIMEOUT); + return FALSE; + } + dwMilliseconds -= _uTickSpan; + _uStartTick += _uTickSpan; + continue; + } + else if (_uResult == WAIT_IO_COMPLETION || _uResult == WAIT_TIMEOUT) + { + // 很奇怪,微软原版遇到 APC唤醒直接会设置 LastError WAIT_IO_COMPLETION + // 遇到超时,LastError WAIT_TIMEOUT(注意不是预期的 ERROR_TIMEOUT)不知道是故意还是有意。 + SetLastError(_uResult); + return FALSE; + } + else if (_uResult == WAIT_ABANDONED) + { + SetLastError(ERROR_ABANDONED_WAIT_0); + return FALSE; + } + else if (_uResult == WAIT_FAILED) + { + // LastError + return FALSE; + } + else + { + // LastError ??? + return FALSE; + } + } } - status = currentEntry->Internal; - //if (status == STATUS_PENDING) status = STATUS_SUCCESS; - if (status != WAIT_OBJECT_0) break; - } - if(!getQueuedCompletionStatus(CompletionPort, - currentEntry, dwMilliseconds)) break; - dwMilliseconds = 0; - } - - *ulNumEntriesRemoved = i; + return TRUE; + }else{ + for (i = 0; i < ulCount; i++) { + _bRet = GetQueuedCompletionStatus( + hCompletionPort, + &dwBytesTransferred, + &lpCompletionKey, + &lpOverlapped, + dwMilliseconds + ); + + if (_bRet || lpOverlapped) { + lpCompletionPortEntries[*ulNumEntriesRemoved].lpCompletionKey = lpCompletionKey; + lpCompletionPortEntries[*ulNumEntriesRemoved].lpOverlapped = lpOverlapped; + lpCompletionPortEntries[*ulNumEntriesRemoved].dwNumberOfBytesTransferred = dwBytesTransferred; + (*ulNumEntriesRemoved)++; + + // Continue collecting if we haven't hit the desired count yet + if (*ulNumEntriesRemoved < ulCount) { + dwMilliseconds = 0; // Set timeout to zero after the first iteration + continue; + } + return TRUE; // All requested entries were retrieved + } else { + // Error occurred or timeout + if (*ulNumEntriesRemoved > 0) { + return TRUE; // Partial success + } + return FALSE; // Complete failure + } + } + } - return TRUE; + return TRUE; } +// BOOL WINAPI GetQueuedCompletionStatusEx( + // HANDLE hCompletionPort, + // LPOVERLAPPED_ENTRY lpCompletionPortEntries, + // ULONG ulCount, + // PULONG ulNumEntriesRemoved, + // DWORD dwMilliseconds, + // BOOL bAlertable // This parameter is not present in Longhorn 4074 -> BOOM CRASH. I hope no pre reset targeted applications use this function. +// ) { + // DWORD dwBytesTransferred; + // ULONG_PTR lpCompletionKey; + // LPOVERLAPPED lpOverlapped; + // BOOL result; + + // if (bAlertable) + // DbgPrint("GetQueuedCompletionStatusEx: Called as alertable!\n"); + + // if (!lpCompletionPortEntries || ulCount == 0 || !ulNumEntriesRemoved) { + // SetLastError(ERROR_INVALID_PARAMETER); + // return FALSE; + // } + + // result = GetQueuedCompletionStatus( + // hCompletionPort, + // &dwBytesTransferred, + // &lpCompletionKey, + // &lpOverlapped, + // dwMilliseconds + // ); + // if (!result || !lpOverlapped) { + // *ulNumEntriesRemoved = 0; + // return FALSE; // All requested entries were retrieved + // } + // lpCompletionPortEntries[0].lpCompletionKey = lpCompletionKey; + // lpCompletionPortEntries[0].lpOverlapped = lpOverlapped; + // lpCompletionPortEntries[0].dwNumberOfBytesTransferred = dwBytesTransferred; + // *ulNumEntriesRemoved = 1; + // return TRUE; +// } + +// BOOL +// WINAPI +// GetQueuedCompletionStatusEx( + // HANDLE CompletionPort, + // LPOVERLAPPED_ENTRY lpCompletionPortEntries, + // ULONG ulCount, + // PULONG ulNumEntriesRemoved, + // DWORD dwMilliseconds, + // BOOL fAlertable +// ) +// { + // NTSTATUS Status; + // IO_STATUS_BLOCK IoStatus; + // ULONG_PTR CompletionKey; + // LARGE_INTEGER Time; + // PLARGE_INTEGER TimePtr; + // OVERLAPPED_ENTRY lpCompletionPortEntriesNew; + // OVERLAPPED_ENTRY lpCompletionPortEntry; + // int i; + + // for(i=0;ilpCompletionKey, + // (PVOID*)&lpCompletionPortEntries->lpOverlapped, + // &IoStatus, + // TimePtr); + // if (!(NT_SUCCESS(Status)) || (Status == STATUS_TIMEOUT)) + // { + // /* Clear out the overlapped output */ + // *lpOverlapped = NULL; + + // /* Check what kind of error we got */ + // if (Status == STATUS_TIMEOUT) + // { + // /* Timeout error is set directly since there's no conversion */ + // SetLastError(WAIT_TIMEOUT); + // } + // else + // { + // /* Any other error gets converted */ + // BaseSetLastNTError(Status); + // } + + // /* This is a failure case */ + // return FALSE; + // } + + // ConvertOverlappedToEntry(lpCompletionPortEntries->lpCompletionKey, &lpCompletionPortEntries->lpOverlapped, &lpCompletionPortEntry); + + // /* Check for error */ + // if (!NT_SUCCESS(IoStatus.Status)) + // { + // /* Convert and fail */ + // BaseSetLastNTError(IoStatus.Status); + // return FALSE; + // } + // lpCompletionPortEntries++; + // } + + // /* Return success */ + // return TRUE; + + + // int i = 0; + // LPOVERLAPPED_ENTRY currentEntry; + // NTSTATUS status; + // DWORD ret; + // LARGE_INTEGER TimeOut; + // PLARGE_INTEGER pTimeOut; + + // pTimeOut = BaseFormatTimeOut(&TimeOut, dwMilliseconds); + + // // validate arguments + // if(!lpCompletionPortEntries + // || !ulCount || !ulNumEntriesRemoved) { + // RtlSetLastWin32Error(ERROR_INVALID_PARAMETER); + // return FALSE; + // } + + // //DbgPrint("GetQueuedCompletionStatusEx: fAlertable"); + + // // retrieve multiple entries + // for(i = 0;i < ulCount; i++) + // { + // currentEntry = lpCompletionPortEntries+i; + // status = currentEntry->Internal; + // if (status == STATUS_PENDING) + // { + // if (!dwMilliseconds) + // { + // SetLastError( ERROR_IO_INCOMPLETE ); + // return FALSE; + // } + // ret = WaitForSingleObjectEx( currentEntry->lpOverlapped->hEvent ? currentEntry->lpOverlapped->hEvent : CompletionPort, dwMilliseconds, fAlertable ); + // if (ret == WAIT_FAILED) + // return FALSE; + // else if (ret) + // { + // SetLastError( ret ); + // return FALSE; + // } + + // status = currentEntry->Internal; + // //if (status == STATUS_PENDING) status = STATUS_SUCCESS; + // if (status != WAIT_OBJECT_0) break; + // } + // if(!getQueuedCompletionStatus(CompletionPort, + // currentEntry, dwMilliseconds)) break; + // dwMilliseconds = 0; + // } + + // *ulNumEntriesRemoved = i; + + // return TRUE; +//} + + /****************************************************************************** * WaitForDebugEventEx (kernelbase.@) */ @@ -883,86 +1068,6 @@ static inline VOID DeleteACVAListEntry( HeapFree(GetProcessHeap(), 0, lpListEntry); } -// WINBASEAPI BOOL WINAPI WaitOnAddress( - // IN volatile LPVOID lpAddr, // address to wait on - // IN LPVOID lpCompare, // pointer to location of old value of lpAddr - // IN SIZE_T cb, // number of bytes to compare - // IN DWORD dwMilliseconds OPTIONAL)// maximum number of milliseconds to wait -// { - // LPACVAHASHTABLEENTRY lpHashTableEntry = &WaitOnAddressHashTable[HashAddress(lpAddr)]; - // LPACVAHASHTABLEADDRESSLISTENTRY lpListEntry; - // DWORD dwLastError; - // BOOL bSuccess; - - // DbgPrint("(%p, %p, %Iu, %I32u)", lpAddr, lpCompare, cb, dwMilliseconds); - - // if (!lpAddr || !lpCompare) { - // SetLastError(ERROR_INVALID_PARAMETER); - // return FALSE; - // } else if (!(cb == 1 || cb == 2 || cb == 4 || cb == 8)) { - // SetLastError(ERROR_INVALID_PARAMETER); - // return FALSE; - // } - - // EnterCriticalSection(&lpHashTableEntry->Lock); - - // if (!CompareVolatileMemory(lpAddr, lpCompare, cb)) { - // LeaveCriticalSection(&lpHashTableEntry->Lock); - // SetLastError(ERROR_SUCCESS); - // return TRUE; - // } - - // lpListEntry = FindOrCreateACVAListEntryForAddress(lpHashTableEntry, lpAddr); - // lpListEntry->dwWaiters++; - // bSuccess = SleepConditionVariableCS(&lpListEntry->CVar, &lpHashTableEntry->Lock, dwMilliseconds); - // dwLastError = GetLastError(); - - // if (--lpListEntry->dwWaiters == 0) { - // DeleteACVAListEntry(lpListEntry); - // } - - // LeaveCriticalSection(&lpHashTableEntry->Lock); - // SetLastError(dwLastError); - // return bSuccess; -// } - -// WINBASEAPI VOID WINAPI WakeByAddressSingle( - // IN LPVOID lpAddr) -// { - // LPACVAHASHTABLEENTRY lpHashTableEntry = &WaitOnAddressHashTable[HashAddress(lpAddr)]; - // LPACVAHASHTABLEADDRESSLISTENTRY lpListEntry; - - // DbgPrint("(%p)", lpAddr); - - // EnterCriticalSection(&lpHashTableEntry->Lock); - // lpListEntry = FindACVAListEntryForAddress(lpHashTableEntry, lpAddr); - - // if (lpListEntry) { - // RtlWakeConditionVariable(&lpListEntry->CVar); - // } - - // LeaveCriticalSection(&lpHashTableEntry->Lock); -// } - -// WINBASEAPI VOID WINAPI WakeByAddressAll( - // IN LPVOID lpAddr) -// { - // LPACVAHASHTABLEENTRY lpHashTableEntry = &WaitOnAddressHashTable[HashAddress(lpAddr)]; - // LPACVAHASHTABLEADDRESSLISTENTRY lpListEntry; - - // DbgPrint("(%p)", lpAddr); - - // EnterCriticalSection(&lpHashTableEntry->Lock); - // lpListEntry = FindACVAListEntryForAddress(lpHashTableEntry, lpAddr); - - // if (lpListEntry) { - // RtlWakeAllConditionVariable(&lpListEntry->CVar); - // } - - // LeaveCriticalSection(&lpHashTableEntry->Lock); -// } - - // // This function is a wrapper around (Kex)RtlWaitOnAddress. // diff --git a/wrappers/extensions/kernelex/sysinfo.c b/wrappers/extensions/kernelex/sysinfo.c index c825b7a6eb..6c20d42f6b 100644 --- a/wrappers/extensions/kernelex/sysinfo.c +++ b/wrappers/extensions/kernelex/sysinfo.c @@ -99,4 +99,32 @@ SetSystemFileCacheSize( result = TRUE; } return result; +} + +// Required for Firefox 133. +BOOL WINAPI GetSystemCpuSetInformation( + PSYSTEM_CPU_SET_INFORMATION Information, + ULONG BufferLength, + PULONG ReturnedLength, + HANDLE Process, + ULONG Flags +) { + + if (ReturnedLength) + *ReturnedLength = sizeof(SYSTEM_CPU_SET_INFORMATION); + + if (BufferLength < sizeof(SYSTEM_CPU_SET_INFORMATION)) { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + + if (!Information) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + // CPU Sets are not a thing prior to Windows 10. Pretend that there is only a single "CPU Set". + memset(Information, 0, sizeof(SYSTEM_CPU_SET_INFORMATION)); // already fills out all the fields we need anyway + Information->Size = sizeof(SYSTEM_CPU_SET_INFORMATION); + return TRUE; } \ No newline at end of file diff --git a/wrappers/extensions/kernelex/thread.c b/wrappers/extensions/kernelex/thread.c index 67c582eb24..21cd0aa11d 100644 --- a/wrappers/extensions/kernelex/thread.c +++ b/wrappers/extensions/kernelex/thread.c @@ -558,7 +558,7 @@ FlsFree(DWORD dwFlsIndex) */ PVOID WINAPI -FlsGetValue(DWORD dwFlsIndex) +FlsGetValueInternal(DWORD dwFlsIndex) { PRTL_FLS_DATA pFlsData; @@ -787,28 +787,30 @@ GetThreadInformation( DWORD ThreadInformationSize ) { - BOOL result = FALSE; // esi@2 - NTSTATUS status; // eax@3 - - if ( ThreadInformationClass ) - { - BaseSetLastNTError(STATUS_INVALID_PARAMETER); - return FALSE; - } - else - { - status = NtQueryInformationProcess( - ProcessHandle, - ProcessDebugPort|0x20, - ThreadInformation, - ThreadInformationSize, - 0); - if ( NT_SUCCESS(status) ) - result = TRUE; - else - BaseSetLastNTError(status); - } - return result; + // BOOL result = FALSE; // esi@2 + // NTSTATUS status; // eax@3 + + // if ( ThreadInformationClass ) + // { + // BaseSetLastNTError(STATUS_INVALID_PARAMETER); + // return FALSE; + // } + // else + // { + // status = NtQueryInformationProcess( + // ProcessHandle, + // ProcessDebugPort|0x20, + // ThreadInformation, + // ThreadInformationSize, + // 0); + // if ( NT_SUCCESS(status) ) + // result = TRUE; + // else + // BaseSetLastNTError(status); + // } + // return result; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /*********************************************************************** @@ -1295,6 +1297,7 @@ SetThreadPriorityInternal( } LONG +WINAPI BasepCheckForReadOnlyResource( PVOID Va ) @@ -1581,4 +1584,18 @@ BOOL WINAPI SetThreadSelectedCpuSets(HANDLE thread, const ULONG *cpu_set_ids, UL FIXME( "thread %p, cpu_set_ids %p, count %lu stub.\n", thread, cpu_set_ids, count ); return TRUE; +} + +// For performance reasons... modern jemalloc will use these APIs if avaliable. +LPVOID WINAPI TlsGetValue2(DWORD dwTlsIndex) { + DWORD LastError = RtlGetLastWin32Error(); + LPVOID Result = TlsGetValue(dwTlsIndex); + RtlSetLastWin32Error(LastError); + return Result; +} +LPVOID WINAPI FlsGetValue2(DWORD dwFlsIndex) { + DWORD LastError = RtlGetLastWin32Error(); + LPVOID Result = FlsGetValue(dwFlsIndex); + RtlSetLastWin32Error(LastError); + return Result; } \ No newline at end of file diff --git a/wrappers/extensions/kernelex/xstate.c b/wrappers/extensions/kernelex/xstate.c index 6d87271ee6..78b6e30355 100644 --- a/wrappers/extensions/kernelex/xstate.c +++ b/wrappers/extensions/kernelex/xstate.c @@ -32,11 +32,11 @@ Revision History: DWORD64 WINAPI GetEnabledXStateFeatures() { - DWORD64 XState = 0; - - XState = 3; // bits 0 and 1 represent X87 and SSE respectively, which all AMD64 CPUs support. - - return XState; + DWORD64 XState = 1; // Always enabled, no matter what + if (IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE)) // Check for SSE + XState |= 2; + + return XState; } // BOOL WINAPI SetXStateFeaturesMask(PCONTEXT Context, DWORD64 FeatureMask) diff --git a/wrappers/extensions/ntext/CMakeLists.txt b/wrappers/extensions/ntext/CMakeLists.txt index 5c209b33a9..862460e340 100644 --- a/wrappers/extensions/ntext/CMakeLists.txt +++ b/wrappers/extensions/ntext/CMakeLists.txt @@ -37,6 +37,7 @@ list(APPEND SOURCE rtl/extfeatures.c rtl/exception.c rtl/heap.c + rtl/hooks.c rtl/imagedir.c rtl/interlck.c rtl/ldrrsrc.c @@ -82,7 +83,7 @@ if(MSVC) add_target_link_flags(ntext "/RELEASE") endif() -target_link_libraries(ntext libcntpr uuid ${PSEH_LIB}) +target_link_libraries(ntext uuid ${PSEH_LIB}) add_importlibs(ntext ntdll) diff --git a/wrappers/extensions/ntext/crypt.c b/wrappers/extensions/ntext/crypt.c index 555814cdec..589a002e5b 100644 --- a/wrappers/extensions/ntext/crypt.c +++ b/wrappers/extensions/ntext/crypt.c @@ -4,7 +4,7 @@ Copyright (c) 2018 Shorthorn Project Module Name: - alpc.c + crypt.c Abstract: diff --git a/wrappers/extensions/ntext/ldr/loader.c b/wrappers/extensions/ntext/ldr/loader.c index 5ccabf7538..e2d4f6b2a4 100644 --- a/wrappers/extensions/ntext/ldr/loader.c +++ b/wrappers/extensions/ntext/ldr/loader.c @@ -300,17 +300,27 @@ NTSTATUS WINAPI LdrUnregisterDllNotification( void *cookie ) /************************************************************************* * LdrSetDefaultDllDirectories (NTDLL.@) */ -NTSTATUS WINAPI LdrSetDefaultDllDirectories( ULONG flags ) +NTSTATUS WINAPI LdrSetDefaultDllDirectories( ULONG _fDirectoryFlags ) { /* LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR doesn't make sense in default dirs */ - const ULONG load_library_search_flags = (LOAD_LIBRARY_SEARCH_APPLICATION_DIR | - LOAD_LIBRARY_SEARCH_USER_DIRS | - LOAD_LIBRARY_SEARCH_SYSTEM32 | - LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + // const ULONG load_library_search_flags = (LOAD_LIBRARY_SEARCH_APPLICATION_DIR | + // LOAD_LIBRARY_SEARCH_USER_DIRS | + // LOAD_LIBRARY_SEARCH_SYSTEM32 | + // LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + + // if (!flags || (flags & ~load_library_search_flags)) + // return STATUS_INVALID_PARAMETER; + if (_fDirectoryFlags & LOAD_LIBRARY_SEARCH_DEFAULT_DIRS) + { + _fDirectoryFlags &= ~LOAD_LIBRARY_SEARCH_DEFAULT_DIRS; + _fDirectoryFlags |= LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32 | LOAD_LIBRARY_SEARCH_USER_DIRS; + } - if (!flags || (flags & ~load_library_search_flags)) - return STATUS_INVALID_PARAMETER; - default_search_flags = flags; + if (_fDirectoryFlags & ~(LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32 | LOAD_LIBRARY_SEARCH_USER_DIRS)) + { + return STATUS_INVALID_PARAMETER; + } + default_search_flags = _fDirectoryFlags; return STATUS_SUCCESS; } diff --git a/wrappers/extensions/ntext/main.h b/wrappers/extensions/ntext/main.h index 46b968e219..b04785e3de 100644 --- a/wrappers/extensions/ntext/main.h +++ b/wrappers/extensions/ntext/main.h @@ -1050,6 +1050,9 @@ typedef struct _SYNCITEM DWORD count; //共享计数 DWORD attr; //节点属性 RTL_SRWLOCK* lock; + + // 唤醒此任务的线程Id + volatile size_t uWakeupThreadId; } SYNCITEM; typedef size_t SYNCSTATUS; @@ -1151,6 +1154,11 @@ typedef struct __declspec(align(16)) _YY_CV_WAIT_BLOCK volatile size_t shareCount; volatile size_t flag; volatile PRTL_SRWLOCK SRWLock; + + // 以下成员YY-Thunks特有 + + // 唤醒此任务的线程Id + volatile size_t uWakeupThreadId; } YY_CV_WAIT_BLOCK; #if defined(_M_AMD64) diff --git a/wrappers/extensions/ntext/ntapi/ntapi.c b/wrappers/extensions/ntext/ntapi/ntapi.c index a05b5402b1..cbaffe557c 100644 --- a/wrappers/extensions/ntext/ntapi/ntapi.c +++ b/wrappers/extensions/ntext/ntapi/ntapi.c @@ -20,16 +20,20 @@ Revision History: #include +static NTSTATUS NTAPI NtLoadKeyToFixOffice2013Installer(POBJECT_ATTRIBUTES TargetKey, POBJECT_ATTRIBUTES SourceFile) { + return NtLoadKey(TargetKey, SourceFile); +} NTSTATUS NTAPI NtLoadKeyEx( - IN POBJECT_ATTRIBUTES TargetKey, - IN POBJECT_ATTRIBUTES SourceFile, - IN ULONG Flags, - IN HANDLE TrustClassKey + IN POBJECT_ATTRIBUTES TargetKey, + IN POBJECT_ATTRIBUTES SourceFile, + IN ULONG Flags, + IN HANDLE TrustClassKey ) { - return NtLoadKey(TargetKey, SourceFile); + DbgPrint("NtOpenKeyEx:: parameters ignored %i , %p\n", Flags, TrustClassKey); + return NtLoadKeyToFixOffice2013Installer(TargetKey, SourceFile); } NTSTATUS @@ -368,6 +372,13 @@ NtOpenTransaction( return STATUS_NOT_IMPLEMENTED; } +static +NTSTATUS +NTAPI +NtOpenKeyToFixOffice2013Installer(PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr) { + return NtOpenKey( retkey, access, attr); +} + NTSTATUS WINAPI NtOpenKeyEx( @@ -377,7 +388,8 @@ NtOpenKeyEx( ULONG options ) { - return NtOpenKey( retkey, access, attr); + DbgPrint("NtOpenKeyEx:: parameters ignored %i , %p\n", options, retkey); + return NtOpenKeyToFixOffice2013Installer( retkey, access, attr); } /************************************************************************** diff --git a/wrappers/extensions/ntext/ntext.spec b/wrappers/extensions/ntext/ntext.spec index da7a0a4e1f..88eaf659ce 100644 --- a/wrappers/extensions/ntext/ntext.spec +++ b/wrappers/extensions/ntext/ntext.spec @@ -68,11 +68,7 @@ @ stdcall LdrLoadAlternateResourceModule(ptr wstr) @ stdcall LdrLoadDll(wstr long ptr ptr) @ stdcall LdrLockLoaderLock(long ptr ptr) -@ stdcall LdrOpenImageFileOptionsKey(ptr long ptr) ; 5.2 SP1 and higher @ stdcall LdrProcessRelocationBlock(ptr long ptr long) -@ stdcall LdrQueryImageFileExecutionOptions(ptr str long ptr long ptr) -@ stdcall LdrQueryImageFileExecutionOptionsEx(ptr ptr long ptr long ptr long) -@ stdcall LdrQueryImageFileKeyOption(ptr ptr long ptr long ptr) ;implemented here @ stdcall LdrQueryProcessModuleInformation(ptr long ptr) @ stdcall LdrSetAppCompatDllRedirectionCallback(long long long) ntdll.LdrSetAppCompatDllRedirectionCallback @ stdcall LdrSetDllManifestProber(ptr) @@ -82,9 +78,9 @@ @ stdcall LdrUnloadDll(ptr) @ stdcall LdrUnlockLoaderLock(long long) @ stdcall LdrVerifyImageMatchesChecksum(ptr long long long) -@ extern NlsAnsiCodePage -@ extern NlsMbCodePageTag -@ extern NlsMbOemCodePageTag +@ stdcall NlsAnsiCodePage() ntdll.NlsAnsiCodePage +@ stdcall NlsMbCodePageTag() ntdll.NlsMbCodePageTag +@ stdcall NlsMbOemCodePageTag() ntdll.NlsMbOemCodePageTag @ stdcall NtAcceptConnectPort(ptr long ptr long long ptr) @ stdcall NtAccessCheck(ptr long long ptr ptr ptr ptr ptr) @ stdcall NtAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr) @@ -106,7 +102,6 @@ @ stdcall NtAreMappedFilesTheSame(ptr ptr) @ stdcall NtAssignProcessToJobObject(long long) @ stdcall NtCallbackReturn(ptr long long) -@ stdcall NtCancelDeviceWakeupRequest(ptr) @ stdcall NtCancelIoFile(long ptr) @ stdcall NtCancelTimer(long ptr) @ stdcall NtClearEvent(long) @@ -134,7 +129,6 @@ @ stdcall NtCreatePagingFile(long long long long) @ stdcall NtCreatePort(ptr ptr long long ptr) @ stdcall NtCreateProcess(ptr long ptr ptr long ptr ptr ptr) -@ stdcall NtCreateProcessEx(ptr long ptr ptr long ptr ptr ptr long) @ stdcall NtCreateProfile(ptr ptr ptr long long ptr long long long) ; CHECKME @ stdcall NtCreateSection(ptr long ptr ptr long long long) @ stdcall NtCreateSemaphore(ptr long ptr long long) @@ -143,7 +137,7 @@ @ stdcall NtCreateTimer(ptr long ptr long) @ stdcall NtCreateToken(ptr long ptr long ptr ptr ptr ptr ptr ptr ptr ptr ptr) @ stdcall NtCreateWaitablePort(ptr ptr long long long) -@ stdcall -arch=win32 NtCurrentTeb() _NtCurrentTeb +@ stdcall -arch=win32 NtCurrentTeb() @ stdcall NtDebugActiveProcess(ptr ptr) @ stdcall NtDebugContinue(ptr ptr long) @ stdcall NtDelayExecution(long ptr) @@ -285,10 +279,8 @@ @ stdcall NtReplyWaitReceivePort(ptr ptr ptr ptr) @ stdcall NtReplyWaitReceivePortEx(ptr ptr ptr ptr ptr) @ stdcall NtReplyWaitReplyPort(ptr ptr) -@ stdcall NtRequestDeviceWakeup(ptr) @ stdcall NtRequestPort(ptr ptr) @ stdcall NtRequestWaitReplyPort(ptr ptr ptr) -@ stdcall NtRequestWakeupLatency(long) @ stdcall NtResetEvent(long ptr) @ stdcall NtResetWriteWatch(long ptr long) @ stdcall NtRestoreKey(long long long) @@ -585,7 +577,6 @@ @ stdcall RtlGetElementGenericTableAvl(ptr long) @ stdcall RtlGetFrame() @ stdcall RtlGetFullPathName_U(wstr long ptr ptr) -@ stdcall RtlGetFullPathName_UstrEx(ptr ptr ptr ptr ptr ptr ptr ptr) @ stdcall RtlGetGroupSecurityDescriptor(ptr ptr ptr) @ stdcall RtlGetLastNtStatus() @ stdcall RtlGetLastWin32Error() @@ -602,10 +593,8 @@ @ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr) @ stdcall RtlGetSecurityDescriptorRMControl(ptr ptr) @ stdcall RtlGetSetBootStatusData(ptr long long ptr long long) -@ stdcall RtlGetThreadErrorMode() @ stdcall RtlGetUnloadEventTrace() ntdll.RtlGetUnloadEventTrace @ stdcall RtlGetUserInfoHeap(ptr long ptr ptr ptr) -@ stdcall RtlGetVersion(ptr) @ stdcall RtlHashUnicodeString(ptr long long ptr) @ stdcall RtlIdentifierAuthoritySid(ptr) @ stdcall RtlImageDirectoryEntryToData(long long long ptr) @@ -614,7 +603,6 @@ @ stdcall RtlImageRvaToVa(ptr long long ptr) @ stdcall RtlImpersonateSelf(long) @ stdcall RtlInitAnsiString(ptr str) -@ stdcall RtlInitAnsiStringEx(ptr str) @ stdcall RtlInitCodePageTable(ptr ptr) @ stdcall RtlInitNlsTables(ptr ptr ptr ptr) @ stdcall RtlInitString(ptr str) @@ -890,7 +878,6 @@ @ stdcall ZwAreMappedFilesTheSame(ptr ptr) NtAreMappedFilesTheSame @ stdcall ZwAssignProcessToJobObject(long long) NtAssignProcessToJobObject @ stdcall ZwCallbackReturn(ptr long long) -@ stdcall ZwCancelDeviceWakeupRequest(ptr) @ stdcall ZwCancelIoFile(long ptr) NtCancelIoFile @ stdcall ZwCancelTimer(long ptr) NtCancelTimer @ stdcall ZwClearEvent(long) NtClearEvent @@ -1071,10 +1058,8 @@ @ stdcall ZwReplyWaitReceivePort(ptr ptr ptr ptr) NtReplyWaitReceivePort @ stdcall ZwReplyWaitReceivePortEx(ptr ptr ptr ptr ptr) @ stdcall ZwReplyWaitReplyPort(ptr ptr) -@ stdcall ZwRequestDeviceWakeup(ptr) @ stdcall ZwRequestPort(ptr ptr) @ stdcall ZwRequestWaitReplyPort(ptr ptr ptr) -@ stdcall ZwRequestWakeupLatency(long) @ stdcall ZwResetEvent(long ptr) @ stdcall ZwResetWriteWatch(long ptr long) @ stdcall ZwRestoreKey(long long long) @@ -1186,38 +1171,38 @@ @ cdecl _ltoa(long ptr long) @ cdecl _ltow(long ptr long) @ cdecl _memccpy(ptr ptr long long) -@ cdecl _memicmp(str str long) +@ cdecl _memicmp(str str long) ntdll._memicmp @ cdecl -arch=x86_64 _setjmp(ptr ptr) @ cdecl -arch=x86_64 _setjmpex(ptr ptr) @ varargs _snprintf(ptr long str) @ varargs _snwprintf(ptr long wstr) @ cdecl _splitpath(str ptr ptr ptr ptr) -@ cdecl _strcmpi(str str) _stricmp +@ cdecl _strcmpi(str str) ntdll._strcmpi @ cdecl _stricmp(str str) -@ cdecl _strlwr(str) +@ cdecl _strlwr(str) ntdll._strlwr @ cdecl _strnicmp(str str long) @ cdecl _strupr(str) -@ cdecl _tolower(long) -@ cdecl _toupper(long) +@ cdecl _tolower(long) ntdll._tolower +@ cdecl _toupper(long) ntdll._toupper @ cdecl _ui64toa(double ptr long) @ cdecl _ui64tow(double ptr long) @ cdecl _ultoa(long ptr long) @ cdecl _ultow(long ptr long) -@ cdecl _vscwprintf(wstr ptr) +@ cdecl _vscwprintf(wstr ptr) ntdll._vscwprintf @ cdecl _vsnprintf(ptr long str ptr) @ cdecl _vsnwprintf(ptr long wstr ptr) -@ cdecl _wcsicmp(wstr wstr) -@ cdecl _wcslwr(wstr) -@ cdecl _wcsnicmp(wstr wstr long) -@ cdecl _wcstoui64(ptr ptr long) +@ cdecl _wcsicmp(wstr wstr) ntdll._wcsicmp +@ cdecl _wcslwr(wstr) ntdll._wcslwr +@ cdecl _wcsnicmp(wstr wstr long) ntdll._wcsnicmp +@ cdecl _wcstoui64(ptr ptr long) ntdll._wcstoui64 @ cdecl _wcsupr(wstr) @ cdecl _wtoi(wstr) @ cdecl _wtoi64(wstr) -@ cdecl _wtol(wstr) +@ cdecl _wtol(wstr) ntdll._wtol @ cdecl abs(long) @ cdecl -arch=i386,x86_64 atan(double) @ cdecl atoi(str) -@ cdecl atol(str) +@ cdecl atol(str) ntdll.atol @ cdecl bsearch(ptr ptr long long ptr) @ cdecl -arch=i386,x86_64 ceil(double) @ cdecl -arch=i386,x86_64 cos(double) @@ -1226,7 +1211,7 @@ @ cdecl isalnum(long) @ cdecl isalpha(long) @ cdecl iscntrl(long) -@ cdecl isdigit(long) +@ cdecl isdigit(long) ntdll.isdigit @ cdecl isgraph(long) @ cdecl islower(long) @ cdecl isprint(long) @@ -1255,53 +1240,55 @@ @ varargs sprintf(ptr str) @ cdecl -arch=i386,x86_64 sqrt(double) @ varargs sscanf(str str) -@ cdecl strcat(str str) -@ cdecl strchr(str long) -@ cdecl strcmp(str str) -@ cdecl strcpy(ptr str) +@ cdecl strcat(str str) ntdll.strcat +@ cdecl strchr(str long) ntdll.strchr +@ cdecl strcmp(str str) ntdll.strcmp +@ cdecl strcpy(ptr str) ntdll.strcpy @ cdecl strcspn(str str) -@ cdecl strlen(str) +@ cdecl strlen(str) ntdll.strlen @ cdecl strncat(str str long) -@ cdecl strncmp(str str long) -@ cdecl strncpy(ptr str long) -@ cdecl strpbrk(str str) -@ cdecl strrchr(str long) +@ cdecl strncmp(str str long) ntdll.strncmp +@ cdecl strncpy(ptr str long) ntdll.strncpy +@ cdecl strpbrk(str str) ntdll.strpbrk +@ cdecl strrchr(str long) ntdll.strrchr @ cdecl strspn(str str) -@ cdecl strstr(str str) +@ cdecl strstr(str str) ntdll.strstr @ cdecl strtol(str ptr long) @ cdecl strtoul(str ptr long) @ varargs swprintf(ptr wstr) @ cdecl -arch=i386,x86_64 tan(double) @ cdecl tolower(long) @ cdecl toupper(long) -@ cdecl towlower(long) +@ cdecl towlower(long) ntdll.towlower @ cdecl towupper(long) @ stdcall vDbgPrintEx(long long str ptr) @ stdcall vDbgPrintExWithPrefix(str long long str ptr) @ cdecl vsprintf(ptr str ptr) -@ cdecl wcscat(wstr wstr) -@ cdecl wcschr(wstr long) -@ cdecl wcscmp(wstr wstr) -@ cdecl wcscpy(ptr wstr) -@ cdecl wcscspn(wstr wstr) -@ cdecl wcslen(wstr) +@ cdecl wcscat(wstr wstr) ntdll.wcscat +@ cdecl wcschr(wstr long) ntdll.wcschr +@ cdecl wcscmp(wstr wstr) ntdll.wcscmp +@ cdecl wcscpy(ptr wstr) ntdll.wcscpy +@ cdecl wcscspn(wstr wstr) ntdll.wcscspn +@ cdecl wcslen(wstr) ntdll.wcslen @ cdecl wcsncat(wstr wstr long) -@ cdecl wcsncmp(wstr wstr long) -@ cdecl wcsncpy(ptr wstr long) -@ cdecl wcspbrk(wstr wstr) -@ cdecl wcsrchr(wstr long) +@ cdecl wcsncmp(wstr wstr long) ntdll.wcsncmp +@ cdecl wcsncpy(ptr wstr long) ntdll.wcsncpy +@ cdecl wcspbrk(wstr wstr) ntdll.wcspbrk +@ cdecl wcsrchr(wstr long) ntdll.wcsrchr @ cdecl wcsspn(wstr wstr) -@ cdecl wcsstr(wstr wstr) +@ cdecl wcsstr(wstr wstr) ntdll.wcsstr @ cdecl wcstol(wstr ptr long) @ cdecl wcstombs(ptr ptr long) @ cdecl wcstoul(wstr ptr long) #Hooks +@ stdcall NtCreateProcessEx(ptr long ptr ptr long ptr ptr ptr long) ;NtCreateProcessExInternal @ stdcall NtQueryInformationThread(long long ptr long ptr) NtQueryInformationThreadInternal @ stdcall NtQueryInformationToken(long long ptr long ptr) NtQueryInformationTokenInternal #Wrapper needed for Integrity Level Introduced on Vista @ stdcall NtQuerySection(long long long long long) NtQuerySectionInternal @ stdcall NtSetInformationProcess(long long long long) NtSetInformationProcessInternal @ stdcall NtSetInformationToken(long long ptr long) NtSetInformationTokenInternal +@ stdcall RtlGetVersion(ptr) RtlGetVersionInternal #Missing on XP and Server 2003 RTM @ stdcall -arch=i386 KiFastSystemCall() ntdll.KiFastSystemCall @@ -1346,7 +1333,7 @@ @ stdcall ZwApphelpCacheControl(long ptr) ntdll.ZwApphelpCacheControl @ stdcall ZwDeleteDriverEntry(long) ntdll.ZwDeleteDriverEntry @ stdcall ZwEnumerateDriverEntries(ptr ptr) ntdll.ZwEnumerateDriverEntries -@ stdcall ZwGetCurrentProcessorNumber() ntdll.ZwGetCurrentProcessorNumber +@ stdcall ZwGetCurrentProcessorNumber() NtGetCurrentProcessorNumber @ stdcall ZwLoadKeyEx(ptr ptr long ptr) ntdll.ZwLoadKeyEx @ stdcall ZwModifyDriverEntry(ptr) ntdll.ZwModifyDriverEntry @ stdcall ZwQueryDriverEntryOrder(ptr ptr) ntdll.ZwQueryDriverEntryOrder @@ -1356,7 +1343,14 @@ @ stdcall ZwWaitForMultipleObjects32(long ptr long long ptr) ntdll.ZwWaitForMultipleObjects32 #Missing XP +@ stdcall LdrOpenImageFileOptionsKey(ptr long ptr) ; 5.2 SP1 and higher +@ stdcall LdrQueryImageFileExecutionOptions(ptr str long ptr long ptr) ntdll.LdrQueryImageFileExecutionOptions +@ stdcall LdrQueryImageFileExecutionOptionsEx(ptr ptr long ptr long ptr long) +@ stdcall LdrQueryImageFileKeyOption(ptr ptr long ptr long ptr) ;implemented here @ stdcall RtlDosPathNameToRelativeNtPathName_U(ptr ptr ptr ptr) +@ stdcall RtlGetFullPathName_UstrEx(ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall RtlGetThreadErrorMode() +@ stdcall RtlInitAnsiStringEx(ptr str) @ stdcall RtlReleaseRelativeName(ptr) #Missing function on Server 2003 RTM @@ -1784,6 +1778,14 @@ @ stdcall WerReportSQMEvent() ntdll.WerReportSQMEvent @ stdcall WerReportWatsonEvent() ntdll.WerReportWatsonEvent +#Missing on Vista+ +@ stdcall NtCancelDeviceWakeupRequest(ptr) ntdll.NtCancelDeviceWakeupRequest +@ stdcall NtRequestDeviceWakeup(ptr) ntdll.NtRequestDeviceWakeup +@ stdcall NtRequestWakeupLatency(long) ntdll.NtRequestWakeupLatency +@ stdcall ZwCancelDeviceWakeupRequest(ptr) ntdll.ZwCancelDeviceWakeupRequest +@ stdcall ZwRequestDeviceWakeup(ptr) ntdll.ZwRequestDeviceWakeup +@ stdcall ZwRequestWakeupLatency(long) ntdll.ZwRequestWakeupLatency + #Vista Beta support Functions @ stdcall RtlpCreateProcessOSCultures(ptr) ntdll.RtlpCreateProcessOSCultures @ stdcall RtlRundownFlsData(ptr) ntdll.RtlRundownFlsData diff --git a/wrappers/extensions/ntext/rtl/avl.c b/wrappers/extensions/ntext/rtl/avl.c index 1b28c009d9..7edaf7ba94 100644 --- a/wrappers/extensions/ntext/rtl/avl.c +++ b/wrappers/extensions/ntext/rtl/avl.c @@ -16,8 +16,7 @@ Module Name: Revision History: ---*/ - +--*/ #define NDEBUG diff --git a/wrappers/extensions/ntext/rtl/boundary.c b/wrappers/extensions/ntext/rtl/boundary.c index 225ccfb5ed..d59c7043d0 100644 --- a/wrappers/extensions/ntext/rtl/boundary.c +++ b/wrappers/extensions/ntext/rtl/boundary.c @@ -1,19 +1,22 @@ - /* - * 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 - * - */ +/*++ + +Copyright (c) 2018 Shorthorn Project + +Module Name: + + boundary.c + +Abstract: + + Implement Boundary functions + +Author: + + Skulltrail 18-March-2018 + +Revision History: + +--*/ #define NDEBUG diff --git a/wrappers/extensions/ntext/rtl/cache.c b/wrappers/extensions/ntext/rtl/cache.c index 28f445fa67..73e2b97828 100644 --- a/wrappers/extensions/ntext/rtl/cache.c +++ b/wrappers/extensions/ntext/rtl/cache.c @@ -1,19 +1,22 @@ - /* - * 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 - * - */ +/*++ + +Copyright (c) 2018 Shorthorn Project + +Module Name: + + cache.c + +Abstract: + + Implement secure memory callback functions + +Author: + + Skulltrail 18-March-2018 + +Revision History: + +--*/ #define NDEBUG diff --git a/wrappers/extensions/ntext/rtl/context.c b/wrappers/extensions/ntext/rtl/context.c index 05e3574d1f..7a097811c6 100644 --- a/wrappers/extensions/ntext/rtl/context.c +++ b/wrappers/extensions/ntext/rtl/context.c @@ -4,7 +4,7 @@ Copyright (c) 2022 Shorthorn Project Module Name: - xstate.c + context.c Abstract: @@ -366,7 +366,6 @@ NTSTATUS NTAPI RtlGetExtendedContextLength2( ULONG context_flags, ULONG *length, return STATUS_SUCCESS; } - /********************************************************************** * RtlGetExtendedContextLength (NTDLL.@) */ diff --git a/wrappers/extensions/ntext/rtl/environ.c b/wrappers/extensions/ntext/rtl/environ.c index 8c2921995d..b148b33f40 100644 --- a/wrappers/extensions/ntext/rtl/environ.c +++ b/wrappers/extensions/ntext/rtl/environ.c @@ -1,20 +1,23 @@ - /* - * 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 - * - */ - +/*++ + +Copyright (c) 2022 Shorthorn Project + +Module Name: + + environment.c + +Abstract: + + This module implements Environment functions + +Author: + + Skulltrail 26-September-2022 + +Revision History: + +--*/ + #define NDEBUG #include diff --git a/wrappers/extensions/ntext/rtl/ldrrsrc.c b/wrappers/extensions/ntext/rtl/ldrrsrc.c index 4908a3ed04..8d455928b3 100644 --- a/wrappers/extensions/ntext/rtl/ldrrsrc.c +++ b/wrappers/extensions/ntext/rtl/ldrrsrc.c @@ -1,25 +1,23 @@ - /* - * 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 - * -Copyright (c) 2015 Microsoft Corporation - +/*++ + +Copyright (c) 2018 Shorthorn Project + Module Name: ldrrsrc.c - - */ + +Abstract: + + Implement Load Resources and Alternate Resources functions + +Author: + + Skulltrail 19-March-2018 + +Revision History: + +--*/ + #include #include @@ -68,23 +66,6 @@ PVOID LdrGetAlternateResourceModuleHandle( IN PVOID Module ) -/*++ - -Routine Description: - - This function gets the alternate resource module from the table - containing the handle. - -Arguments: - - Module - Module of which alternate resource module needs to loaded. - -Return Value: - - Handle of the alternate resource module. - ---*/ - { ULONG ModuleIndex; @@ -104,32 +85,10 @@ LdrpSetAlternateResourceModuleHandle( IN PVOID Module, IN PVOID AlternateModule ) - -/*++ - -Routine Description: - - This function records the handle of the base module and alternate - resource module in an array. - -Arguments: - - Module - The handle of the base module. - AlternateModule - The handle of the alternate resource module - -Return Value: - - TBD. - ---*/ - { PALT_RESOURCE_MODULE NewModules; if (AlternateResourceModules == NULL){ - // - // Allocate memory of initial size MEMBLOCKSIZE. - // NewModules = RtlAllocateHeap( RtlProcessHeap(), HEAP_ZERO_MEMORY, @@ -177,25 +136,6 @@ LdrLoadAlternateResourceModuleEx( IN PVOID Module, IN LPCWSTR PathToAlternateModule OPTIONAL ) - -/*++ - -Routine Description: - - This function does the acutally loading into memory of the alternate - resource module, or loads from the table if it was loaded before. - -Arguments: - - Module - The handle of the base module. - PathToAlternateModule - Optional path from which module is being loaded. - -Return Value: - - Handle to the alternate resource module. - ---*/ - { PVOID AlternateModule, DllBase; PLDR_DATA_TABLE_ENTRY Entry; @@ -226,10 +166,6 @@ Return Value: NtQueryDefaultUILanguage(&UILangId); - /*if (!LdrAlternateResourcesEnabled()) { - return NULL; - }*/ - RtlEnterCriticalSection(&LocaleCritSection); AlternateModule = LdrGetAlternateResourceModuleHandle(Module); @@ -239,28 +175,16 @@ Return Value: ImpersonateLangId = NtCurrentTeb()->IsImpersonating != 0 ? UILangId : 0; CustomLangId = UILangId; } - //AlternateModule = LdrGetAlternateResourceModuleHandle(Module, CustomLangId); if (AlternateModule == NO_ALTERNATE_RESOURCE_MODULE){ - // - // We tried to load this module before but failed. Don't try - // again in the future. - // RtlLeaveCriticalSection(&LocaleCritSection); return NULL; } else if (AlternateModule > 0){ - // - // We found the previously loaded match - // RtlLeaveCriticalSection(&LocaleCritSection); return AlternateModule; } if (ARGUMENT_PRESENT(PathToAlternateModule)){ - // - // Caller suplied path. - // - CopyCount = wcslen(PathToAlternateModule); for (p = (LPWSTR) PathToAlternateModule + CopyCount; @@ -277,19 +201,16 @@ Return Value: DllPathNameLength = (ULONG)(p - PathToAlternateModule) * sizeof(WCHAR); - wcscpy(//RtlCopyMemory( + memcpy( DllPathName, PathToAlternateModule - );//,DllPathNameLength); + ,DllPathNameLength); BaseDllName = p ; BaseDllNameLength = CopyCount * sizeof(WCHAR) - DllPathNameLength; } else{ - // - // Try to get full dll path from Ldr data table. - // Status = LdrFindEntryForAddress(Module, &Entry); if (!NT_SUCCESS( Status )){ goto error_exit; @@ -298,10 +219,10 @@ Return Value: DllPathNameLength = Entry->FullDllName.Length - Entry->BaseDllName.Length; - wcscpy(//RtlCopyMemory( + memcpy( DllPathName, - Entry->FullDllName.Buffer - );//,DllPathNameLength); + Entry->FullDllName.Buffer, + DllPathNameLength); BaseDllName = Entry->BaseDllName.Buffer; BaseDllNameLength = Entry->BaseDllName.Length; @@ -309,9 +230,6 @@ Return Value: DllPathName[DllPathNameLength / sizeof(WCHAR)] = UNICODE_NULL; - // - // Generate the langid directory like "0804\" - // if (!UILangId){ Status = NtQueryDefaultUILanguage( &UILangId ); if (!NT_SUCCESS( Status )) { @@ -333,9 +251,6 @@ Return Value: LangIdDir[CopyCount++] = L'\\'; LangIdDir[CopyCount++] = UNICODE_NULL; - // - // Get culture name by LANGID of CustomLangId - // for(i=0;iSize; } - } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { - Status = GetExceptionCode(); - } + // } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { + // Status = GetExceptionCode(); + // } return Status; } @@ -955,7 +871,7 @@ LdrpSearchResourceSection_U_by_name( { pos = (min + max) / 2; str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const char *)root + entry[pos].NameOffset); - res = _wcsnicmp( name, str->NameString, str->Length ); + res = wcsncmp( name, str->NameString, str->Length ); if (!res && namelen == str->Length) { if (!entry[pos].DataIsDirectory == !want_dir) @@ -1116,13 +1032,13 @@ LdrFindResource_U( _SEH2_TRY { - // if (ResourceInfo) - // { - // DbgPrint( "module %p type %lx name %lx lang %04lx level %lu\n", - // BaseAddress, ResourceInfo->Type, - // Level > 1 ? ResourceInfo->Name : 0, - // Level > 2 ? ResourceInfo->Language : 0, Level ); - // } + if (ResourceInfo) + { + DbgPrint( "module %p type %lx name %lx lang %04lx level %lu\n", + BaseAddress, ResourceInfo->Type, + Level > 1 ? ResourceInfo->Name : 0, + Level > 2 ? ResourceInfo->Language : 0, Level ); + } status = LdrpSearchResourceSection_U( BaseAddress, ResourceInfo, Level, &res, FALSE ); if (NT_SUCCESS(status)) @@ -1151,13 +1067,13 @@ LdrFindResourceEx_U( _SEH2_TRY { - // if (ResourceInfo) - // { - // DbgPrint( "module %p type %lx name %lx lang %04lx level %lu\n", - // BaseAddress, ResourceInfo->Type, - // Level > 1 ? ResourceInfo->Name : 0, - // Level > 2 ? ResourceInfo->Language : 0, Level ); - // } + if (ResourceInfo) + { + DbgPrint( "module %p type %lx name %lx lang %04lx level %lu\n", + BaseAddress, ResourceInfo->Type, + Level > 1 ? ResourceInfo->Name : 0, + Level > 2 ? ResourceInfo->Language : 0, Level ); + } status = LdrpSearchResourceSection_U( BaseAddress, ResourceInfo, Level, &res, FALSE ); if (NT_SUCCESS(status)) @@ -1186,13 +1102,13 @@ LdrFindResourceDirectory_U( _SEH2_TRY { - // if (info) - // { - // DbgPrint( "module %p type %ws name %ws lang %04lx level %lu\n", - // BaseAddress, (LPCWSTR)info->Type, - // level > 1 ? (LPCWSTR)info->Name : L"", - // level > 2 ? info->Language : 0, level ); - // } + if (info) + { + DbgPrint( "module %p type %ws name %ws lang %04lx level %lu\n", + BaseAddress, (LPCWSTR)info->Type, + level > 1 ? (LPCWSTR)info->Name : L"", + level > 2 ? info->Language : 0, level ); + } status = LdrpSearchResourceSection_U( BaseAddress, info, level, &res, TRUE ); if (NT_SUCCESS(status)) diff --git a/wrappers/extensions/ntext/rtl/synch.c b/wrappers/extensions/ntext/rtl/synch.c index 5ce47e8d71..1532cc8493 100644 --- a/wrappers/extensions/ntext/rtl/synch.c +++ b/wrappers/extensions/ntext/rtl/synch.c @@ -71,7 +71,7 @@ typedef struct _ADDRESS_WAIT_BLOCK struct _ADDRESS_WAIT_BLOCK* back; // 它是前驱 struct _ADDRESS_WAIT_BLOCK* notify; - // 似乎指向Root,但是Root时才指向自己,其余情况为 nullptr,这是一种安全性? + // 似乎指向Root,但是Root时才指向自己,其余情况为 NULL,这是一种安全性? struct _ADDRESS_WAIT_BLOCK* next; volatile long flag; } ADDRESS_WAIT_BLOCK; @@ -129,6 +129,56 @@ RtlpInitializeWaitOnAddressKeyedEvent( RTL_RUN_ONCE *once, void *param, void **c } +static LARGE_INTEGER* __fastcall NtFormatTimeOut(LARGE_INTEGER* Timeout, DWORD dwMilliseconds) +{ + if (dwMilliseconds == INFINITE) + return NULL; + + Timeout->QuadPart = -10000ll * dwMilliseconds; + + return Timeout; +} + +static NTSTATUS NTAPI SecondWaitWorkaroundNtWaitForKeyedEvent( + IN HANDLE KeyedEventHandle, + IN YY_CV_WAIT_BLOCK* Key, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Timeout OPTIONAL +) +{ + NTSTATUS Status; + // 目前只有Windows XP收到报告说会卡死,所以我们这里判断一下 + if (Timeout == NULL)// && NtCurrentTeb()->ProcessEnvironmentBlock->OSMajorVersion < 6) + { + LARGE_INTEGER _nTimeOut; + NtFormatTimeOut(&_nTimeOut, 0); + for (; Key->uWakeupThreadId == 0;) + { + Status = NtWaitForKeyedEvent(KeyedEventHandle, (PVOID)Key, Alertable, &_nTimeOut); + if (Status != STATUS_TIMEOUT) + return STATUS_TIMEOUT; + } + + // 等5毫秒应该足够唤醒线程调用Release了 + // 这里只是经验假设,可能不能彻底规避问题。但是正常情况下应该足以缓解死等问题。 + NtWaitForKeyedEvent(KeyedEventHandle, Key, Alertable, NtFormatTimeOut(&_nTimeOut, 5)); + return STATUS_SUCCESS; + } + return NtWaitForKeyedEvent(KeyedEventHandle, Key, Alertable, Timeout); +} + +static NTSTATUS NTAPI SecondWaitWorkaroundNtReleaseKeyedEvent( + IN HANDLE KeyedEventHandle, + IN YY_CV_WAIT_BLOCK* Key, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Timeout OPTIONAL +) +{ + InterlockedExchange((volatile long*)&Key->uWakeupThreadId, HandleToUlong(NtCurrentTeb()->ClientId.UniqueThread)); + return NtReleaseKeyedEvent(KeyedEventHandle, Key, Alertable, Timeout); +} + + static ULONG_PTR* GetBlockByWaitOnAddressHashTable(LPVOID Address) { static volatile ULONG_PTR WaitOnAddressHashTable[128]; @@ -141,7 +191,7 @@ static ULONG_PTR* GetBlockByWaitOnAddressHashTable(LPVOID Address) VOID InitializeGlobalKeyedEventHandle() { HANDLE KeyedEventHandle; - //Windows XP等平台则 使用系统自身的 CritSecOutOfMemoryEvent,Vista或者更高平台 我们直接返回 nullptr 即可。 + //Windows XP等平台则 使用系统自身的 CritSecOutOfMemoryEvent,Vista或者更高平台 我们直接返回 NULL 即可。 if (GlobalKeyedEventHandle == NULL) { const wchar_t Name[] = L"\\KernelObjects\\CritSecOutOfMemoryEvent"; @@ -1065,8 +1115,7 @@ void NTAPI RtlReleaseSRWLockShared(RTL_SRWLOCK* SRWLock) BOOL NTAPI RtlTryAcquireSRWLockExclusive(RTL_SRWLOCK* SRWLock) { - BOOL IsLocked=InterlockedBitTestAndSet((LONG*)SRWLock,SRW_HOLD_BIT); - return !(IsLocked==TRUE); + return !(InterlockedBitTestAndSet((LONG*)SRWLock,SRW_HOLD_BIT)==TRUE); } BOOL NTAPI RtlTryAcquireSRWLockShared(RTL_SRWLOCK* SRWLock) @@ -1132,7 +1181,7 @@ static BOOL __fastcall RtlpQueueWaitBlockToSRWLock(YY_CV_WAIT_BLOCK* pBolck, RTL for (;;) { - Current = *(volatile long*)SRWLock; + Current = *(volatile size_t*)SRWLock; if ((Current & 0x1) == 0) break; @@ -1169,7 +1218,7 @@ static BOOL __fastcall RtlpQueueWaitBlockToSRWLock(YY_CV_WAIT_BLOCK* pBolck, RTL } //清泠 发现的Bug,我们应该返回 TRUE,减少必要的内核等待。 - if (InterlockedCompareExchange((volatile long*)SRWLock, New, Current) == Current) + if ((size_t)InterlockedCompareExchangePointer((void *volatile *)SRWLock, (volatile long*)New, (volatile long*)Current) == Current) return TRUE; RtlBackoff(&backoff); @@ -1200,7 +1249,7 @@ static void __fastcall RtlpWakeConditionVariable(RTL_CONDITION_VARIABLE *Conditi if ((ConditionVariableStatus & 0x7) == 0x7) { - ConditionVariableStatus = InterlockedExchange((volatile long*)ConditionVariable, 0); + ConditionVariableStatus = (size_t)InterlockedExchangePointer((void *volatile *)ConditionVariable, 0); *ppInsert = YY_CV_GET_BLOCK(ConditionVariableStatus); @@ -1220,7 +1269,7 @@ static void __fastcall RtlpWakeConditionVariable(RTL_CONDITION_VARIABLE *Conditi if (MaxWakeCount <= Count) { - LastStatus = InterlockedCompareExchange((volatile long*)ConditionVariable, (size_t)(pWaitBlock), ConditionVariableStatus); + LastStatus = (size_t)InterlockedCompareExchangePointer((void *volatile *)ConditionVariable, (volatile long*)(pWaitBlock), (volatile long*)ConditionVariableStatus); if (LastStatus == ConditionVariableStatus) { @@ -1252,7 +1301,7 @@ static void __fastcall RtlpWakeConditionVariable(RTL_CONDITION_VARIABLE *Conditi if (MaxWakeCount <= Count) { - LastStatus = InterlockedCompareExchange((volatile long*)ConditionVariable, (size_t)(pWaitBlock), ConditionVariableStatus); + LastStatus = (size_t)InterlockedCompareExchangePointer((void *volatile *)ConditionVariable, (volatile long*)(pWaitBlock), (volatile long*)ConditionVariableStatus); if (LastStatus == ConditionVariableStatus) { @@ -1263,7 +1312,7 @@ static void __fastcall RtlpWakeConditionVariable(RTL_CONDITION_VARIABLE *Conditi } else { - LastStatus = InterlockedCompareExchange((volatile long*)ConditionVariable, 0, ConditionVariableStatus); + LastStatus = (size_t)InterlockedCompareExchangePointer((void *volatile *)ConditionVariable, (volatile long*)0, (volatile long*)ConditionVariableStatus); if (LastStatus == ConditionVariableStatus) @@ -1287,7 +1336,7 @@ static void __fastcall RtlpWakeConditionVariable(RTL_CONDITION_VARIABLE *Conditi { if (pWake->SRWLock == NULL || RtlpQueueWaitBlockToSRWLock(pWake, pWake->SRWLock, (pWake->flag >> 2) & 0x1) == FALSE) { - NtReleaseKeyedEvent(GlobalKeyedEventHandle, pWake, 0, NULL); + SecondWaitWorkaroundNtReleaseKeyedEvent(GlobalKeyedEventHandle, pWake, 0, NULL); } } @@ -1306,7 +1355,7 @@ RtlWakeConditionVariable( size_t Current; size_t Last; - Current = *(volatile long*)ConditionVariable; + Current = *(volatile size_t*)ConditionVariable; for (; Current; Current = Last) { @@ -1317,13 +1366,13 @@ RtlWakeConditionVariable( return; } - Last = InterlockedCompareExchange((volatile long*)ConditionVariable, Current + 1, Current); + Last = (size_t)InterlockedCompareExchangePointer((void *volatile *)ConditionVariable, (volatile long*)(Current + 1), (volatile long*)Current); if (Last == Current) return; } else { - Last = InterlockedCompareExchange((volatile long*)ConditionVariable, Current | 0x8, Current); + Last = (size_t)InterlockedCompareExchangePointer((void *volatile *)ConditionVariable, (volatile long*)(Current | 0x8), (volatile long*)Current); if (Last == Current) { RtlpWakeConditionVariable(ConditionVariable, Current + 8, 1); @@ -1339,7 +1388,7 @@ RtlWakeAllConditionVariable( _Inout_ RTL_CONDITION_VARIABLE *ConditionVariable ) { - size_t Current = *(volatile long*)ConditionVariable; + size_t Current = (size_t)ConditionVariable; size_t Last; YY_CV_WAIT_BLOCK* pBlock; YY_CV_WAIT_BLOCK* Tmp; @@ -1348,13 +1397,13 @@ RtlWakeAllConditionVariable( { if (Current & 0x8) { - Last = InterlockedCompareExchange((volatile long*)ConditionVariable, Current | 0x7, Current); + Last = (size_t)InterlockedCompareExchangePointer((void *volatile *)ConditionVariable, (volatile long*)(Current | 0x7), (volatile long*)Current); if (Last == Current) return; } else { - Last = InterlockedCompareExchange((volatile long*)ConditionVariable, 0, Current); + Last = (size_t)InterlockedCompareExchangePointer((void *volatile *)ConditionVariable, (volatile long*)0, (volatile long*)Current); if (Last == Current) { @@ -1364,7 +1413,7 @@ RtlWakeAllConditionVariable( if (!InterlockedBitTestAndReset((volatile LONG*)&pBlock->flag, 1)) { - NtReleaseKeyedEvent(GlobalKeyedEventHandle, pBlock, FALSE, NULL); + SecondWaitWorkaroundNtReleaseKeyedEvent(GlobalKeyedEventHandle, pBlock, FALSE, NULL); } pBlock = Tmp; @@ -1378,43 +1427,43 @@ RtlWakeAllConditionVariable( static void __fastcall RtlpOptimizeConditionVariableWaitList(RTL_CONDITION_VARIABLE *ConditionVariable, size_t ConditionVariableStatus) { - YY_CV_WAIT_BLOCK *pWaitBlock; - YY_CV_WAIT_BLOCK *pItem; - YY_CV_WAIT_BLOCK *temp; - size_t LastStatus; - - for (;;) - { - pWaitBlock = YY_CV_GET_BLOCK(ConditionVariableStatus); - pItem = pWaitBlock; - - for (; pItem->notify == NULL;) - { - temp = pItem; - pItem = pItem->back; - pItem->next = temp; - } + YY_CV_WAIT_BLOCK *pWaitBlock; + YY_CV_WAIT_BLOCK *pItem; + YY_CV_WAIT_BLOCK *temp; + size_t LastStatus; + + for (;;) + { + pWaitBlock = YY_CV_GET_BLOCK(ConditionVariableStatus); + pItem = pWaitBlock; - pWaitBlock->notify = pItem->notify; + for (; pItem->notify == NULL;) + { + temp = pItem; + pItem = pItem->back; + pItem->next = temp; + } - LastStatus = InterlockedCompareExchange((volatile long*)ConditionVariable, (size_t)(pWaitBlock), ConditionVariableStatus); + pWaitBlock->notify = pItem->notify; - if (LastStatus == ConditionVariableStatus) - break; + LastStatus = (size_t)InterlockedCompareExchangePointer((void *volatile *)ConditionVariable, (volatile long*)pWaitBlock, (volatile long*)ConditionVariableStatus); - ConditionVariableStatus = LastStatus; + if (LastStatus == ConditionVariableStatus) + return; - if (ConditionVariableStatus & 7) - { - RtlpWakeConditionVariable(ConditionVariable, ConditionVariableStatus, 0); - return; - } - } + if (LastStatus & 7) + { + RtlpWakeConditionVariable(ConditionVariable, LastStatus, 0); + return; + } + + ConditionVariableStatus = LastStatus; + } } static BOOL __fastcall RtlpWakeSingle(RTL_CONDITION_VARIABLE *ConditionVariable, YY_CV_WAIT_BLOCK* pBlock) { - volatile long Current = *(volatile long*)ConditionVariable; + size_t Current = (size_t)ConditionVariable; YY_CV_WAIT_BLOCK *pWaitBlock; YY_CV_WAIT_BLOCK *pSuccessor; size_t Last; @@ -1427,7 +1476,7 @@ static BOOL __fastcall RtlpWakeSingle(RTL_CONDITION_VARIABLE *ConditionVariable, { if (Current & 0x8) { - Last = InterlockedCompareExchange((volatile long*)ConditionVariable, Current | 0x7, Current); + Last = (size_t)InterlockedCompareExchangePointer((void *volatile *)ConditionVariable, (volatile long*)(Current | 0x7), (volatile long*)Current); if (Last == Current) return FALSE; @@ -1438,7 +1487,7 @@ static BOOL __fastcall RtlpWakeSingle(RTL_CONDITION_VARIABLE *ConditionVariable, { New = Current | 0x8; - Last = InterlockedCompareExchange((volatile long*)ConditionVariable, New, Current); + Last = (size_t)InterlockedCompareExchangePointer((void *volatile *)ConditionVariable, (volatile long*)New, (volatile long*)Current); if (Last == Current) { @@ -1474,7 +1523,7 @@ static BOOL __fastcall RtlpWakeSingle(RTL_CONDITION_VARIABLE *ConditionVariable, New = back == 0 ? back : back ^ ((New ^ back) & 0xF); - Last = InterlockedCompareExchange((volatile long*)ConditionVariable, New, Current); + Last = (size_t)InterlockedCompareExchangePointer((void *volatile *)ConditionVariable, (volatile long*)New, (volatile long*)Current); if (Last == Current) { @@ -1534,6 +1583,7 @@ RtlSleepConditionVariableCS( StackWaitBlock.next = NULL; StackWaitBlock.flag = 2; StackWaitBlock.SRWLock = NULL; + StackWaitBlock.uWakeupThreadId = 0; OldConditionVariable = *(size_t*)ConditionVariable; for (;;) @@ -1552,7 +1602,7 @@ RtlSleepConditionVariableCS( StackWaitBlock.notify = &StackWaitBlock; } - LastConditionVariable = InterlockedCompareExchange((volatile long*)ConditionVariable, NewConditionVariable, OldConditionVariable); + LastConditionVariable = (size_t)InterlockedCompareExchangePointer((void *volatile *)ConditionVariable, (volatile long*)NewConditionVariable, (volatile long*)OldConditionVariable); if (LastConditionVariable == OldConditionVariable) break; @@ -1567,6 +1617,8 @@ RtlSleepConditionVariableCS( { RtlpOptimizeConditionVariableWaitList(ConditionVariable, NewConditionVariable); } + + InitializeGlobalKeyedEventHandle(); //自旋 for (SpinCount = ConditionVariableSpinCount; SpinCount; --SpinCount) @@ -1583,7 +1635,8 @@ RtlSleepConditionVariableCS( if (Status == STATUS_TIMEOUT && RtlpWakeSingle(ConditionVariable, &StackWaitBlock) == FALSE) { - NtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, NULL); + SecondWaitWorkaroundNtWaitForKeyedEvent(GlobalKeyedEventHandle, &StackWaitBlock, 0, NULL); + //NtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, NULL); Status = STATUS_SUCCESS; } } @@ -1609,83 +1662,88 @@ RtlSleepConditionVariableSRW( size_t New; size_t Last; NTSTATUS Status = STATUS_SUCCESS; + + do{ + if (Flags & ~RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) + { + break; + } - if (Flags & ~RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) - { - return STATUS_INVALID_PARAMETER_2; - } - - StackWaitBlock.next = NULL; - StackWaitBlock.flag = 2; - StackWaitBlock.SRWLock = NULL; + StackWaitBlock.next = NULL; + StackWaitBlock.flag = 2; + StackWaitBlock.SRWLock = NULL; + StackWaitBlock.uWakeupThreadId = 0; - if (Flags& RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) - { - StackWaitBlock.flag |= 0x4; - } - - Current = *(volatile long*)ConditionVariable; + if (Flags& RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) + { + StackWaitBlock.flag |= 0x4; + } - for (;;) - { - New = (size_t)(&StackWaitBlock) | (Current & YY_CV_MASK); + Current = *(volatile size_t*)ConditionVariable; - if (StackWaitBlock.back = YY_CV_GET_BLOCK(Current)) + for (;;) { - StackWaitBlock.notify = NULL; + New = (size_t)(&StackWaitBlock) | (Current & YY_CV_MASK); - New |= 0x8; - } - else - { - StackWaitBlock.notify = &StackWaitBlock; - } + if (StackWaitBlock.back = YY_CV_GET_BLOCK(Current)) + { + StackWaitBlock.notify = NULL; - Last = InterlockedCompareExchange((volatile long*)ConditionVariable, New, Current); + New |= 0x8; + } + else + { + StackWaitBlock.notify = &StackWaitBlock; + } - if (Last == Current) - { - break; - } + Last = (size_t)InterlockedCompareExchangePointer((void *volatile *)ConditionVariable, (volatile long*)New, (volatile long*)Current); - Current = Last; - } + if (Last == Current) + { + break; + } - if (Flags& RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) - RtlReleaseSRWLockShared(SRWLock); - else - RtlReleaseSRWLockExclusive(SRWLock); + Current = Last; + } - if ((Current ^ New) & 0x8) - { - //新增0x8 标记位才调用 RtlpOptimizeConditionVariableWaitList - RtlpOptimizeConditionVariableWaitList(ConditionVariable, New); - } + if (Flags& RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) + RtlReleaseSRWLockShared(SRWLock); + else + RtlReleaseSRWLockExclusive(SRWLock); - //自旋 - for (SpinCount = ConditionVariableSpinCount; SpinCount; --SpinCount) - { - if (!(StackWaitBlock.flag & 2)) - break; + if ((Current ^ New) & 0x8) + { + //新增0x8 标记位才调用 RtlpOptimizeConditionVariableWaitList + RtlpOptimizeConditionVariableWaitList(ConditionVariable, New); + } + + InitializeGlobalKeyedEventHandle(); - YieldProcessor(); - } + //自旋 + for (SpinCount = ConditionVariableSpinCount; SpinCount; --SpinCount) + { + if (!(StackWaitBlock.flag & 2)) + break; - if (InterlockedBitTestAndReset((volatile LONG*)&StackWaitBlock.flag, 1)) - { - Status = NtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, dwMilliseconds); + YieldProcessor(); + } - if (Status == STATUS_TIMEOUT && RtlpWakeSingle(ConditionVariable, &StackWaitBlock) == FALSE) + if (InterlockedBitTestAndReset((volatile LONG*)&StackWaitBlock.flag, 1)) { - NtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, NULL); - Status = STATUS_SUCCESS; + Status = NtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, dwMilliseconds); + + if (Status == STATUS_TIMEOUT && RtlpWakeSingle(ConditionVariable, &StackWaitBlock) == FALSE) + { + SecondWaitWorkaroundNtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, NULL); + Status = STATUS_SUCCESS; + } } - } - if (Flags& RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) - RtlAcquireSRWLockShared(SRWLock); - else - RtlAcquireSRWLockExclusive(SRWLock); + if (Flags& RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) + RtlAcquireSRWLockShared(SRWLock); + else + RtlAcquireSRWLockExclusive(SRWLock); + } while (FALSE); return Status; } @@ -1762,7 +1820,8 @@ typedef struct _KEX_RTL_WAIT_ON_ADDRESS_HASH_BUCKET { // hashes addresses will become larger and slower by more than a factor of 2. // demo: https://godbolt.org/z/K9q9KheYj // -static KEX_RTL_WAIT_ON_ADDRESS_HASH_BUCKET KexRtlWaitOnAddressHashTable[32] = {0}; +#define KexRtlWoaHashEntries 32 // Must be a power of two. +static KEX_RTL_WAIT_ON_ADDRESS_HASH_BUCKET KexRtlWaitOnAddressHashTable[KexRtlWoaHashEntries] = {0}; #pragma warning(disable:4715) // not all control paths return a value static inline BOOLEAN KexRtlpEqualVolatileMemory( @@ -1783,8 +1842,9 @@ static inline BOOLEAN KexRtlpEqualVolatileMemory( static FORCEINLINE PKEX_RTL_WAIT_ON_ADDRESS_HASH_BUCKET KexRtlpGetWoaHashBucket( IN volatile VOID *Address) { - return &KexRtlWaitOnAddressHashTable[ - (((ULONG_PTR) Address) >> 4) % ARRAYSIZE(KexRtlWaitOnAddressHashTable)]; + return &KexRtlWaitOnAddressHashTable[ + (((ULONG_PTR) Address) >> 4) & (KexRtlWoaHashEntries - 1)]; +// Improved from VxKex by using & operation instead of % operation, improving performance for debug builds and likely ancient compilers. } // @@ -1843,11 +1903,11 @@ NTSTATUS NTAPI RtlWaitOnAddress( // ASSERT (AddressSize == 1 || AddressSize == 2 || // AddressSize == 4 || AddressSize == 8); - if (AddressSize != 1 && AddressSize != 2 && - AddressSize != 4 && AddressSize != 8) { + if (AddressSize != 4 && AddressSize != 2 && + AddressSize != 1 && AddressSize != 8) { - return STATUS_INVALID_PARAMETER; - } + return STATUS_INVALID_PARAMETER; + } // // Figure out which hash bucket we belong in. diff --git a/wrappers/extensions/ntext/rtl/sysinfo.c b/wrappers/extensions/ntext/rtl/sysinfo.c index 332ae4bc75..a14fead485 100644 --- a/wrappers/extensions/ntext/rtl/sysinfo.c +++ b/wrappers/extensions/ntext/rtl/sysinfo.c @@ -1,25 +1,26 @@ -/* - * Copyright 2009 Henri Verbeet for CodeWeavers - * - * 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 - * - */ -#define NDEBUG +/*++ + +Copyright (c) 2018 Shorthorn Project + +Module Name: + + sysinfo.c + +Abstract: + + Implement System Information functions + +Author: + + Skulltrail 07-November-2024 + +Revision History: + +--*/ -#include -#include +#define NDEBUG + +#include BOOLEAN globalVerificationTablet = TRUE; BOOLEAN globalVerificationMediaCenter = TRUE; @@ -967,51 +968,4 @@ RtlGetDeviceFamilyInfoEnum( if(pulDeviceForm){ *pulDeviceForm = 0; } -} - -// /* - // * @implemented - // * @note User-mode version of RtlGetVersion in ntoskrnl/rtl/misc.c - // */ -// NTSTATUS NTAPI -// RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation) -// { - // SIZE_T Length; - // PPEB Peb = NtCurrentPeb(); - - // if (lpVersionInformation->dwOSVersionInfoSize != sizeof(RTL_OSVERSIONINFOW) && - // lpVersionInformation->dwOSVersionInfoSize != sizeof(RTL_OSVERSIONINFOEXW)) - // { - // return STATUS_INVALID_PARAMETER; - // } - - // lpVersionInformation->dwMajorVersion = 6; - // lpVersionInformation->dwMinorVersion = 1; - // lpVersionInformation->dwBuildNumber = 7601; - // lpVersionInformation->dwPlatformId = Peb->OSPlatformId; - // RtlZeroMemory(lpVersionInformation->szCSDVersion, sizeof(lpVersionInformation->szCSDVersion)); - - // Length = wcslen(L"Service Pack 1"); - - // /* If we have a CSD version string, initialized by Application Compatibility... */ - // RtlStringCbCopyExW(lpVersionInformation->szCSDVersion, - // ARRAYSIZE(lpVersionInformation->szCSDVersion), - // L"Service Pack 1", NULL , NULL, STRSAFE_NULL_ON_FAILURE); - // /* Always null-terminate the user CSD version string */ - // //lpVersionInformation->szCSDVersion[Length] = UNICODE_NULL; - - // if (lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW)) - // { - // PRTL_OSVERSIONINFOEXW InfoEx = (PRTL_OSVERSIONINFOEXW)lpVersionInformation; - // InfoEx->wServicePackMajor = (Peb->OSCSDVersion >> 8) & 0xFF; - // InfoEx->wServicePackMinor = Peb->OSCSDVersion & 0xFF; - // InfoEx->wSuiteMask = SharedUserData->SuiteMask & 0xFFFF; - // InfoEx->wProductType = SharedUserData->NtProductType; - // InfoEx->wReserved = 0; - - // /* HACK: ReactOS specific changes, see bug-reports CORE-6611 and CORE-4620 (aka. #5003) */ - // //SetRosSpecificInfo(InfoEx); - // } - - // return STATUS_SUCCESS; -// } \ No newline at end of file +} \ No newline at end of file diff --git a/wrappers/extensions/ntext/rtl/wow64.c b/wrappers/extensions/ntext/rtl/wow64.c index ce308af6a8..ed4acaa1b9 100644 --- a/wrappers/extensions/ntext/rtl/wow64.c +++ b/wrappers/extensions/ntext/rtl/wow64.c @@ -41,74 +41,6 @@ PVOID Wow64SetFilesystemRedirectorEx ( IN PVOID NewValue ) -/*++ - -Routine Description: - - This routine allows a thread running inside Wow64 to disable file-system - redirection for all calls happening in the context of this thread. - - - NOTE: This routine should only called from a wow64 process, and is only available - when running on .NET server platforms and beyond. If you component will - run on downlevel platforms (XP 2600 for example), you shouldn't use WOW64_FILE_SYSTEM_DISABLE_REDIRECT (see below). - -Example (Enumerating files under c:\windows\system32): - - { - HANDLE File; - WIN32_FIND_DATA FindData; -#ifndef _WIN64 - BOOL bWow64Process = FALSE; - PVOID Wow64RedirectionOld; -#endif - - // - // Disable Wow64 file system redirection - // -#ifndef _WIN64 - IsWow64Process (GetCurrentProcess (), &bWow64Process); - if (bWow64Process == TRUE) { - Wow64RedirectionOld = Wow64SetFilesystemRedirectorEx (WOW64_FILE_SYSTEM_DISABLE_REDIRECT); - } -#endif - File = FindFirstFileA ("c:\\windows\\system32\\*.*", &FindData); - - do { - . - . - } while (FindNextFileA (File, &FindData) != 0); - - FindClose (File); - - // - // Enable Wow64 file-system redirection - // -#ifndef _WIN64 - if (bWow64Process == TRUE) { - Wow64SetFilesystemRedirectorEx (Wow64RedirectionOld); - } -#endif - } - - -Arguments: - - NewValue - New Wow64 file-system redirection value. This can either be: - a- pointer to a unicode string with a fully-qualified path name (e.g. L"c:\\windows\\notepad.exe"). - b- any of the following predefined values : - * WOW64_FILE_SYSTEM_ENABLE_REDIRECT : Enables file-system redirection (default) - * WOW64_FILE_SYSTEM_DISABLE_REDIRECT : Disables file-system redirection on all - file I/O operations happening within the context of the current thread. - * WOW64_FILE_SYSTEM_DISABLE_REDIRECT_LEGACY: Use this only if you want to run on - download level platforms (for example XP 2600), as it will have no effect - and prevents your program from malfunctioning. - -Return: - - Old Wow64 file-system redirection value - ---*/ { PVOID OldValue; OldValue = (PVOID)(ULONG_PTR)NtCurrentTeb()->TlsSlots[WOW64_TLS_FILESYSREDIR]; diff --git a/wrappers/extensions/setupext/CMakeLists.txt b/wrappers/extensions/setupext/CMakeLists.txt deleted file mode 100644 index eabfbd800d..0000000000 --- a/wrappers/extensions/setupext/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ - -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -spec2def(setupext.dll setupext.spec) - -list(APPEND SOURCE - devinst.c - hooks.c - query.c - version.rc - ${CMAKE_CURRENT_BINARY_DIR}/setupext_stubs.c - ${CMAKE_CURRENT_BINARY_DIR}/setupext.def) - -set(baseaddress_setupext 0x69370000) - -add_library(setupext SHARED ${SOURCE}) -set_module_type(setupext win32dll ENTRYPOINT 0) -target_link_libraries(setupext wine) -add_importlibs(setupext setupapi advapi32 kernel32 ntdll) -add_cd_file(TARGET setupext DESTINATION reactos/system32 FOR all) diff --git a/wrappers/extensions/setupext/devinst.c b/wrappers/extensions/setupext/devinst.c deleted file mode 100644 index 05a92a93d1..0000000000 --- a/wrappers/extensions/setupext/devinst.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright 2009 Henri Verbeet for CodeWeavers - * - * 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 "setupapi_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(setupapi); - -static struct device **devnode_table; -static unsigned int devnode_table_size; - -/* is used to identify if a DeviceInfoSet pointer is -valid or not */ -#define SETUP_DEVICE_INFO_SET_MAGIC 0xd00ff056 - -static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr) -{ - static const WCHAR fmt[] = {'{','%','0','8','X','-','%','0','4','X','-', - '%','0','4','X','-','%','0','2','X','%','0','2','X','-','%','0','2', - 'X','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','%', - '0','2','X','}',0}; - - swprintf( - guidStr, - fmt, guid->Data1, guid->Data2, guid->Data3, - guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], - guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); -} - -static DEVINST alloc_devnode(struct device *device) -{ - unsigned int i; - - for (i = 0; i < devnode_table_size; ++i) - { - if (!devnode_table[i]) - break; - } - - if (i == devnode_table_size) - { - if (devnode_table) - { - devnode_table_size *= 2; - devnode_table = heap_realloc_zero(devnode_table, - devnode_table_size * sizeof(*devnode_table)); - } - else - { - devnode_table_size = 256; - devnode_table = heap_alloc_zero(devnode_table_size * sizeof(*devnode_table)); - } - } - - devnode_table[i] = device; - return i; -} - -static struct device *get_devnode_device(DEVINST devnode) -{ - if (devnode < devnode_table_size) - return devnode_table[devnode]; - - WARN("device node %u not found\n", devnode); - return NULL; -} - -static LSTATUS get_device_property(struct device *device, const DEVPROPKEY *prop_key, DEVPROPTYPE *prop_type, - BYTE *prop_buff, DWORD prop_buff_size, DWORD *required_size, DWORD flags) -{ - WCHAR key_path[55] = L"Properties\\"; - HKEY hkey; - DWORD value_type; - DWORD value_size = 0; - LSTATUS ls; - - if (!prop_key) - return ERROR_INVALID_DATA; - - if (!prop_type || (!prop_buff && prop_buff_size)) - return ERROR_INVALID_USER_BUFFER; - - if (flags) - return ERROR_INVALID_FLAGS; - - SETUPDI_GuidToString(&prop_key->fmtid, key_path + 11); - swprintf(key_path + 49,L"\\%04X", prop_key->pid); - - ls = RegOpenKeyExW(device->key, key_path, 0, KEY_QUERY_VALUE, &hkey); - if (!ls) - { - value_size = prop_buff_size; - ls = RegQueryValueExW(hkey, NULL, NULL, &value_type, prop_buff, &value_size); - RegCloseKey(hkey); - } - - switch (ls) - { - case NO_ERROR: - case ERROR_MORE_DATA: - *prop_type = 0xffff & value_type; - ls = (ls == ERROR_MORE_DATA || !prop_buff) ? ERROR_INSUFFICIENT_BUFFER : NO_ERROR; - break; - case ERROR_FILE_NOT_FOUND: - *prop_type = DEVPROP_TYPE_EMPTY; - value_size = 0; - ls = ERROR_NOT_FOUND; - break; - default: - *prop_type = DEVPROP_TYPE_EMPTY; - value_size = 0; - FIXME("Unhandled error %#x\n", ls); - break; - } - - if (required_size) - *required_size = value_size; - - return ls; -} - -static struct DeviceInfoSet *get_device_set(HDEVINFO devinfo) -{ - struct DeviceInfoSet *set = devinfo; - - if (!devinfo || devinfo == INVALID_HANDLE_VALUE || set->magic != SETUP_DEVICE_INFO_SET_MAGIC) - { - SetLastError(ERROR_INVALID_HANDLE); - return NULL; - } - - return set; -} - -static struct device *get_device(HDEVINFO devinfo, const SP_DEVINFO_DATA *data) -{ - struct DeviceInfoSet *set; - struct device *device; - - if (!(set = get_device_set(devinfo))) - return FALSE; - - if (!data || data->cbSize != sizeof(*data) || !data->Reserved) - { - SetLastError(ERROR_INVALID_PARAMETER); - return NULL; - } - - device = (struct device *)data->Reserved; - - if (device->set != set) - { - SetLastError(ERROR_INVALID_PARAMETER); - return NULL; - } - - if (device->removed) - { - SetLastError(ERROR_NO_SUCH_DEVINST); - return NULL; - } - - return device; -} - -static BOOL is_valid_property_type(DEVPROPTYPE prop_type) -{ - DWORD type = prop_type & DEVPROP_MASK_TYPE; - DWORD typemod = prop_type & DEVPROP_MASK_TYPEMOD; - - if (type > MAX_DEVPROP_TYPE) - return FALSE; - if (typemod > MAX_DEVPROP_TYPEMOD) - return FALSE; - - if (typemod == DEVPROP_TYPEMOD_ARRAY - && (type == DEVPROP_TYPE_EMPTY || type == DEVPROP_TYPE_NULL || type == DEVPROP_TYPE_STRING - || type == DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING)) - return FALSE; - - if (typemod == DEVPROP_TYPEMOD_LIST - && !(type == DEVPROP_TYPE_STRING || type == DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING)) - return FALSE; - - return TRUE; -} - -/*********************************************************************** - * CM_Get_DevNode_Property_ExW (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_DevNode_Property_ExW(DEVINST devnode, const DEVPROPKEY *prop_key, DEVPROPTYPE *prop_type, - BYTE *prop_buff, ULONG *prop_buff_size, ULONG flags, HMACHINE machine) -{ - struct device *device = get_devnode_device(devnode); - LSTATUS ls; - - TRACE("%u, %p, %p, %p, %p, %#x, %p\n", devnode, prop_key, prop_type, prop_buff, prop_buff_size, - flags, machine); - - if (machine) - return CR_MACHINE_UNAVAILABLE; - - if (!device) - return CR_NO_SUCH_DEVINST; - - if (!prop_buff_size) - return CR_INVALID_POINTER; - - ls = get_device_property(device, prop_key, prop_type, prop_buff, *prop_buff_size, prop_buff_size, flags); - switch (ls) - { - case NO_ERROR: - return CR_SUCCESS; - case ERROR_INVALID_DATA: - return CR_INVALID_DATA; - case ERROR_INVALID_USER_BUFFER: - return CR_INVALID_POINTER; - case ERROR_INVALID_FLAGS: - return CR_INVALID_FLAG; - case ERROR_INSUFFICIENT_BUFFER: - return CR_BUFFER_SMALL; - case ERROR_NOT_FOUND: - return CR_NO_SUCH_VALUE; - } - return CR_FAILURE; -} - -/*********************************************************************** - * CM_Get_DevNode_PropertyW (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_DevNode_PropertyW(DEVINST dev, const DEVPROPKEY *key, DEVPROPTYPE *type, - PVOID buf, PULONG len, ULONG flags) -{ - return CM_Get_DevNode_Property_ExW(dev, key, type, buf, len, flags, NULL); -} - -BOOL WINAPI SetupDiSetDevicePropertyW(HDEVINFO devinfo, PSP_DEVINFO_DATA device_data, const DEVPROPKEY *key, - DEVPROPTYPE type, const BYTE *buffer, DWORD size, DWORD flags) -{ - static const WCHAR propertiesW[] = {'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's', 0}; - static const WCHAR formatW[] = {'\\', '%', '0', '4', 'X', 0}; - struct device *device; - HKEY properties_hkey, property_hkey; - WCHAR property_hkey_path[44]; - LSTATUS ls; - - TRACE("%p %p %p %#x %p %d %#x\n", devinfo, device_data, key, type, buffer, size, flags); - - if (!(device = get_device(devinfo, device_data))) - return FALSE; - - if (!key || !is_valid_property_type(type) - || (buffer && !size && !(type == DEVPROP_TYPE_EMPTY || type == DEVPROP_TYPE_NULL)) - || (buffer && size && (type == DEVPROP_TYPE_EMPTY || type == DEVPROP_TYPE_NULL))) - { - SetLastError(ERROR_INVALID_DATA); - return FALSE; - } - - if (size && !buffer) - { - SetLastError(ERROR_INVALID_USER_BUFFER); - return FALSE; - } - - if (flags) - { - SetLastError(ERROR_INVALID_FLAGS); - return FALSE; - } - - ls = RegCreateKeyExW(device->key, propertiesW, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &properties_hkey, NULL); - if (ls) - { - SetLastError(ls); - return FALSE; - } - - SETUPDI_GuidToString(&key->fmtid, property_hkey_path); - swprintf(property_hkey_path + 38, formatW, key->pid); - - if (type == DEVPROP_TYPE_EMPTY) - { - ls = RegDeleteKeyW(properties_hkey, property_hkey_path); - RegCloseKey(properties_hkey); - SetLastError(ls == ERROR_FILE_NOT_FOUND ? ERROR_NOT_FOUND : ls); - return !ls; - } - else if (type == DEVPROP_TYPE_NULL) - { - if (!(ls = RegOpenKeyW(properties_hkey, property_hkey_path, &property_hkey))) - { - ls = RegDeleteValueW(property_hkey, NULL); - RegCloseKey(property_hkey); - } - - RegCloseKey(properties_hkey); - SetLastError(ls == ERROR_FILE_NOT_FOUND ? ERROR_NOT_FOUND : ls); - return !ls; - } - else - { - if (!(ls = RegCreateKeyExW(properties_hkey, property_hkey_path, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, - &property_hkey, NULL))) - { - ls = RegSetValueExW(property_hkey, NULL, 0, 0xffff0000 | (0xffff & type), buffer, size); - RegCloseKey(property_hkey); - } - - RegCloseKey(properties_hkey); - SetLastError(ls); - return !ls; - } -} - -/*********************************************************************** - * SetupDiGetDevicePropertyW (SETUPAPI.@) - */ -BOOL WINAPI SetupDiGetDevicePropertyW(HDEVINFO devinfo, PSP_DEVINFO_DATA device_data, - const DEVPROPKEY *prop_key, DEVPROPTYPE *prop_type, BYTE *prop_buff, - DWORD prop_buff_size, DWORD *required_size, DWORD flags) -{ - struct device *device; - LSTATUS ls; - - TRACE("%p, %p, %p, %p, %p, %d, %p, %#x\n", devinfo, device_data, prop_key, prop_type, prop_buff, prop_buff_size, - required_size, flags); - - if (!(device = get_device(devinfo, device_data))) - return FALSE; - - ls = get_device_property(device, prop_key, prop_type, prop_buff, prop_buff_size, required_size, flags); - - SetLastError(ls); - return !ls; -} - -DWORD -GetErrorCodeFromCrCode(const IN CONFIGRET cr) -{ - switch (cr) - { - case CR_ACCESS_DENIED: return ERROR_ACCESS_DENIED; - case CR_BUFFER_SMALL: return ERROR_INSUFFICIENT_BUFFER; - case CR_CALL_NOT_IMPLEMENTED: return ERROR_CALL_NOT_IMPLEMENTED; - case CR_FAILURE: return ERROR_GEN_FAILURE; - case CR_INVALID_DATA: return ERROR_INVALID_USER_BUFFER; - case CR_INVALID_DEVICE_ID: return ERROR_INVALID_PARAMETER; - case CR_INVALID_MACHINENAME: return ERROR_INVALID_COMPUTERNAME; - case CR_INVALID_DEVNODE: return ERROR_INVALID_PARAMETER; - case CR_INVALID_FLAG: return ERROR_INVALID_FLAGS; - case CR_INVALID_POINTER: return ERROR_INVALID_PARAMETER; - case CR_INVALID_PROPERTY: return ERROR_INVALID_PARAMETER; - case CR_NO_SUCH_DEVNODE: return ERROR_FILE_NOT_FOUND; - case CR_NO_SUCH_REGISTRY_KEY: return ERROR_FILE_NOT_FOUND; - case CR_NO_SUCH_VALUE: return ERROR_FILE_NOT_FOUND; - case CR_OUT_OF_MEMORY: return ERROR_NOT_ENOUGH_MEMORY; - case CR_REGISTRY_ERROR: return ERROR_GEN_FAILURE; - case CR_ALREADY_SUCH_DEVINST: return ERROR_DEVINST_ALREADY_EXISTS; - case CR_SUCCESS: return ERROR_SUCCESS; - default: return ERROR_GEN_FAILURE; - } -} - -/*********************************************************************** - * SetupDiRestartDevices (SETUPAPI.@) - */ -BOOL -WINAPI -SetupDiRestartDevices( - HDEVINFO DeviceInfoSet, - PSP_DEVINFO_DATA DeviceInfoData) -{ - struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet; - struct DeviceInfo *devInfo; - CONFIGRET cr; - - TRACE("%s(%p %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData); - - if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE) - { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } - if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC) - { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } - - if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA) - || !DeviceInfoData->Reserved) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; - - cr = CM_Enable_DevNode_Ex(devInfo->dnDevInst, 0, set->hMachine); - if (cr != CR_SUCCESS) - { - SetLastError(GetErrorCodeFromCrCode(cr)); - return FALSE; - } - - return TRUE; -} - -/*********************************************************************** - * CM_Register_Notification (cfgmgr32.@) - */ -CONFIGRET WINAPI CM_Register_Notification( CM_NOTIFY_FILTER *filter, void *context, - PCM_NOTIFY_CALLBACK callback, HCMNOTIFICATION *notify_context ) -{ - FIXME("%p %p %p %p stub!\n", filter, context, callback, notify_context); - - return CR_CALL_NOT_IMPLEMENTED; -} - -/*********************************************************************** - * CM_Get_Device_Interface_PropertyW (cfgmgr32.@) - */ -CONFIGRET WINAPI CM_Get_Device_Interface_PropertyW( LPCWSTR device_interface, const DEVPROPKEY *property_key, - DEVPROPTYPE *property_type, BYTE *property_buffer, - ULONG *property_buffer_size, ULONG flags ) -{ - FIXME("%s %p %p %p %p %ld stub!\n", debugstr_w(device_interface), property_key, property_type, - property_buffer, property_buffer_size, flags); - - return CR_CALL_NOT_IMPLEMENTED; -} - -/*********************************************************************** - * CM_Register_Notification (cfgmgr32.@) - */ -CONFIGRET WINAPI CM_Unregister_Notification(HCMNOTIFICATION *notify_context ) -{ - FIXME("%p stub!\n", notify_context); - - return CR_CALL_NOT_IMPLEMENTED; -} \ No newline at end of file diff --git a/wrappers/extensions/setupext/hooks.c b/wrappers/extensions/setupext/hooks.c deleted file mode 100644 index a60f6cfb4e..0000000000 --- a/wrappers/extensions/setupext/hooks.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * setupapi query functions - * - * Copyright 2006 James Hawkins - * - * 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 "setupapi_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(setupapi); - -/*********************************************************************** - * CMP_WaitNoPendingInstallEvents [SETUPAPI.@] - */ -DWORD -WINAPI -CMP_WaitNoPendingInstallEventsInternal( - _In_ DWORD dwTimeout) -{ - HANDLE hEvent; - DWORD ret; - - TRACE("CMP_WaitNoPendingInstallEvents(%lu)\n", dwTimeout); - - hEvent = OpenEventW(SYNCHRONIZE, FALSE, L"Global\\PnP_No_Pending_Install_Events"); - if (hEvent == NULL) - return WAIT_FAILED; - - ret = WaitForSingleObject(hEvent, dwTimeout); - CloseHandle(hEvent); - return ret; -} \ No newline at end of file diff --git a/wrappers/extensions/setupext/main.c b/wrappers/extensions/setupext/main.c deleted file mode 100644 index 9963d6e4be..0000000000 --- a/wrappers/extensions/setupext/main.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2009 Henri Verbeet for CodeWeavers - * - * 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 "setupapi_private.h" - -BOOL -WINAPI -DllMain( - HINSTANCE hinstDll, - DWORD dwReason, - LPVOID reserved) -{ - switch (dwReason) - { - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDll); - break; - - case DLL_PROCESS_DETACH: - break; - } - - return TRUE; -} diff --git a/wrappers/extensions/setupext/query.c b/wrappers/extensions/setupext/query.c deleted file mode 100644 index aede536fb3..0000000000 --- a/wrappers/extensions/setupext/query.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * setupapi query functions - * - * Copyright 2006 James Hawkins - * - * 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 "setupapi_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(setupapi); - -/*********************************************************************** - * SetupGetInfDriverStoreLocationW (SETUPAPI.@) - */ -BOOL WINAPI SetupGetInfDriverStoreLocationW( - PCWSTR FileName, PSP_ALTPLATFORM_INFO AlternativePlatformInfo, - PCWSTR LocaleName, PWSTR ReturnBuffer, DWORD ReturnBufferSize, - PDWORD RequiredSize) -{ - FIXME("stub: %s %p %s %p %u %p\n", debugstr_w(FileName), AlternativePlatformInfo, debugstr_w(LocaleName), ReturnBuffer, ReturnBufferSize, RequiredSize); - - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - -DWORD WINAPI CM_MapCrToWin32Err( CONFIGRET code, DWORD default_error ) -{ - //TRACE( "code: %#lx, default_error: %ld\n", code, default_error ); - - switch (code) - { - case CR_SUCCESS: return ERROR_SUCCESS; - case CR_OUT_OF_MEMORY: return ERROR_NOT_ENOUGH_MEMORY; - case CR_INVALID_POINTER: return ERROR_INVALID_USER_BUFFER; - case CR_INVALID_FLAG: return ERROR_INVALID_FLAGS; - case CR_INVALID_DEVNODE: - case CR_INVALID_DEVICE_ID: - case CR_INVALID_MACHINENAME: - case CR_INVALID_PROPERTY: - case CR_INVALID_REFERENCE_STRING: return ERROR_INVALID_DATA; - case CR_NO_SUCH_DEVNODE: - case CR_NO_SUCH_VALUE: - case CR_NO_SUCH_DEVICE_INTERFACE: return ERROR_NOT_FOUND; - case CR_ALREADY_SUCH_DEVNODE: return ERROR_ALREADY_EXISTS; - case CR_BUFFER_SMALL: return ERROR_INSUFFICIENT_BUFFER; - case CR_NO_REGISTRY_HANDLE: return ERROR_INVALID_HANDLE; - case CR_REGISTRY_ERROR: return ERROR_REGISTRY_CORRUPT; - case CR_NO_SUCH_REGISTRY_KEY: return ERROR_FILE_NOT_FOUND; - case CR_REMOTE_COMM_FAILURE: - case CR_MACHINE_UNAVAILABLE: - case CR_NO_CM_SERVICES: return ERROR_SERVICE_NOT_ACTIVE; - case CR_ACCESS_DENIED: return ERROR_ACCESS_DENIED; - case CR_CALL_NOT_IMPLEMENTED: return ERROR_CALL_NOT_IMPLEMENTED; - } - - return default_error; -} \ No newline at end of file diff --git a/wrappers/extensions/setupext/setupapi_private.h b/wrappers/extensions/setupext/setupapi_private.h deleted file mode 100644 index e1583e5006..0000000000 --- a/wrappers/extensions/setupext/setupapi_private.h +++ /dev/null @@ -1,205 +0,0 @@ -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "winnt.h" -#include "winreg.h" -#include "wingdi.h" -#include "winuser.h" -#include "winnls.h" -#include "winsvc.h" -#include "setupapi.h" -#include "wine/debug.h" -#include "wine/heap.h" -#include "wine/list.h" -#include "cfgmgr32.h" -#include "winioctl.h" -#include "rpc.h" -#include "rpcdce.h" -#include "cguid.h" -#include "devpropdef.h" - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -typedef HANDLE HCMNOTIFICATION, *PHCMNOTIFICATION; - -DWORD -GetErrorCodeFromCrCode(const IN CONFIGRET cr); - -static inline void * __WINE_ALLOC_SIZE(2) heap_realloc_zero(void *mem, size_t len) -{ - return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len); -} - -struct DeviceInfoSet -{ - DWORD magic; /* if is equal to SETUP_DEVICE_INFO_SET_MAGIC struct is okay */ - GUID ClassGuid; - HWND hwndParent; - struct list devices; - /* Used when dealing with CM_* functions */ - HMACHINE hMachine; - /* Contains the name of the remote computer ('\\COMPUTERNAME' for example), - * or NULL if related to local machine. Points into szData field at the - * end of the structure */ - PCWSTR MachineName; -}; - -struct device -{ - struct DeviceInfoSet *set; - HKEY key; - BOOL phantom; - WCHAR *instanceId; - struct list interfaces; - GUID class; - DEVINST devnode; - struct list entry; - BOOL removed; - SP_DEVINSTALL_PARAMS_W params; - struct driver *drivers; - unsigned int driver_count; - struct driver *selected_driver; -}; - -struct ClassInstallParams -{ - PSP_PROPCHANGE_PARAMS PropChangeParams; - PSP_ADDPROPERTYPAGE_DATA AddPropertyPageData; -}; - -struct DeviceInfo /* Element of DeviceInfoSet.ListHead */ -{ - LIST_ENTRY ListEntry; - /* Used when dealing with CM_* functions */ - DEVINST dnDevInst; - - /* Link to parent DeviceInfoSet */ - struct DeviceInfoSet *set; - - /* Reserved Field of SP_DEVINSTALL_PARAMS_W structure - * points to a struct DriverInfoElement */ - SP_DEVINSTALL_PARAMS_W InstallParams; - - /* Information about devnode: - * - instanceId: - * "Root\*PNP0501" for example. - * It doesn't contain the unique ID for the device - * (points into the Data field at the end of the structure) - * WARNING: no NULL char exist between instanceId and UniqueId - * in Data field! - * - UniqueId - * "5&1be2108e&0" or "0000" - * If DICD_GENERATE_ID is specified in creation flags, - * this unique ID is autogenerated using 4 digits, base 10 - * (points into the Data field at the end of the structure) - * - DeviceDescription - * String which identifies the device. Can be NULL. If not NULL, - * points into the Data field at the end of the structure - * - ClassGuid - * Identifies the class of this device. It is GUID_NULL if the - * device has not been installed - * - CreationFlags - * Is a combination of: - * - DICD_GENERATE_ID - * the unique ID needs to be generated - * - DICD_INHERIT_CLASSDRVS - * inherit driver of the device info set (== same pointer) - */ - PCWSTR instanceId; - PCWSTR UniqueId; - PCWSTR DeviceDescription; - GUID ClassGuid; - DWORD CreationFlags; - - /* If CreationFlags contains DICD_INHERIT_CLASSDRVS, this list is invalid */ - /* If the driver is not searched/detected, this list is empty */ - LIST_ENTRY DriverListHead; /* List of struct DriverInfoElement */ - - /* List of interfaces implemented by this device */ - LIST_ENTRY InterfaceListHead; /* List of struct DeviceInterface */ - - /* Used by SetupDiGetClassInstallParamsW/SetupDiSetClassInstallParamsW */ - struct ClassInstallParams ClassInstallParams; - - /* Device property page provider data */ - HMODULE hmodDevicePropPageProvider; - PVOID pDevicePropPageProvider; - - /* Variable size array (contains data for instanceId, UniqueId, DeviceDescription) */ - WCHAR Data[ANYSIZE_ARRAY]; -}; - -typedef enum _CM_NOTIFY_FILTER_TYPE -{ - CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE, - CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE, - CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE, - CM_NOTIFY_FILTER_TYPE_MAX -} CM_NOTIFY_FILTER_TYPE, *PCM_NOTIFY_FILTER_TYPE; - -typedef enum _CM_NOTIFY_ACTION -{ - CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL, - CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL, - CM_NOTIFY_ACTION_DEVICEQUERYREMOVE, - CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED, - CM_NOTIFY_ACTION_DEVICEREMOVEPENDING, - CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE, - CM_NOTIFY_ACTION_DEVICECUSTOMEVENT, - CM_NOTIFY_ACTION_DEVICEINSTANCEENUMERATED, - CM_NOTIFY_ACTION_DEVICEINSTANCESTARTED, - CM_NOTIFY_ACTION_DEVICEINSTANCEREMOVED, - CM_NOTIFY_ACTION_MAX -} CM_NOTIFY_ACTION, *PCM_NOTIFY_ACTION; - -typedef struct _CM_NOTIFY_FILTER -{ - DWORD cbSize; - DWORD Flags; - CM_NOTIFY_FILTER_TYPE FilterType; - DWORD Reserved; - union - { - struct - { - GUID ClassGuid; - } DeviceInterface; - struct - { - HANDLE hTarget; - } DeviceHandle; - struct - { - WCHAR InstanceId[MAX_DEVICE_ID_LEN]; - } DeviceInstance; - } u; -} CM_NOTIFY_FILTER, *PCM_NOTIFY_FILTER; - -typedef struct _CM_NOTIFY_EVENT_DATA -{ - CM_NOTIFY_FILTER_TYPE FilterType; - DWORD Reserved; - union - { - struct - { - GUID ClassGuid; - WCHAR SymbolicLink[ANYSIZE_ARRAY]; - } DeviceInterface; - struct - { - GUID EventGuid; - LONG NameOffset; - DWORD DataSize; - BYTE Data[ANYSIZE_ARRAY]; - } DeviceHandle; - struct - { - WCHAR InstanceId[ANYSIZE_ARRAY]; - } DeviceInstance; - } u; -} CM_NOTIFY_EVENT_DATA, *PCM_NOTIFY_EVENT_DATA; - -typedef DWORD (WINAPI *PCM_NOTIFY_CALLBACK)(HCMNOTIFICATION,void*,CM_NOTIFY_ACTION,CM_NOTIFY_EVENT_DATA*,DWORD); \ No newline at end of file diff --git a/wrappers/extensions/setupext/setupext.spec b/wrappers/extensions/setupext/setupext.spec deleted file mode 100644 index 92ec0c5678..0000000000 --- a/wrappers/extensions/setupext/setupext.spec +++ /dev/null @@ -1,641 +0,0 @@ -# Functions exported by Win2003 SP1 -@ stdcall CMP_GetBlockedDriverInfo(str long long long) -@ stdcall CMP_GetServerSideDeviceInstallFlags(ptr) -@ stdcall CMP_Init_Detection(long) -@ stdcall CMP_RegisterNotification(ptr ptr long ptr) -@ stdcall CMP_Report_LogOn(long long) -@ stdcall CMP_UnregisterNotification(ptr) -@ stdcall CMP_WaitServicesAvailable(ptr) -@ stdcall CM_Add_Empty_Log_Conf(ptr ptr long long) -@ stdcall CM_Add_Empty_Log_Conf_Ex(ptr ptr long long ptr) -@ stdcall CM_Add_IDA(ptr str long) -@ stdcall CM_Add_IDW(ptr wstr long) -@ stdcall CM_Add_ID_ExA(ptr str long ptr) -@ stdcall CM_Add_ID_ExW(ptr wstr long ptr) -@ stdcall CM_Add_Range(long long long long) -@ stdcall CM_Add_Res_Des(ptr ptr long ptr long long) -@ stdcall CM_Add_Res_Des_Ex(ptr ptr long ptr long long long) -@ stdcall CM_Connect_MachineA(str ptr) -@ stdcall CM_Connect_MachineW(wstr ptr) -@ stdcall CM_Create_DevNodeA(ptr str long long) -@ stdcall CM_Create_DevNodeW(ptr wstr long long) -@ stdcall CM_Create_DevNode_ExA(ptr str long long long) -@ stdcall CM_Create_DevNode_ExW(ptr wstr long long long) -@ stdcall CM_Create_Range_List(long long) -@ stdcall CM_Delete_Class_Key(ptr long) -@ stdcall CM_Delete_Class_Key_Ex(ptr long long) -@ stdcall CM_Delete_DevNode_Key(long long long) -@ stdcall CM_Delete_DevNode_Key_Ex(long long long ptr) -@ stdcall CM_Delete_Range(long long long long) -@ stdcall CM_Detect_Resource_Conflict(ptr long ptr long ptr long) -@ stdcall CM_Detect_Resource_Conflict_Ex(ptr long ptr long ptr long ptr) -@ stdcall CM_Disable_DevNode(long long) -@ stdcall CM_Disable_DevNode_Ex(long long ptr) -@ stdcall CM_Disconnect_Machine(long) -@ stdcall CM_Dup_Range_List(ptr ptr long) -@ stdcall CM_Enable_DevNode(long long) -@ stdcall CM_Enable_DevNode_Ex(long long ptr) -@ stdcall CM_Enumerate_Classes(long ptr long) -@ stdcall CM_Enumerate_Classes_Ex(long ptr long ptr) -@ stdcall CM_Enumerate_EnumeratorsA(long str ptr long) -@ stdcall CM_Enumerate_EnumeratorsW(long wstr ptr long) -@ stdcall CM_Enumerate_Enumerators_ExA(long str ptr long long) -@ stdcall CM_Enumerate_Enumerators_ExW(long wstr ptr long long) -@ stdcall CM_Find_Range(ptr long long long long ptr long) -@ stdcall CM_First_Range(ptr ptr ptr ptr long) -@ stdcall CM_Free_Log_Conf(ptr long) -@ stdcall CM_Free_Log_Conf_Ex(ptr long ptr) -@ stdcall CM_Free_Log_Conf_Handle(ptr) -@ stdcall CM_Free_Range_List(ptr long) -@ stdcall CM_Free_Res_Des(ptr ptr long) -@ stdcall CM_Free_Res_Des_Ex(ptr ptr long long) -@ stdcall CM_Free_Res_Des_Handle(ptr) -@ stdcall CM_Free_Resource_Conflict_Handle(ptr) -@ stdcall CM_Get_Child(ptr long long) -@ stdcall CM_Get_Child_Ex(ptr long long long) -@ stdcall CM_Get_Class_Key_NameA(ptr str ptr long) -@ stdcall CM_Get_Class_Key_NameW(ptr wstr ptr long) -@ stdcall CM_Get_Class_Key_Name_ExA(ptr str ptr long long) -@ stdcall CM_Get_Class_Key_Name_ExW(ptr wstr ptr long long) -@ stdcall CM_Get_Class_NameA(ptr str ptr long) -@ stdcall CM_Get_Class_NameW(ptr wstr ptr long) -@ stdcall CM_Get_Class_Name_ExA(ptr str ptr long long) -@ stdcall CM_Get_Class_Name_ExW(ptr wstr ptr long long) -@ stdcall CM_Get_Class_Registry_PropertyA(ptr long ptr ptr ptr long ptr) -@ stdcall CM_Get_Class_Registry_PropertyW(ptr long ptr ptr ptr long ptr) -@ stdcall CM_Get_Depth(ptr long long) -@ stdcall CM_Get_Depth_Ex(ptr long long long) -@ stdcall CM_Get_DevNode_Custom_PropertyA(long str ptr ptr ptr long) -@ stdcall CM_Get_DevNode_Custom_PropertyW(long wstr ptr ptr ptr long) -@ stdcall CM_Get_DevNode_Custom_Property_ExA(long str ptr ptr ptr long ptr) -@ stdcall CM_Get_DevNode_Custom_Property_ExW(long wstr ptr ptr ptr long ptr) -@ stdcall CM_Get_DevNode_Registry_PropertyA(long long ptr ptr ptr long) -@ stdcall CM_Get_DevNode_Registry_PropertyW(long long ptr ptr ptr long) -@ stdcall CM_Get_DevNode_Registry_Property_ExA(long long ptr ptr ptr long long) -@ stdcall CM_Get_DevNode_Registry_Property_ExW(long long ptr ptr ptr long long) -@ stdcall CM_Get_DevNode_Status(ptr ptr long long) -@ stdcall CM_Get_DevNode_Status_Ex(ptr ptr long long long) -@ stdcall CM_Get_Device_IDA(long str long long) -@ stdcall CM_Get_Device_IDW(long wstr long long) -@ stdcall CM_Get_Device_ID_ExA(long str long long long) -@ stdcall CM_Get_Device_ID_ExW(long wstr long long long) -@ stdcall CM_Get_Device_ID_ListA(str str long long) -@ stdcall CM_Get_Device_ID_ListW(wstr wstr long long) -@ stdcall CM_Get_Device_ID_List_ExA(str str long long long) -@ stdcall CM_Get_Device_ID_List_ExW(wstr wstr long long long) -@ stdcall CM_Get_Device_ID_List_SizeA(ptr str long) -@ stdcall CM_Get_Device_ID_List_SizeW(ptr wstr long) -@ stdcall CM_Get_Device_ID_List_Size_ExA(ptr str long long) -@ stdcall CM_Get_Device_ID_List_Size_ExW(ptr wstr long long) -@ stdcall CM_Get_Device_ID_Size(ptr long long) -@ stdcall CM_Get_Device_ID_Size_Ex(ptr long long long) -@ stdcall CM_Get_Device_Interface_AliasA(str ptr str ptr long) -@ stdcall CM_Get_Device_Interface_AliasW(wstr ptr wstr ptr long) -@ stdcall CM_Get_Device_Interface_Alias_ExA(str ptr str ptr long long) -@ stdcall CM_Get_Device_Interface_Alias_ExW(wstr ptr wstr ptr long long) -@ stdcall CM_Get_Device_Interface_ListA(ptr str str long long) -@ stdcall CM_Get_Device_Interface_ListW(ptr wstr wstr long long) -@ stdcall CM_Get_Device_Interface_List_ExA(ptr str str long long ptr) -@ stdcall CM_Get_Device_Interface_List_ExW(ptr wstr wstr long long ptr) -@ stdcall CM_Get_Device_Interface_List_SizeA(ptr ptr str long) -@ stdcall CM_Get_Device_Interface_List_SizeW(ptr ptr wstr long) -@ stdcall CM_Get_Device_Interface_List_Size_ExA(ptr ptr str long ptr) -@ stdcall CM_Get_Device_Interface_List_Size_ExW(ptr ptr wstr long ptr) -@ stdcall CM_Get_First_Log_Conf(ptr long long) -@ stdcall CM_Get_First_Log_Conf_Ex(ptr long long long) -@ stdcall CM_Get_Global_State(ptr long) -@ stdcall CM_Get_Global_State_Ex(ptr long long) -@ stdcall CM_Get_HW_Prof_FlagsA(str long ptr long) -@ stdcall CM_Get_HW_Prof_FlagsW(wstr long ptr long) -@ stdcall CM_Get_HW_Prof_Flags_ExA(str long ptr long long) -@ stdcall CM_Get_HW_Prof_Flags_ExW(wstr long ptr long long) -@ stdcall CM_Get_Hardware_Profile_InfoA(long ptr long) -@ stdcall CM_Get_Hardware_Profile_InfoW(long ptr long) -@ stdcall CM_Get_Hardware_Profile_Info_ExA(long ptr long long) -@ stdcall CM_Get_Hardware_Profile_Info_ExW(long ptr long long) -@ stdcall CM_Get_Log_Conf_Priority(ptr ptr long) -@ stdcall CM_Get_Log_Conf_Priority_Ex(ptr ptr long long) -@ stdcall CM_Get_Next_Log_Conf(ptr ptr long) -@ stdcall CM_Get_Next_Log_Conf_Ex(ptr ptr long long) -@ stdcall CM_Get_Next_Res_Des(ptr ptr long ptr long) -@ stdcall CM_Get_Next_Res_Des_Ex(ptr ptr long ptr long long) -@ stdcall CM_Get_Parent(ptr long long) -@ stdcall CM_Get_Parent_Ex(ptr long long long) -@ stdcall CM_Get_Res_Des_Data(ptr ptr long long) -@ stdcall CM_Get_Res_Des_Data_Ex(ptr ptr long long long) -@ stdcall CM_Get_Res_Des_Data_Size(ptr ptr long) -@ stdcall CM_Get_Res_Des_Data_Size_Ex(ptr ptr long long) -@ stdcall CM_Get_Resource_Conflict_Count(ptr ptr) -@ stdcall CM_Get_Resource_Conflict_DetailsA(ptr long ptr) -@ stdcall CM_Get_Resource_Conflict_DetailsW(ptr long ptr) -@ stdcall CM_Get_Sibling(ptr long long) -@ stdcall CM_Get_Sibling_Ex(ptr long long long) -@ stdcall CM_Get_Version() -@ stdcall CM_Get_Version_Ex(long) -@ stdcall CM_Intersect_Range_List(ptr ptr ptr long) -@ stdcall CM_Invert_Range_List(ptr ptr long long) -@ stdcall CM_Is_Dock_Station_Present(ptr) -@ stdcall CM_Is_Dock_Station_Present_Ex(ptr long) -@ stdcall CM_Is_Version_Available(long) -@ stdcall CM_Is_Version_Available_Ex(long long) -@ stdcall CM_Locate_DevNodeA(ptr str long) -@ stdcall CM_Locate_DevNodeW(ptr wstr long) -@ stdcall CM_Locate_DevNode_ExA(ptr str long long) -@ stdcall CM_Locate_DevNode_ExW(ptr wstr long long) -@ stdcall CM_Merge_Range_List(ptr ptr ptr long) -@ stdcall CM_Modify_Res_Des(ptr ptr long ptr long long) -@ stdcall CM_Modify_Res_Des_Ex(ptr ptr long ptr long long long) -@ stdcall CM_Move_DevNode(long long long) -@ stdcall CM_Move_DevNode_Ex(long long long long) -@ stdcall CM_Next_Range(ptr ptr ptr long) -@ stdcall CM_Open_Class_KeyA(ptr str long long ptr long) -@ stdcall CM_Open_Class_KeyW(ptr wstr long long ptr long) -@ stdcall CM_Open_Class_Key_ExA(ptr str long long ptr long long) -@ stdcall CM_Open_Class_Key_ExW(ptr wstr long long ptr long long) -@ stdcall CM_Open_DevNode_Key(ptr long long long ptr long) -@ stdcall CM_Open_DevNode_Key_Ex(ptr long long long ptr long long) -@ stdcall CM_Query_And_Remove_SubTreeA(long ptr str long long) -@ stdcall CM_Query_And_Remove_SubTreeW(long ptr wstr long long) -@ stdcall CM_Query_And_Remove_SubTree_ExA(long ptr str long long long) -@ stdcall CM_Query_And_Remove_SubTree_ExW(long ptr wstr long long long) -@ stdcall CM_Query_Arbitrator_Free_Data(ptr long long long long) -@ stdcall CM_Query_Arbitrator_Free_Data_Ex(ptr long long long long ptr) -@ stdcall CM_Query_Arbitrator_Free_Size(ptr long long long) -@ stdcall CM_Query_Arbitrator_Free_Size_Ex(ptr long long long ptr) -@ stdcall CM_Query_Remove_SubTree(long long) -@ stdcall CM_Query_Remove_SubTree_Ex(long long long) -@ stdcall CM_Query_Resource_Conflict_List(ptr ptr long ptr long long ptr) -@ stdcall CM_Reenumerate_DevNode(long long) -@ stdcall CM_Reenumerate_DevNode_Ex(long long long) -@ stdcall CM_Register_Device_Driver(long long) -@ stdcall CM_Register_Device_Driver_Ex(long long ptr) -@ stdcall CM_Register_Device_InterfaceA(long ptr str str ptr long) -@ stdcall CM_Register_Device_InterfaceW(long ptr wstr wstr ptr long) -@ stdcall CM_Register_Device_Interface_ExA(long ptr str str ptr long long) -@ stdcall CM_Register_Device_Interface_ExW(long ptr wstr wstr ptr long long) -@ stdcall CM_Remove_SubTree(long long) -@ stdcall CM_Remove_SubTree_Ex(long long long) -@ stdcall CM_Request_Device_EjectA(long ptr str long long) -@ stdcall CM_Request_Device_EjectW(long ptr wstr long long) -@ stdcall CM_Request_Device_Eject_ExA(long ptr str long long long) -@ stdcall CM_Request_Device_Eject_ExW(long ptr wstr long long long) -@ stdcall CM_Request_Eject_PC() -@ stdcall CM_Request_Eject_PC_Ex(long) -@ stdcall CM_Run_Detection(long) -@ stdcall CM_Run_Detection_Ex(long long) -@ stdcall CM_Set_Class_Registry_PropertyA(ptr long ptr long long ptr) -@ stdcall CM_Set_Class_Registry_PropertyW(ptr long ptr long long ptr) -@ stdcall CM_Set_DevNode_Problem(long long long) -@ stdcall CM_Set_DevNode_Problem_Ex(long long long long) -@ stdcall CM_Set_DevNode_Registry_PropertyA(long long ptr long long) -@ stdcall CM_Set_DevNode_Registry_PropertyW(long long ptr long long) -@ stdcall CM_Set_DevNode_Registry_Property_ExA(long long ptr long long long) -@ stdcall CM_Set_DevNode_Registry_Property_ExW(long long ptr long long long) -@ stdcall CM_Set_HW_Prof(long long) -@ stdcall CM_Set_HW_Prof_Ex(long long long) -@ stdcall CM_Set_HW_Prof_FlagsA(str long long long) -@ stdcall CM_Set_HW_Prof_FlagsW(wstr long long long) -@ stdcall CM_Set_HW_Prof_Flags_ExA(str long long long long) -@ stdcall CM_Set_HW_Prof_Flags_ExW(wstr long long long long) -@ stdcall CM_Setup_DevNode(long long) -@ stdcall CM_Setup_DevNode_Ex(long long long) -@ stdcall CM_Test_Range_Available(long long ptr long) -@ stdcall CM_Uninstall_DevNode(long long) -@ stdcall CM_Uninstall_DevNode_Ex(long long long) -@ stdcall CM_Unregister_Device_InterfaceA(str long) -@ stdcall CM_Unregister_Device_InterfaceW(wstr long) -@ stdcall CM_Unregister_Device_Interface_ExA(str long long) -@ stdcall CM_Unregister_Device_Interface_ExW(wstr long long) -@ stdcall DoesUserHavePrivilege(wstr) -@ stdcall ExtensionPropSheetPageProc(long ptr long) -@ stdcall InstallCatalog(str str ptr) -@ stdcall InstallHinfSection(long long str long) InstallHinfSectionA -@ stdcall InstallHinfSectionA(long long str long) -@ stdcall InstallHinfSectionW(long long wstr long) -@ stdcall IsUserAdmin() pSetupIsUserAdmin -@ stdcall MyFree(ptr) -@ stdcall MyMalloc(long) -@ stdcall MyRealloc(ptr long) -@ stdcall SetupAddInstallSectionToDiskSpaceListA(long long long str ptr long) -@ stdcall SetupAddInstallSectionToDiskSpaceListW(ptr ptr ptr wstr ptr long) -@ stdcall SetupAddSectionToDiskSpaceListA(ptr ptr ptr str long ptr long) -@ stdcall SetupAddSectionToDiskSpaceListW(ptr ptr ptr wstr long ptr long) -@ stdcall SetupAddToDiskSpaceListA(ptr str long long long ptr long) -@ stdcall SetupAddToDiskSpaceListW(ptr wstr long long long ptr long) -@ stdcall SetupAddToSourceListA(long str) -@ stdcall SetupAddToSourceListW(long wstr) -@ stdcall SetupAdjustDiskSpaceListA(ptr str long long ptr long) -@ stdcall SetupAdjustDiskSpaceListW(ptr wstr long long ptr long) -@ stdcall SetupBackupErrorA(ptr str str str long long) -@ stdcall SetupBackupErrorW(ptr wstr wstr wstr long long) -@ stdcall SetupCancelTemporarySourceList() -@ stdcall SetupCloseFileQueue(ptr) -@ stdcall SetupCloseInfFile(long) -@ stdcall SetupCloseLog() -@ stdcall SetupCommitFileQueue(long long ptr ptr) SetupCommitFileQueueA -@ stdcall SetupCommitFileQueueA(long long ptr ptr) -@ stdcall SetupCommitFileQueueW(long long ptr ptr) -@ stdcall SetupCopyErrorA(long str str str str str long long str long ptr) -@ stdcall SetupCopyErrorW(long wstr wstr wstr wstr wstr long long wstr long ptr) -@ stdcall SetupCopyOEMInfA(str str long long ptr long ptr ptr) -@ stdcall SetupCopyOEMInfW(wstr wstr long long ptr long ptr ptr) -@ stdcall SetupCreateDiskSpaceListA(ptr long long) -@ stdcall SetupCreateDiskSpaceListW(ptr long long) -@ stdcall SetupDecompressOrCopyFileA(str str ptr) -@ stdcall SetupDecompressOrCopyFileW(wstr wstr ptr) -@ stdcall SetupDefaultQueueCallback(ptr long long long) SetupDefaultQueueCallbackA -@ stdcall SetupDefaultQueueCallbackA(ptr long long long) -@ stdcall SetupDefaultQueueCallbackW(ptr long long long) -@ stdcall SetupDeleteErrorA(long str str long long) -@ stdcall SetupDeleteErrorW(long wstr wstr long long) -@ stdcall SetupDestroyDiskSpaceList(long) -@ stdcall SetupDiAskForOEMDisk(ptr ptr) -@ stdcall SetupDiBuildClassInfoList(long ptr long ptr) -@ stdcall SetupDiBuildClassInfoListExA(long ptr long ptr str ptr) -@ stdcall SetupDiBuildClassInfoListExW(long ptr long ptr wstr ptr) -@ stdcall SetupDiBuildDriverInfoList(long ptr long) -@ stdcall SetupDiCallClassInstaller(long ptr ptr) -@ stdcall SetupDiCancelDriverInfoSearch(ptr) -@ stdcall SetupDiChangeState(ptr ptr) -@ stdcall SetupDiClassGuidsFromNameA(str ptr long ptr) -@ stdcall SetupDiClassGuidsFromNameExA(str ptr long ptr str ptr) -@ stdcall SetupDiClassGuidsFromNameExW(wstr ptr long ptr wstr ptr) -@ stdcall SetupDiClassGuidsFromNameW(wstr ptr long ptr) -@ stdcall SetupDiClassNameFromGuidA(ptr str long ptr) -@ stdcall SetupDiClassNameFromGuidExA(ptr str long ptr wstr ptr) -@ stdcall SetupDiClassNameFromGuidExW(ptr wstr long ptr wstr ptr) -@ stdcall SetupDiClassNameFromGuidW(ptr wstr long ptr) -@ stdcall SetupDiCreateDevRegKeyA(ptr ptr long long long ptr str) -@ stdcall SetupDiCreateDevRegKeyW(ptr ptr long long long ptr wstr) -@ stdcall SetupDiCreateDeviceInfoA(ptr str ptr str ptr long ptr) -@ stdcall SetupDiCreateDeviceInfoList(ptr ptr) -@ stdcall SetupDiCreateDeviceInfoListExA(ptr long str ptr) -@ stdcall SetupDiCreateDeviceInfoListExW(ptr long wstr ptr) -@ stdcall SetupDiCreateDeviceInfoW(ptr wstr ptr wstr ptr long ptr) -@ stdcall SetupDiCreateDeviceInterfaceA(ptr ptr ptr str long ptr) -@ stdcall SetupDiCreateDeviceInterfaceRegKeyA(ptr ptr long long ptr ptr) -@ stdcall SetupDiCreateDeviceInterfaceRegKeyW(ptr ptr long long ptr ptr) -@ stdcall SetupDiCreateDeviceInterfaceW(ptr ptr ptr wstr long ptr) -@ stdcall SetupDiDeleteDevRegKey(ptr ptr long long long) -@ stdcall SetupDiDeleteDeviceInfo(long ptr) -@ stdcall SetupDiDeleteDeviceInterfaceData(ptr ptr) -@ stdcall SetupDiDeleteDeviceInterfaceRegKey(ptr ptr long) -@ stdcall SetupDiDestroyClassImageList(ptr) -@ stdcall SetupDiDestroyDeviceInfoList(long) -@ stdcall SetupDiDestroyDriverInfoList(long ptr long) -@ stdcall SetupDiDrawMiniIcon(ptr ptr long long) -@ stdcall SetupDiEnumDeviceInfo(long long ptr) -@ stdcall SetupDiEnumDeviceInterfaces(long ptr ptr long ptr) -@ stdcall SetupDiEnumDriverInfoA(long ptr long long ptr) -@ stdcall SetupDiEnumDriverInfoW(long ptr long long ptr) -@ stdcall SetupDiGetActualSectionToInstallA(long str str long ptr ptr) -@ stdcall SetupDiGetActualSectionToInstallExA(long str ptr str long ptr ptr ptr) -@ stdcall SetupDiGetActualSectionToInstallExW(long wstr ptr wstr long ptr ptr ptr) -@ stdcall SetupDiGetActualSectionToInstallW(long wstr wstr long ptr ptr) -@ stdcall SetupDiGetClassBitmapIndex(ptr ptr) -@ stdcall SetupDiGetClassDescriptionA(ptr str long ptr) -@ stdcall SetupDiGetClassDescriptionExA(ptr str long ptr str ptr) -@ stdcall SetupDiGetClassDescriptionExW(ptr wstr long ptr wstr ptr) -@ stdcall SetupDiGetClassDescriptionW(ptr wstr long ptr) -@ stdcall SetupDiGetClassDevPropertySheetsA(ptr ptr ptr long ptr long) -@ stdcall SetupDiGetClassDevPropertySheetsW(ptr ptr ptr long ptr long) -@ stdcall SetupDiGetClassDevsA(ptr ptr long long) -@ stdcall SetupDiGetClassDevsExA(ptr str ptr long ptr str ptr) -@ stdcall SetupDiGetClassDevsExW(ptr wstr ptr long ptr wstr ptr) -@ stdcall SetupDiGetClassDevsW(ptr ptr long long) -@ stdcall SetupDiGetClassImageIndex(ptr ptr ptr) -@ stdcall SetupDiGetClassImageList(ptr) -@ stdcall SetupDiGetClassImageListExA(ptr str ptr) -@ stdcall SetupDiGetClassImageListExW(ptr wstr ptr) -@ stdcall SetupDiGetClassInstallParamsA(ptr ptr ptr long ptr) -@ stdcall SetupDiGetClassInstallParamsW(ptr ptr ptr long ptr) -@ stdcall SetupDiGetClassRegistryPropertyA(ptr long ptr ptr long ptr str ptr) -@ stdcall SetupDiGetClassRegistryPropertyW(ptr long ptr ptr long ptr wstr ptr) -@ stdcall SetupDiGetCustomDevicePropertyA(ptr ptr str long ptr ptr long ptr) -@ stdcall SetupDiGetCustomDevicePropertyW(ptr ptr wstr long ptr ptr long ptr) -@ stdcall SetupDiGetDeviceInfoListClass(ptr ptr) -@ stdcall SetupDiGetDeviceInfoListDetailA(ptr ptr) -@ stdcall SetupDiGetDeviceInfoListDetailW(ptr ptr) -@ stdcall SetupDiGetDeviceInstallParamsA(ptr ptr ptr) -@ stdcall SetupDiGetDeviceInstallParamsW(ptr ptr ptr) -@ stdcall SetupDiGetDeviceInstanceIdA(ptr ptr str long ptr) -@ stdcall SetupDiGetDeviceInstanceIdW(ptr ptr wstr long ptr) -@ stdcall SetupDiGetDeviceInterfaceAlias(ptr ptr ptr ptr) -@ stdcall SetupDiGetDeviceInterfaceDetailA(long ptr ptr long ptr ptr) -@ stdcall SetupDiGetDeviceInterfaceDetailW(long ptr ptr long ptr ptr) -@ stdcall SetupDiGetDeviceRegistryPropertyA(long ptr long ptr ptr long ptr) -@ stdcall SetupDiGetDeviceRegistryPropertyW(long ptr long ptr ptr long ptr) -@ stdcall SetupDiGetDriverInfoDetailA(ptr ptr ptr ptr long ptr) -@ stdcall SetupDiGetDriverInfoDetailW(ptr ptr ptr ptr long ptr) -@ stdcall SetupDiGetDriverInstallParamsA(ptr ptr ptr ptr) -@ stdcall SetupDiGetDriverInstallParamsW(ptr ptr ptr ptr) -@ stdcall SetupDiGetHwProfileFriendlyNameA(long str long ptr) -@ stdcall SetupDiGetHwProfileFriendlyNameExA(long str long ptr str ptr) -@ stdcall SetupDiGetHwProfileFriendlyNameExW(long wstr long ptr wstr ptr) -@ stdcall SetupDiGetHwProfileFriendlyNameW(long wstr long ptr) -@ stdcall SetupDiGetHwProfileList(ptr long ptr ptr) -@ stdcall SetupDiGetHwProfileListExA(ptr long ptr ptr str ptr) -@ stdcall SetupDiGetHwProfileListExW(ptr long ptr ptr wstr ptr) -@ stdcall SetupDiGetINFClassA(str ptr ptr long ptr) -@ stdcall SetupDiGetINFClassW(wstr ptr ptr long ptr) -@ stdcall SetupDiGetSelectedDevice(ptr ptr) -@ stdcall SetupDiGetSelectedDriverA(ptr ptr ptr) -@ stdcall SetupDiGetSelectedDriverW(ptr ptr ptr) -@ stdcall SetupDiGetWizardPage(ptr ptr ptr long long) -@ stdcall SetupDiInstallClassA(long str long ptr) -@ stdcall SetupDiInstallClassExA(long str long ptr ptr ptr ptr) -@ stdcall SetupDiInstallClassExW(long wstr long ptr ptr ptr ptr) -@ stdcall SetupDiInstallClassW(long wstr long ptr) -@ stdcall SetupDiInstallDevice(ptr ptr) -@ stdcall SetupDiInstallDeviceInterfaces(ptr ptr) -@ stdcall SetupDiInstallDriverFiles(ptr ptr) -@ stdcall SetupDiLoadClassIcon(ptr ptr ptr) -@ stdcall SetupDiMoveDuplicateDevice(ptr ptr) -@ stdcall SetupDiOpenClassRegKey(ptr long) -@ stdcall SetupDiOpenClassRegKeyExA(ptr long long str ptr) -@ stdcall SetupDiOpenClassRegKeyExW(ptr long long wstr ptr) -@ stdcall SetupDiOpenDevRegKey(ptr ptr long long long long) -@ stdcall SetupDiOpenDeviceInfoA(ptr str long long ptr) -@ stdcall SetupDiOpenDeviceInfoW(ptr wstr long long ptr) -@ stdcall SetupDiOpenDeviceInterfaceA(ptr str long ptr) -@ stdcall SetupDiOpenDeviceInterfaceRegKey(ptr ptr long long) -@ stdcall SetupDiOpenDeviceInterfaceW(ptr wstr long ptr) -@ stdcall SetupDiRegisterCoDeviceInstallers(ptr ptr) -@ stdcall SetupDiRegisterDeviceInfo(ptr ptr long ptr ptr ptr) -@ stdcall SetupDiRemoveDevice(ptr ptr) -@ stdcall SetupDiRemoveDeviceInterface(ptr ptr) -@ stdcall SetupDiSelectBestCompatDrv(ptr ptr) -@ stdcall SetupDiSelectDevice(ptr ptr) -@ stdcall SetupDiSelectOEMDrv(ptr ptr ptr) -@ stdcall SetupDiSetClassInstallParamsA(ptr ptr ptr long) -@ stdcall SetupDiSetClassInstallParamsW(ptr ptr ptr long) -@ stdcall SetupDiSetClassRegistryPropertyA(ptr long ptr long str ptr) -@ stdcall SetupDiSetClassRegistryPropertyW(ptr long ptr long wstr ptr) -@ stdcall SetupDiSetDeviceInstallParamsA(ptr ptr ptr) -@ stdcall SetupDiSetDeviceInstallParamsW(ptr ptr ptr) -@ stdcall SetupDiSetDeviceInterfaceDefault(ptr ptr long ptr) -@ stdcall SetupDiSetDeviceRegistryPropertyA(ptr ptr long ptr long) -@ stdcall SetupDiSetDeviceRegistryPropertyW(ptr ptr long ptr long) -@ stdcall SetupDiSetDriverInstallParamsA(ptr ptr ptr ptr) -@ stdcall SetupDiSetDriverInstallParamsW(ptr ptr ptr ptr) -@ stdcall SetupDiSetSelectedDevice(ptr ptr) -@ stdcall SetupDiSetSelectedDriverA(ptr ptr ptr) -@ stdcall SetupDiSetSelectedDriverW(ptr ptr ptr) -@ stdcall SetupDiUnremoveDevice(ptr ptr) -@ stdcall SetupDuplicateDiskSpaceListA(ptr ptr long long) -@ stdcall SetupDuplicateDiskSpaceListW(ptr ptr long long) -@ stdcall SetupEnumInfSectionsA(long long ptr long ptr) -@ stdcall SetupEnumInfSectionsW(long long ptr long ptr) -@ stdcall SetupFindFirstLineA(long str str ptr) -@ stdcall SetupFindFirstLineW(long wstr wstr ptr) -@ stdcall SetupFindNextLine(ptr ptr) -@ stdcall SetupFindNextMatchLineA(ptr str ptr) -@ stdcall SetupFindNextMatchLineW(ptr wstr ptr) -@ stdcall SetupFreeSourceListA(str long) -@ stdcall SetupFreeSourceListW(wstr long) -@ stdcall SetupGetBackupInformationA(ptr ptr) -@ stdcall SetupGetBackupInformationW(ptr ptr) -@ stdcall SetupGetBinaryField(ptr long ptr long ptr) -@ stdcall SetupGetFieldCount(ptr) -@ stdcall SetupGetFileCompressionInfoA(str ptr ptr ptr ptr) -@ stdcall SetupGetFileCompressionInfoExA(str ptr long ptr ptr ptr ptr) -@ stdcall SetupGetFileCompressionInfoExW(wstr ptr long ptr ptr ptr ptr) -@ stdcall SetupGetFileCompressionInfoW(wstr ptr ptr ptr ptr) -@ stdcall SetupGetFileQueueCount(long long ptr) -@ stdcall SetupGetFileQueueFlags(long ptr) -@ stdcall SetupGetInfFileListA(str long str long ptr) -@ stdcall SetupGetInfFileListW(wstr long wstr long ptr) -@ stdcall SetupGetInfInformationA(ptr long ptr long ptr) -@ stdcall SetupGetInfInformationW(ptr long ptr long ptr) -@ stdcall SetupGetInfSections(ptr ptr ptr ptr) -@ stdcall SetupGetIntField(ptr long ptr) -@ stdcall SetupGetLineByIndexA(long str long ptr) -@ stdcall SetupGetLineByIndexW(long wstr long ptr) -@ stdcall SetupGetLineCountA(long str) -@ stdcall SetupGetLineCountW(long wstr) -@ stdcall SetupGetLineTextA(ptr long str str ptr long ptr) -@ stdcall SetupGetLineTextW(ptr long wstr wstr ptr long ptr) -@ stdcall SetupGetMultiSzFieldA(ptr long ptr long ptr) -@ stdcall SetupGetMultiSzFieldW(ptr long ptr long ptr) -@ stdcall SetupGetNonInteractiveMode() -@ stdcall SetupGetSourceFileLocationA(ptr ptr str ptr ptr long ptr) -@ stdcall SetupGetSourceFileLocationW(ptr ptr wstr ptr ptr long ptr) -@ stdcall SetupGetSourceFileSizeA(ptr ptr str str ptr long) -@ stdcall SetupGetSourceFileSizeW(ptr ptr wstr wstr ptr long) -@ stdcall SetupGetSourceInfoA(ptr long long ptr long ptr) -@ stdcall SetupGetSourceInfoW(ptr long long ptr long ptr) -@ stdcall SetupGetStringFieldA(ptr long ptr long ptr) -@ stdcall SetupGetStringFieldW(ptr long ptr long ptr) -@ stdcall SetupGetTargetPathA(ptr ptr str ptr long ptr) -@ stdcall SetupGetTargetPathW(ptr ptr wstr ptr long ptr) -@ stdcall SetupInitDefaultQueueCallback(long) -@ stdcall SetupInitDefaultQueueCallbackEx(long long long long ptr) -@ stdcall SetupInitializeFileLogA(str long) -@ stdcall SetupInitializeFileLogW(wstr long) -@ stdcall SetupInstallFileA(ptr ptr str str str long ptr ptr) -@ stdcall SetupInstallFileExA(ptr ptr str str str long ptr ptr ptr) -@ stdcall SetupInstallFileExW(ptr ptr wstr wstr wstr long ptr ptr ptr) -@ stdcall SetupInstallFileW(ptr ptr wstr wstr wstr long ptr ptr) -@ stdcall SetupInstallFilesFromInfSectionA(long long long str str long) -@ stdcall SetupInstallFilesFromInfSectionW(long long long wstr wstr long) -@ stdcall SetupInstallFromInfSectionA(long long str long long str long ptr ptr long ptr) -@ stdcall SetupInstallFromInfSectionW(long long wstr long long wstr long ptr ptr long ptr) -@ stdcall SetupInstallServicesFromInfSectionA(long str long) -@ stdcall SetupInstallServicesFromInfSectionExA(long str long ptr ptr ptr ptr) -@ stdcall SetupInstallServicesFromInfSectionExW(long wstr long ptr ptr ptr ptr) -@ stdcall SetupInstallServicesFromInfSectionW(long wstr long) -@ stdcall SetupIterateCabinetA(str long ptr ptr) -@ stdcall SetupIterateCabinetW(wstr long ptr ptr) -@ stdcall SetupLogErrorA(str long) -@ stdcall SetupLogErrorW(wstr long) -@ stdcall SetupLogFileA(ptr str str str long str str str long) -@ stdcall SetupLogFileW(ptr wstr wstr wstr long wstr wstr wstr long) -@ stdcall SetupOpenAppendInfFileA(str long ptr) -@ stdcall SetupOpenAppendInfFileW(wstr long ptr) -@ stdcall SetupOpenFileQueue() -@ stdcall SetupOpenInfFileA(str str long ptr) -@ stdcall SetupOpenInfFileW(wstr wstr long ptr) -@ stdcall SetupOpenLog(long) -@ stdcall SetupOpenMasterInf() -@ stdcall SetupPrepareQueueForRestoreA(ptr str long) -@ stdcall SetupPrepareQueueForRestoreW(ptr wstr long) -@ stdcall SetupPromptForDiskA(ptr str str str str str long ptr long ptr) -@ stdcall SetupPromptForDiskW(ptr wstr wstr wstr wstr wstr long ptr long ptr) -@ stdcall SetupPromptReboot(ptr ptr long) -@ stdcall SetupQueryDrivesInDiskSpaceListA(ptr str long ptr) -@ stdcall SetupQueryDrivesInDiskSpaceListW(ptr wstr long ptr) -@ stdcall SetupQueryFileLogA(ptr str str ptr str long ptr) -@ stdcall SetupQueryFileLogW(ptr wstr wstr ptr wstr long ptr) -@ stdcall SetupQueryInfFileInformationA(ptr long str long ptr) -@ stdcall SetupQueryInfFileInformationW(ptr long wstr long ptr) -@ stdcall SetupQueryInfOriginalFileInformationA(ptr long ptr ptr) -@ stdcall SetupQueryInfOriginalFileInformationW(ptr long ptr ptr) -@ stdcall SetupQueryInfVersionInformationA(ptr long str str long ptr) -@ stdcall SetupQueryInfVersionInformationW(ptr long wstr wstr long ptr) -@ stdcall SetupQuerySourceListA(long str ptr) -@ stdcall SetupQuerySourceListW(long wstr ptr) -@ stdcall SetupQuerySpaceRequiredOnDriveA(long str ptr ptr long) -@ stdcall SetupQuerySpaceRequiredOnDriveW(long wstr ptr ptr long) -@ stdcall SetupQueueCopyA(long str str str str str str str long) -@ stdcall SetupQueueCopyIndirectA(ptr) -@ stdcall SetupQueueCopyIndirectW(ptr) -@ stdcall SetupQueueCopySectionA(long str long long str long) -@ stdcall SetupQueueCopySectionW(long wstr long long wstr long) -@ stdcall SetupQueueCopyW(long wstr wstr wstr wstr wstr wstr wstr long) -@ stdcall SetupQueueDefaultCopyA(long long str str str long) -@ stdcall SetupQueueDefaultCopyW(long long wstr wstr wstr long) -@ stdcall SetupQueueDeleteA(long str str) -@ stdcall SetupQueueDeleteSectionA(long long long str) -@ stdcall SetupQueueDeleteSectionW(long long long wstr) -@ stdcall SetupQueueDeleteW(long wstr wstr) -@ stdcall SetupQueueRenameA(long str str str str) -@ stdcall SetupQueueRenameSectionA(long long long str) -@ stdcall SetupQueueRenameSectionW(long long long wstr) -@ stdcall SetupQueueRenameW(long wstr wstr wstr wstr) -@ stdcall SetupRemoveFileLogEntryA(ptr str str) -@ stdcall SetupRemoveFileLogEntryW(ptr wstr wstr) -@ stdcall SetupRemoveFromDiskSpaceListA(ptr str long ptr long) -@ stdcall SetupRemoveFromDiskSpaceListW(ptr wstr long ptr long) -@ stdcall SetupRemoveFromSourceListA(long str) -@ stdcall SetupRemoveFromSourceListW(long wstr) -@ stdcall SetupRemoveInstallSectionFromDiskSpaceListA(ptr ptr ptr str ptr long) -@ stdcall SetupRemoveInstallSectionFromDiskSpaceListW(ptr ptr ptr wstr ptr long) -@ stdcall SetupRemoveSectionFromDiskSpaceListA(ptr ptr ptr str long ptr long) -@ stdcall SetupRemoveSectionFromDiskSpaceListW(ptr ptr ptr wstr long ptr long) -@ stdcall SetupRenameErrorA(long str str str long long) -@ stdcall SetupRenameErrorW(long wstr wstr wstr long long) -@ stdcall SetupScanFileQueue(long long long ptr ptr ptr) SetupScanFileQueueA -@ stdcall SetupScanFileQueueA(long long long ptr ptr ptr) -@ stdcall SetupScanFileQueueW(long long long ptr ptr ptr) -@ stdcall SetupSetDirectoryIdA(long long str) -@ stdcall SetupSetDirectoryIdExA(ptr long str long long ptr) -@ stdcall SetupSetDirectoryIdExW(ptr long wstr long long ptr) -@ stdcall SetupSetDirectoryIdW(long long wstr) -@ stdcall SetupSetFileQueueAlternatePlatformA(ptr ptr str) -@ stdcall SetupSetFileQueueAlternatePlatformW(ptr ptr wstr) -@ stdcall SetupSetFileQueueFlags(long long long) -@ stdcall SetupSetNonInteractiveMode(long) -@ stdcall SetupSetPlatformPathOverrideA(str) -@ stdcall SetupSetPlatformPathOverrideW(wstr) -@ stdcall SetupSetSourceListA(long ptr long) -@ stdcall SetupSetSourceListW(long ptr long) -@ stdcall SetupTermDefaultQueueCallback(ptr) -@ stdcall SetupTerminateFileLog(long) -@ stdcall SetupUninstallNewlyCopiedInfs(ptr long ptr) -@ stdcall SetupUninstallOEMInfA(str long ptr) -@ stdcall SetupUninstallOEMInfW(wstr long ptr) -@ stdcall SetupVerifyInfFileA(str ptr ptr) -@ stdcall SetupVerifyInfFileW(wstr ptr ptr) -@ stdcall UnicodeToMultiByte(wstr long) pSetupUnicodeToMultiByte -@ stdcall VerifyCatalogFile(long wstr long long long long) -@ stdcall pSetupAccessRunOnceNodeList() -@ stdcall pSetupAcquireSCMLock(ptr ptr) -@ stdcall pSetupAddMiniIconToList(ptr ptr) -@ stdcall pSetupAddTagToGroupOrderListEntry(wstr ptr ptr) -@ stdcall pSetupAppendStringToMultiSz(ptr wstr long wstr wstr long) -@ stdcall pSetupCaptureAndConvertAnsiArg(str ptr) -@ stdcall pSetupCenterWindowRelativeToParent(long) -@ stdcall pSetupConcatenatePaths(wstr wstr long ptr) -@ stdcall pSetupDestroyRunOnceNodeList() -@ stdcall pSetupDiGetDeviceInfoContext(ptr ptr ptr) -@ stdcall pSetupDiSetDeviceInfoContext(ptr ptr ptr) -@ stdcall pSetupDoesUserHavePrivilege(wstr) -@ stdcall pSetupDuplicateString(wstr) -@ stdcall pSetupEnablePrivilege(wstr long) -@ stdcall pSetupFree(ptr) -@ stdcall pSetupFreeStringArray(ptr ptr) -@ stdcall pSetupGetCurrentDriverSigningPolicy(ptr) -@ stdcall pSetupGetField(ptr long) -@ stdcall pSetupGetFileTitle(wstr) -@ stdcall pSetupGetGlobalFlags() -@ stdcall pSetupGetInfSections(ptr ptr ptr ptr) -@ stdcall pSetupGetQueueFlags(ptr) -@ stdcall pSetupGetRealSystemTime(ptr) -@ stdcall pSetupGetVersionInfoFromImage(wstr ptr ptr) -@ stdcall pSetupGuidFromString(wstr ptr) -@ stdcall pSetupHandleFailedVerification(ptr ptr wstr long long long long long long long) -@ stdcall pSetupInfCacheBuild(ptr) -@ stdcall pSetupInfIsFromOemLocation(wstr ptr) -@ stdcall pSetupInstallCatalog(wstr wstr ptr) -@ stdcall pSetupInstallStopEx(ptr ptr ptr) setupapibase.pSetupInstallStopEx -@ stdcall pSetupIsGuidNull(ptr) -@ stdcall pSetupIsUserAdmin() -@ stdcall pSetupMakeSurePathExists(wstr) -@ stdcall pSetupMalloc(long) -@ stdcall pSetupModifyGlobalFlags(ptr ptr) -@ stdcall pSetupMultiByteToUnicode(str long) -@ stdcall pSetupOpenAndMapFileForRead(wstr ptr ptr ptr ptr) -@ stdcall pSetupOutOfMemory(ptr) -@ stdcall pSetupQueryMultiSzValueToArray(ptr wstr wstr ptr ptr ptr) -@ stdcall pSetupRealloc(ptr long) -@ stdcall pSetupRegistryDelnode(long long) -@ stdcall pSetupRetrieveServiceConfig(ptr long) -@ stdcall pSetupSetArrayToMultiSzValue(ptr wstr wstr ptr ptr) -@ stdcall pSetupSetGlobalFlags(long) -@ stdcall pSetupSetNoDriverPrompts(long) -@ stdcall pSetupSetQueueFlags(ptr long) -@ stdcall pSetupSetSystemSourcePath(wstr ptr) -@ stdcall pSetupShouldDeviceBeExcluded(wstr ptr ptr) -@ stdcall pSetupStringFromGuid(ptr wstr long) -@ stdcall pSetupStringTableAddString(ptr wstr long) -@ stdcall pSetupStringTableAddStringEx(ptr wstr long ptr long) -@ stdcall pSetupStringTableDestroy(ptr) -@ stdcall pSetupStringTableDuplicate(ptr) -@ stdcall pSetupStringTableEnum(ptr ptr ptr ptr ptr) -@ stdcall pSetupStringTableGetExtraData(ptr long ptr long) -@ stdcall pSetupStringTableInitialize() -@ stdcall pSetupStringTableInitializeEx(long long) -@ stdcall pSetupStringTableLookUpString(ptr wstr long) -@ stdcall pSetupStringTableLookUpStringEx(ptr wstr long ptr ptr) -@ stdcall pSetupStringTableSetExtraData(ptr long ptr long) -@ stdcall pSetupStringTableStringFromId(ptr long) -@ stdcall pSetupStringTableStringFromIdEx(ptr long ptr ptr) -@ stdcall pSetupUnicodeToMultiByte(wstr long) -@ stdcall pSetupUnmapAndCloseFile(long long ptr) -@ stdcall pSetupVerifyCatalogFile(wstr) -@ stdcall pSetupVerifyFile(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) -@ stdcall pSetupVerifyQueuedCatalogs(ptr) -@ stdcall pSetupWriteLogEntry(ptr ptr long ptr str) -@ stdcall pSetupWriteLogError(ptr ptr long) - -#Hooks -@ stdcall CMP_WaitNoPendingInstallEvents(long) CMP_WaitNoPendingInstallEventsInternal - -#Missing on XP -@ stdcall SetupConfigureWmiFromInfSectionA(ptr ptr str) setupapibase.SetupConfigureWmiFromInfSectionA -@ stdcall SetupConfigureWmiFromInfSectionW(ptr ptr wstr) setupapibase.SetupConfigureWmiFromInfSectionW -@ stdcall SetupDiGetActualModelsSectionA(ptr ptr ptr long ptr ptr) setupapibase.SetupDiGetActualModelsSectionA -@ stdcall SetupDiGetActualModelsSectionW(ptr ptr ptr long ptr ptr) setupapibase.SetupDiGetActualModelsSectionW -@ stdcall SetupDiRestartDevices(ptr ptr) ;setupapibase.SetupDiRestartDevices -@ stdcall pSetupIsLocalSystem() setupapibase.pSetupIsLocalSystem - -; #From Native Vista Setupapi.dll -; @ stdcall CM_Install_DevNode_ExW(long long long long long long ptr long long) setupapibase.CM_Install_DevNode_ExW -; @ stdcall CM_Install_DevNodeW(long long long long long long ptr long) setupapibase.CM_Install_DevNodeW -; @ stdcall pSetupDiGetStrongNameForDriverNode(long long ptr wstr long long) setupapibase.pSetupDiGetStrongNameForDriverNode -; @ stdcall pSetupDiInvalidateHelperModules(long long long) setupapibase.pSetupDiInvalidateHelperModules -; @ stdcall SetupCloseTextLogSection(long long long long long) setupapibase.SetupCloseTextLogSection -; @ stdcall SetupCreateTextLogSectionW(wstr long wstr long) setupapibase.SetupCreateTextLogSectionW -; @ stdcall SetupDiReportPnPDeviceProblem(ptr ptr long long) setupapibase.SetupDiReportPnPDeviceProblem -; @ stdcall SetupWriteTextLog(long long long long ptr) setupapibase.SetupWriteTextLog -; @ stdcall SetupGetThreadLogToken() setupapibase.SetupGetThreadLogToken -; @ stdcall SetupSetThreadLogToken(long) setupapibase.SetupSetThreadLogToken -; @ stdcall SetupDiReportDriverNotFoundError(ptr ptr long) setupapibase.SetupDiReportDriverNotFoundError -; @ stdcall SetupDiLoadDeviceIcon(long ptr long long long ptr) setupapibase.SetupDiLoadDeviceIcon -; @ stdcall SetupDiGetDevicePropertyKeys(long ptr ptr long ptr long) setupapibase.SetupDiGetDevicePropertyKeys -; @ stdcall SetupDiGetClassPropertyExW(ptr ptr ptr ptr long ptr long wstr ptr) setupapibase.SetupDiGetClassPropertyExW -; @ stdcall SetupDiGetClassPropertyKeysExW(ptr ptr long ptr long wstr ptr) setupapibase.SetupDiGetClassPropertyKeysExW - -#Vista functions -@ stdcall CM_Get_Device_Interface_PropertyW(wstr ptr ptr ptr ptr long) -@ stdcall CM_Get_DevNode_PropertyW(long ptr ptr ptr ptr long) -@ stdcall SetupGetInfDriverStoreLocationW(wstr ptr wstr ptr long ptr) -@ stdcall SetupDiGetDevicePropertyW(ptr ptr ptr ptr ptr long ptr long) -@ stdcall SetupDiSetDevicePropertyW(ptr ptr ptr long ptr long long) - -#Win7 functions -@ stdcall CM_MapCrToWin32Err(long long) - -#Win8 functions -@ stdcall CM_Register_Notification(ptr ptr ptr ptr) -@ stdcall CM_Unregister_Notification(ptr) \ No newline at end of file diff --git a/wrappers/extensions/setupext/version.rc b/wrappers/extensions/setupext/version.rc deleted file mode 100644 index 373f540a3d..0000000000 --- a/wrappers/extensions/setupext/version.rc +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2009 Henri Verbeet for CodeWeavers - * - * 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 - */ - -#define WINE_FILEDESCRIPTION_STR "Windows Setup API Wrapper for One-Core-API" -#define WINE_FILENAME_STR "setupapi.dll" - -#include "common_wrappers_ver.rc" \ No newline at end of file diff --git a/wrappers/extensions/shellex/CMakeLists.txt b/wrappers/extensions/shellex/CMakeLists.txt index a94da352e3..88bf198c16 100644 --- a/wrappers/extensions/shellex/CMakeLists.txt +++ b/wrappers/extensions/shellex/CMakeLists.txt @@ -10,7 +10,7 @@ include_directories(${REACTOS_SOURCE_DIR}/wrappers/dependencies/propsys) include_directories(${REACTOS_SOURCE_DIR}/wrappers/dependencies/shellbase) spec2def(shellex.dll shellex.spec) -set(baseaddress_shellex 0x6b630000) +set(baseaddress_shellex 0x6b630000) list(APPEND SOURCE assoc.c @@ -23,7 +23,6 @@ list(APPEND SOURCE misc.c path.c pidl.c - shellexec.c shellitem.c shelllink.c shellole.c diff --git a/wrappers/extensions/shellex/hooks.c b/wrappers/extensions/shellex/hooks.c index 442b8dfc72..86ace41241 100644 --- a/wrappers/extensions/shellex/hooks.c +++ b/wrappers/extensions/shellex/hooks.c @@ -125,11 +125,11 @@ BOOL WINAPI Shell_NotifyIconAInternal(DWORD dwMessage, PNOTIFYICONDATAA lpData) // lpXPData.uVersion = 3; // return Shell_NotifyIconANative(dwMessage, &lpXPData); // } - return Shell_NotifyIconANative(dwMessage, lpData); + return Shell_NotifyIconA(dwMessage, lpData); } BOOLEAN -CheckIfIsExplorerOrMsiExec(){ +CheckIfIsOSExec(){ // Get the current Process ID DWORD currentProcessId = GetCurrentProcessId(); @@ -145,17 +145,8 @@ CheckIfIsExplorerOrMsiExec(){ return FALSE; } - // // Obter o nome do executável do processo atual - // if (GetModuleFileName(NULL, processName, sizeof(processName)) == 0) { - // DbgPrint("Falha ao obter o nome do processo.\n"); - // } else { - // DbgPrint("Processo atual: %s\n", processName); - // DbgPrint("ID do processo atual: %lu\n", processId); - // DbgPrint("O nome somente do executável e: %s\n", PathFindFileName(processName)); - // } - // Compare executable name with "explorer.exe" - if ((wcsicmp(PathFindFileNameW(exePath), L"EXPLORER.EXE") == 0) || wcsicmp(PathFindFileNameW(exePath), L"MSIEXEC.EXE") == 0) { + if ((wcsicmp(PathFindFileNameW(exePath), L"EXPLORER.EXE") == 0) || wcsicmp(PathFindFileNameW(exePath), L"MSIEXEC.EXE") == 0 || wcsicmp(PathFindFileNameW(exePath), L"Rundll32.EXE") == 0 || wcsicmp(PathFindFileNameW(exePath), L"SYSOCMGR.EXE") == 0) { return TRUE; } else { return FALSE; @@ -183,7 +174,7 @@ HRESULT WINAPI DllGetClassObjectInternal(REFCLSID rclsid, REFIID iid, LPVOID *pp //TRACE("index[%u]\n", i); if(IsEqualIID(&CLSID_ShellLink, rclsid)) { - if(!CheckIfIsExplorerOrMsiExec()){ + if(!CheckIfIsOSExec()){ pcf = IDefClF_fnConstructor(InterfaceTable[i].lpfnCI, NULL, NULL); break; }else{ @@ -208,20 +199,6 @@ HRESULT WINAPI DllGetClassObjectInternal(REFCLSID rclsid, REFIID iid, LPVOID *pp return hres; } -/************************************************************************* - * ShellExecuteW [SHELL32.294] - * from shellapi.h - * WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, - * LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd); - */ -HINSTANCE WINAPI ShellExecuteWInternal(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, - LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd) -{ - //PathCchCanonicalize(lpFile, MAX_PATH, lpFile); - return ShellExecuteWNative(hwnd, lpVerb, lpFile, lpParameters, lpDirectory, nShowCmd); - -} - /************************************************************************** * Default ClassFactory Implementation * diff --git a/wrappers/extensions/shellex/main.c b/wrappers/extensions/shellex/main.c index 743071447a..762c228bad 100644 --- a/wrappers/extensions/shellex/main.c +++ b/wrappers/extensions/shellex/main.c @@ -27,32 +27,11 @@ WNDPROC lpPrevWndFunc; BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) { - DWORD bufferSize = 65535; - LPWSTR AppData; - - TRACE("fdwReason %u\n", fdwReason); - switch(fdwReason) { case DLL_PROCESS_ATTACH: shell32_hInstance = hInstDLL; - DisableThreadLibraryCalls(shell32_hInstance); - AppData = (LPWSTR)HeapAlloc(GetProcessHeap(), 8, MAX_PATH * 2); - if (!AppData) - return E_OUTOFMEMORY; - - if(GetEnvironmentVariableW(L"HOMEPATH", AppData, bufferSize) > 0 || GetEnvironmentVariableW(L"LOCALAPPDATA", AppData, bufferSize) == 0){ - SetEnvironmentVariableW(L"LOCALAPPDATA", wcscat(AppData, L"\\Local Settings\\Application Data\\")); - } - // //Hack to disable sandbox for Firefox 73+ - // if(GetEnvironmentVariableW(L"MOZ_DISABLE_CONTENT_SANDBOX", AppData, bufferSize) == 0){ - // SetEnvironmentVariableW(L"MOZ_DISABLE_CONTENT_SANDBOX", L"1"); - // } - - //SetEnvironmentVariable("COMPLUS_EnableWriteXorExecute", 0); - SetEnvironmentVariable("PROGRAMDATA", "%SYSTEMDRIVE%\\ProgramData"); - - HeapFree(GetProcessHeap(), 0, AppData); + DisableThreadLibraryCalls(shell32_hInstance); break; } diff --git a/wrappers/extensions/shellex/shellex.spec b/wrappers/extensions/shellex/shellex.spec index 887f2d8b44..1505acb9cc 100644 --- a/wrappers/extensions/shellex/shellex.spec +++ b/wrappers/extensions/shellex/shellex.spec @@ -331,6 +331,7 @@ @ stdcall RealShellExecuteA(ptr str str str str str str str long ptr) @ stdcall RealShellExecuteExA(ptr str str str str str str str long ptr long) @ stdcall RealShellExecuteExW(ptr str str str str str str str long ptr long) +@ stdcall RealShellExecuteW(ptr wstr wstr wstr wstr wstr wstr wstr long ptr) @ stdcall RegenerateUserEnvironment(ptr long) @ stdcall SHAddToRecentDocs(long ptr) @ stdcall SHAppBarMessage(long ptr) @@ -426,6 +427,7 @@ @ stdcall ShellExecuteEx(long) @ stdcall ShellExecuteExA(long) @ stdcall ShellExecuteExW(long) +@ stdcall ShellExecuteW(long wstr wstr wstr wstr long) @ stdcall ShellHookProc(long ptr ptr) @ stdcall StrChrA(str long) @ stdcall StrChrIA(str long) @@ -528,8 +530,6 @@ #Hooks @ stdcall CommandLineToArgvW(wstr ptr) CommandLineToArgvWInternal @ stdcall DllGetClassObject(ptr ptr ptr) DllGetClassObjectInternal -@ stdcall RealShellExecuteW(ptr wstr wstr wstr wstr wstr wstr wstr long ptr) ;ShellExecuteWInternal -@ stdcall ShellExecuteW(long wstr wstr wstr wstr long) ShellExecuteWInternal ;@ stdcall Shell_NotifyIcon(long ptr) Shell_NotifyIconAInternal ;Redirected to Longhorn shell ;@ stdcall Shell_NotifyIconA(long ptr) Shell_NotifyIconAInternal ;Redirected to Longhorn shell @ stdcall Shell_NotifyIconW(long ptr) Shell_NotifyIconWInternal ;Redirected to Longhorn shell diff --git a/wrappers/extensions/shellex/shellexec.c b/wrappers/extensions/shellex/shellexec.c deleted file mode 100644 index 0fc3c46bc5..0000000000 --- a/wrappers/extensions/shellex/shellexec.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Shell Library Functions - * - * Copyright 1998 Marcus Meissner - * Copyright 2002 Eric Pouech - * - * 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 -#include -#include -#include -#include - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" -#include "winreg.h" -#include "winuser.h" -#include "shlwapi.h" -#include "ddeml.h" - -#include "main.h" -#include "pidl.h" -#include "shresdef.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(exec); - diff --git a/wrappers/extensions/shellex/shlmenu.c b/wrappers/extensions/shellex/shlmenu.c index aa8946ac48..852bdab9ba 100644 --- a/wrappers/extensions/shellex/shlmenu.c +++ b/wrappers/extensions/shellex/shlmenu.c @@ -1131,7 +1131,7 @@ SHOpenWithDialog( LPCWSTR strCmd= L"shell32.dll,OpenAs_RunDLL "; StrCatW(strCmd, poainfo->pcszFile); - ShellExecuteWNative(hwnd, + ShellExecuteW(hwnd, L"open", L"Rundll32.exe", strCmd, diff --git a/wrappers/extensions/shlwext/CMakeLists.txt b/wrappers/extensions/shlwext/CMakeLists.txt deleted file mode 100644 index 75734b2f40..0000000000 --- a/wrappers/extensions/shlwext/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ - -remove_definitions(-D_WIN32_WINNT=0x502) -add_definitions(-D_WIN32_WINNT=0x600) - -add_definitions( - -D__WINESRC__ - -D_SHLWAPI_) - -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -spec2def(shlwext.dll shlwext.spec) - -list(APPEND SOURCE - assoc.c - main.c - string.c - thread.c - version.rc - ${CMAKE_CURRENT_BINARY_DIR}/shlwext_stubs.c - ${CMAKE_CURRENT_BINARY_DIR}/shlwext.def) - -set(baseaddress_shlwext 0x60050000) - -add_library(shlwext SHARED ${SOURCE}) -set_module_type(shlwext win32dll) -target_link_libraries(shlwext wine uuid) -add_importlibs(shlwext shlwapi advapi32 msvcrt kernel32 user32 ole32 gdi32 ntdll userenv wininet shell32 propsys) -add_cd_file(TARGET shlwext DESTINATION reactos/system32 FOR all) diff --git a/wrappers/extensions/shlwext/assoc.c b/wrappers/extensions/shlwext/assoc.c deleted file mode 100644 index 3b6226c329..0000000000 --- a/wrappers/extensions/shlwext/assoc.c +++ /dev/null @@ -1,282 +0,0 @@ -/*++ - -Copyright (c) 2024 Shorthorn Project - -Module Name: - - istream.c - -Abstract: - - This module implements Win32 Shell IStream Interface Functions - -Author: - - Skulltrail 10-September-2024 - -Revision History: - ---*/ - -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "winnls.h" -#include "winreg.h" -#include "objbase.h" -#include "shlguid.h" -#include "shlobj.h" -#include "shlwapi.h" -#include "wine/unicode.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(shlwapi); - -struct AssocPerceivedInfo -{ - PCWSTR Type; - PERCEIVED Perceived; - INT FlagHardcoded; - INT FlagSoftcoded; - PCWSTR Extensions; -}; - -static const WCHAR unspecified_exts[] = { - '.','l','n','k',0, - '.','s','e','a','r','c','h','-','m','s',0, - 0 -}; - -static const WCHAR image_exts[] = { - '.','b','m','p',0, - '.','d','i','b',0, - '.','e','m','f',0, - '.','g','i','f',0, - '.','i','c','o',0, - '.','j','f','i','f',0, - '.','j','p','e',0, - '.','j','p','e','g',0, - '.','j','p','g',0, - '.','p','n','g',0, - '.','r','l','e',0, - '.','t','i','f',0, - '.','t','i','f','f',0, - '.','w','m','f',0, - 0 -}; - -static const WCHAR audio_exts[] = { - '.','a','i','f',0, - '.','a','i','f','c',0, - '.','a','i','f','f',0, - '.','a','u',0, - '.','m','3','u',0, - '.','m','i','d',0, - '.','m','i','d','i',0, -#if _WIN32_WINNT > 0x602 - '.','m','p','2',0, -#endif - '.','m','p','3',0, - '.','r','m','i',0, - '.','s','n','d',0, - '.','w','a','v',0, - '.','w','a','x',0, - '.','w','m','a',0, - 0 -}; - -static const WCHAR video_exts[] = { - '.','a','s','f',0, - '.','a','s','x',0, - '.','a','v','i',0, - '.','d','v','r','-','m','s',0, - '.','I','V','F',0, - '.','m','1','v',0, -#if _WIN32_WINNT <= 0x602 - '.','m','p','2',0, -#endif - '.','m','p','2','v',0, - '.','m','p','a',0, - '.','m','p','e',0, - '.','m','p','e','g',0, - '.','m','p','g',0, - '.','m','p','v','2',0, - '.','w','m',0, - '.','w','m','v',0, - '.','w','m','x',0, - '.','w','v','x',0, - 0 -}; - -static const WCHAR compressed_exts[] = { - '.','z','i','p',0, - 0 -}; - -static const WCHAR document_exts[] = { -#if _WIN32_WINNT >= 0x600 - '.','h','t','m',0, - '.','h','t','m','l',0, -#endif - '.','m','h','t',0, - 0 -}; - -static const WCHAR system_exts[] = { - '.','c','p','l',0, - 0 -}; - -static const WCHAR application_exts[] = { - '.','b','a','s',0, - '.','b','a','t',0, - '.','c','m','d',0, - '.','c','o','m',0, - '.','e','x','e',0, - '.','h','t','a',0, - '.','m','s','i',0, - '.','p','i','f',0, - '.','r','e','g',0, - '.','s','c','r',0, - '.','v','b',0, - 0 -}; - -const WCHAR type_text[] = {'t','e','x','t',0}; -const WCHAR type_image[] = {'i','m','a','g','e',0}; -const WCHAR type_audio[] = {'a','u','d','i','o',0}; -const WCHAR type_video[] = {'v','i','d','e','o',0}; -const WCHAR type_compressed[] = {'c','o','m','p','r','e','s','s','e','d',0}; -const WCHAR type_document[] = {'d','o','c','u','m','e','n','t',0}; -const WCHAR type_system[] = {'s','y','s','t','e','m',0}; -const WCHAR type_application[] = {'a','p','p','l','i','c','a','t','i','o','n',0}; - -#define HARDCODED_NATIVE_WMSDK (PERCEIVEDFLAG_HARDCODED | PERCEIVEDFLAG_NATIVESUPPORT | PERCEIVEDFLAG_WMSDK) -#define HARDCODED_NATIVE_GDIPLUS (PERCEIVEDFLAG_HARDCODED | PERCEIVEDFLAG_NATIVESUPPORT | PERCEIVEDFLAG_GDIPLUS) -#define HARDCODED_NATIVE_ZIPFLDR (PERCEIVEDFLAG_HARDCODED | PERCEIVEDFLAG_NATIVESUPPORT | PERCEIVEDFLAG_ZIPFOLDER) -#define SOFTCODED_NATIVESUPPORT (PERCEIVEDFLAG_SOFTCODED | PERCEIVEDFLAG_NATIVESUPPORT) - -static const struct AssocPerceivedInfo known_types[] = { - { NULL, PERCEIVED_TYPE_UNSPECIFIED, PERCEIVEDFLAG_HARDCODED, PERCEIVEDFLAG_SOFTCODED, unspecified_exts }, - { type_text, PERCEIVED_TYPE_TEXT, PERCEIVEDFLAG_HARDCODED, SOFTCODED_NATIVESUPPORT, NULL }, - { type_image, PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, PERCEIVEDFLAG_SOFTCODED, image_exts }, - { type_audio, PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, PERCEIVEDFLAG_SOFTCODED, audio_exts }, - { type_video, PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, PERCEIVEDFLAG_SOFTCODED, video_exts }, - { type_compressed, PERCEIVED_TYPE_COMPRESSED, HARDCODED_NATIVE_ZIPFLDR, PERCEIVEDFLAG_SOFTCODED, compressed_exts }, - { type_document, PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_HARDCODED, PERCEIVEDFLAG_SOFTCODED, document_exts }, - { type_system, PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_HARDCODED, PERCEIVEDFLAG_SOFTCODED, system_exts }, - { type_application, PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, PERCEIVEDFLAG_SOFTCODED, application_exts }, -}; - -static const struct AssocPerceivedInfo* AssocFindByBuiltinExtension(LPCWSTR pszExt) -{ - UINT n; - for (n = 0; n < sizeof(known_types) / sizeof(known_types[0]); ++n) - { - PCWSTR Ext = known_types[n].Extensions; - while (Ext && *Ext) - { - if (!StrCmpIW(Ext, pszExt)) - return &known_types[n]; - Ext += (strlenW(Ext) + 1); - } - } - return NULL; -} - -static const struct AssocPerceivedInfo* AssocFindByType(LPCWSTR pszType) -{ - UINT n; - for (n = 0; n < sizeof(known_types) / sizeof(known_types[0]); ++n) - { - if (known_types[n].Type) - { - if (!StrCmpIW(known_types[n].Type, pszType)) - return &known_types[n]; - } - } - return NULL; -} - -/************************************************************************* - * AssocGetPerceivedType [SHLWAPI.@] - * - * Detect the type of a file by inspecting its extension - * - * PARAMS - * lpszExt [I] File extension to evaluate. - * lpType [O] Pointer to perceived type - * lpFlag [O] Pointer to perceived type flag - * lppszType [O] Address to pointer for perceived type text - * - * RETURNS - * Success: S_OK. lpType and lpFlag contain the perceived type and - * its information. If lppszType is not NULL, it will point - * to a string with perceived type text. - * Failure: An HRESULT error code indicating the error. - * - * NOTES - * lppszType is optional and it can be NULL. - * if lpType or lpFlag are NULL, the function will crash. - * if lpszExt is NULL, an error is returned. - */ -HRESULT WINAPI AssocGetPerceivedType(LPCWSTR lpszExt, PERCEIVED *lpType, - INT *lpFlag, LPWSTR *lppszType) -{ - static const WCHAR PerceivedTypeKey[] = {'P','e','r','c','e','i','v','e','d','T','y','p','e',0}; - static const WCHAR SystemFileAssociationsKey[] = {'S','y','s','t','e','m','F','i','l','e', - 'A','s','s','o','c','i','a','t','i','o','n','s','\\','%','s',0}; - const struct AssocPerceivedInfo *Info; - - TRACE("(%s,%p,%p,%p)\n", debugstr_w(lpszExt), lpType, lpFlag, lppszType); - - Info = AssocFindByBuiltinExtension(lpszExt); - if (Info) - { - *lpType = Info->Perceived; - *lpFlag = Info->FlagHardcoded; - } - else - { - WCHAR Buffer[100] = { 0 }; - DWORD Size = sizeof(Buffer); - if (RegGetValueW(HKEY_CLASSES_ROOT, lpszExt, PerceivedTypeKey, - RRF_RT_REG_SZ, NULL, Buffer, &Size) == ERROR_SUCCESS) - { - Info = AssocFindByType(Buffer); - } - if (!Info) - { - WCHAR KeyName[MAX_PATH] = { 0 }; - snprintfW(KeyName, MAX_PATH, SystemFileAssociationsKey, lpszExt); - Size = sizeof(Buffer); - if (RegGetValueW(HKEY_CLASSES_ROOT, KeyName, PerceivedTypeKey, - RRF_RT_REG_SZ, NULL, Buffer, &Size) == ERROR_SUCCESS) - { - Info = AssocFindByType(Buffer); - } - } - if (Info) - { - *lpType = Info->Perceived; - *lpFlag = Info->FlagSoftcoded; - } - } - - if (Info) - { - if (lppszType && Info->Type) - { - return SHStrDupW(Info->Type, lppszType); - } - return Info->Type ? S_OK : E_FAIL; - } - else - { - *lpType = PERCEIVED_TYPE_UNSPECIFIED; - *lpFlag = 0; - } - return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); -} \ No newline at end of file diff --git a/wrappers/extensions/shlwext/istream.c b/wrappers/extensions/shlwext/istream.c deleted file mode 100644 index 3132197b57..0000000000 --- a/wrappers/extensions/shlwext/istream.c +++ /dev/null @@ -1,659 +0,0 @@ -/*++ - -Copyright (c) 2024 Shorthorn Project - -Module Name: - - istream.c - -Abstract: - - This module implements Win32 Shell IStream Interface Functions - -Author: - - Skulltrail 10-September-2024 - -Revision History: - ---*/ - -#include "main.h" - -WINE_DEFAULT_DEBUG_CHANNEL(shlwapi); - -/* Layout of ISHFileStream object */ -typedef struct -{ - IStream IStream_iface; - LONG ref; - HANDLE hFile; - DWORD dwMode; - LPOLESTR lpszPath; - DWORD type; - DWORD grfStateBits; -} ISHFileStream; - -static inline ISHFileStream *impl_from_IStream(IStream *iface) -{ - return CONTAINING_RECORD(iface, ISHFileStream, IStream_iface); -} - -static HRESULT WINAPI IStream_fnCommit(IStream*,DWORD); - - -/************************************************************************** -* IStream_fnQueryInterface -*/ -static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface, REFIID riid, LPVOID *ppvObj) -{ - ISHFileStream *This = impl_from_IStream(iface); - - TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppvObj); - - *ppvObj = NULL; - - if(IsEqualIID(riid, &IID_IUnknown) || - IsEqualIID(riid, &IID_IStream)) - { - IStream_AddRef(iface); - *ppvObj = iface; - return S_OK; - } - return E_NOINTERFACE; -} - -/************************************************************************** -* IStream_fnAddRef -*/ -static ULONG WINAPI IStream_fnAddRef(IStream *iface) -{ - ISHFileStream *This = impl_from_IStream(iface); - ULONG refCount = InterlockedIncrement(&This->ref); - - TRACE("(%p)->(ref before=%u)\n",This, refCount - 1); - - return refCount; -} - -/************************************************************************** -* IStream_fnRelease -*/ -static ULONG WINAPI IStream_fnRelease(IStream *iface) -{ - ISHFileStream *This = impl_from_IStream(iface); - ULONG refCount = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(ref before=%u)\n",This, refCount + 1); - - if (!refCount) - { - IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */ - LocalFree(This->lpszPath); - CloseHandle(This->hFile); - HeapFree(GetProcessHeap(), 0, This); - } - - return refCount; -} - -/************************************************************************** - * IStream_fnRead - */ -static HRESULT WINAPI IStream_fnRead(IStream *iface, void* pv, ULONG cb, ULONG* pcbRead) -{ - ISHFileStream *This = impl_from_IStream(iface); - DWORD dwRead = 0; - - TRACE("(%p,%p,0x%08x,%p)\n", This, pv, cb, pcbRead); - - if (!ReadFile(This->hFile, pv, cb, &dwRead, NULL)) - { - WARN("error %d reading file\n", GetLastError()); - return S_FALSE; - } - if (pcbRead) - *pcbRead = dwRead; - return dwRead == cb ? S_OK : S_FALSE; -} - -/************************************************************************** - * IStream_fnWrite - */ -static HRESULT WINAPI IStream_fnWrite(IStream *iface, const void* pv, ULONG cb, ULONG* pcbWritten) -{ - ISHFileStream *This = impl_from_IStream(iface); - DWORD dwWritten = 0; - - TRACE("(%p,%p,0x%08x,%p)\n", This, pv, cb, pcbWritten); - - switch (STGM_ACCESS_MODE(This->dwMode)) - { - case STGM_WRITE: - case STGM_READWRITE: - break; - default: - return STG_E_ACCESSDENIED; - } - - if (!WriteFile(This->hFile, pv, cb, &dwWritten, NULL)) - return HRESULT_FROM_WIN32(GetLastError()); - - if (pcbWritten) - *pcbWritten = dwWritten; - return S_OK; -} - -/************************************************************************** - * IStream_fnSeek - */ -static HRESULT WINAPI IStream_fnSeek(IStream *iface, LARGE_INTEGER dlibMove, - DWORD dwOrigin, ULARGE_INTEGER* pNewPos) -{ - ISHFileStream *This = impl_from_IStream(iface); - DWORD dwPos; - - TRACE("(%p,%d,%d,%p)\n", This, dlibMove.u.LowPart, dwOrigin, pNewPos); - - IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */ - dwPos = SetFilePointer(This->hFile, dlibMove.u.LowPart, NULL, dwOrigin); - if( dwPos == INVALID_SET_FILE_POINTER ) - return HRESULT_FROM_WIN32(GetLastError()); - - if (pNewPos) - { - pNewPos->u.HighPart = 0; - pNewPos->u.LowPart = dwPos; - } - return S_OK; -} - -/************************************************************************** - * IStream_fnSetSize - */ -static HRESULT WINAPI IStream_fnSetSize(IStream *iface, ULARGE_INTEGER libNewSize) -{ - ISHFileStream *This = impl_from_IStream(iface); - - TRACE("(%p,%d)\n", This, libNewSize.u.LowPart); - - IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */ - if( ! SetFilePointer( This->hFile, libNewSize.QuadPart, NULL, FILE_BEGIN ) ) - return E_FAIL; - - if( ! SetEndOfFile( This->hFile ) ) - return E_FAIL; - - return S_OK; -} - -/************************************************************************** - * IStream_fnCopyTo - */ -static HRESULT WINAPI IStream_fnCopyTo(IStream *iface, IStream* pstm, ULARGE_INTEGER cb, - ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten) -{ - ISHFileStream *This = impl_from_IStream(iface); - char copyBuff[1024]; - ULONGLONG ulSize; - HRESULT hRet = S_OK; - - TRACE("(%p,%p,%d,%p,%p)\n", This, pstm, cb.u.LowPart, pcbRead, pcbWritten); - - if (pcbRead) - pcbRead->QuadPart = 0; - if (pcbWritten) - pcbWritten->QuadPart = 0; - - if (!pstm) - return S_OK; - - IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */ - - /* Copy data */ - ulSize = cb.QuadPart; - while (ulSize) - { - ULONG ulLeft, ulRead, ulWritten; - - ulLeft = ulSize > sizeof(copyBuff) ? sizeof(copyBuff) : ulSize; - - /* Read */ - hRet = IStream_fnRead(iface, copyBuff, ulLeft, &ulRead); - if (FAILED(hRet) || ulRead == 0) - break; - if (pcbRead) - pcbRead->QuadPart += ulRead; - - /* Write */ - hRet = IStream_fnWrite(pstm, copyBuff, ulRead, &ulWritten); - if (pcbWritten) - pcbWritten->QuadPart += ulWritten; - if (FAILED(hRet) || ulWritten != ulLeft) - break; - - ulSize -= ulLeft; - } - return hRet; -} - -/************************************************************************** - * IStream_fnCommit - */ -static HRESULT WINAPI IStream_fnCommit(IStream *iface, DWORD grfCommitFlags) -{ - ISHFileStream *This = impl_from_IStream(iface); - - TRACE("(%p,%d)\n", This, grfCommitFlags); - /* Currently unbuffered: This function is not needed */ - return S_OK; -} - -/************************************************************************** - * IStream_fnRevert - */ -static HRESULT WINAPI IStream_fnRevert(IStream *iface) -{ - ISHFileStream *This = impl_from_IStream(iface); - - TRACE("(%p)\n", This); - return E_NOTIMPL; -} - -/************************************************************************** - * IStream_fnLockUnlockRegion - */ -static HRESULT WINAPI IStream_fnLockUnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, - ULARGE_INTEGER cb, DWORD dwLockType) -{ - ISHFileStream *This = impl_from_IStream(iface); - TRACE("(%p,%d,%d,%d)\n", This, libOffset.u.LowPart, cb.u.LowPart, dwLockType); - return E_NOTIMPL; -} - -/************************************************************************* - * IStream_fnStat - */ -static HRESULT WINAPI IStream_fnStat(IStream *iface, STATSTG* lpStat, - DWORD grfStatFlag) -{ - ISHFileStream *This = impl_from_IStream(iface); - BY_HANDLE_FILE_INFORMATION fi; - - TRACE("(%p,%p,%d)\n", This, lpStat, grfStatFlag); - - if (!lpStat) - return STG_E_INVALIDPOINTER; - - memset(&fi, 0, sizeof(fi)); - GetFileInformationByHandle(This->hFile, &fi); - - if (grfStatFlag & STATFLAG_NONAME) - lpStat->pwcsName = NULL; - else - lpStat->pwcsName = StrDupW(This->lpszPath); - lpStat->type = This->type; - lpStat->cbSize.u.LowPart = fi.nFileSizeLow; - lpStat->cbSize.u.HighPart = fi.nFileSizeHigh; - lpStat->mtime = fi.ftLastWriteTime; - lpStat->ctime = fi.ftCreationTime; - lpStat->atime = fi.ftLastAccessTime; - lpStat->grfMode = This->dwMode; - lpStat->grfLocksSupported = 0; - memcpy(&lpStat->clsid, &IID_IStream, sizeof(CLSID)); - lpStat->grfStateBits = This->grfStateBits; - lpStat->reserved = 0; - - return S_OK; -} - -/************************************************************************* - * IStream_fnClone - */ -static HRESULT WINAPI IStream_fnClone(IStream *iface, IStream** ppstm) -{ - ISHFileStream *This = impl_from_IStream(iface); - - TRACE("(%p)\n",This); - if (ppstm) - *ppstm = NULL; - return E_NOTIMPL; -} - -static const IStreamVtbl SHLWAPI_fsVTable = -{ - IStream_fnQueryInterface, - IStream_fnAddRef, - IStream_fnRelease, - IStream_fnRead, - IStream_fnWrite, - IStream_fnSeek, - IStream_fnSetSize, - IStream_fnCopyTo, - IStream_fnCommit, - IStream_fnRevert, - IStream_fnLockUnlockRegion, - IStream_fnLockUnlockRegion, - IStream_fnStat, - IStream_fnClone -}; - -/************************************************************************** - * IStream_Create - * - * Internal helper: Create and initialise a new file stream object. - */ -static IStream *IStream_Create(LPCWSTR lpszPath, HANDLE hFile, DWORD dwMode) -{ - ISHFileStream *fileStream; - - fileStream = HeapAlloc(GetProcessHeap(), 0, sizeof(ISHFileStream)); - if (!fileStream) return NULL; - - fileStream->IStream_iface.lpVtbl = &SHLWAPI_fsVTable; - fileStream->ref = 1; - fileStream->hFile = hFile; - fileStream->dwMode = dwMode; - fileStream->lpszPath = StrDupW(lpszPath); - fileStream->type = 0; /* FIXME */ - fileStream->grfStateBits = 0; /* FIXME */ - - TRACE ("Returning %p\n", fileStream); - return &fileStream->IStream_iface; -} - -/************************************************************************* - * SHCreateStreamOnFileEx [SHLWAPI.@] - * - * Create a stream on a file. - * - * PARAMS - * lpszPath [I] Path of file to create stream on - * dwMode [I] Mode to create stream in - * dwAttributes [I] Attributes of the file - * bCreate [I] Whether to create the file if it doesn't exist - * lpTemplate [I] Reserved, must be NULL - * lppStream [O] Destination for created stream - * - * RETURNS - * Success: S_OK. lppStream contains the new stream object - * Failure: E_INVALIDARG if any parameter is invalid, or an HRESULT error code - * - * NOTES - * This function is available in Unicode only. - */ -HRESULT WINAPI SHCreateStreamOnFileEx(LPCWSTR lpszPath, DWORD dwMode, - DWORD dwAttributes, BOOL bCreate, - IStream *lpTemplate, IStream **lppStream) -{ - DWORD dwAccess, dwShare, dwCreate; - HANDLE hFile; - - TRACE("(%s,%d,0x%08X,%d,%p,%p)\n", debugstr_w(lpszPath), dwMode, - dwAttributes, bCreate, lpTemplate, lppStream); - - if (!lpszPath || !lppStream || lpTemplate) - return E_INVALIDARG; - - *lppStream = NULL; - - /* Access */ - switch (STGM_ACCESS_MODE(dwMode)) - { - case STGM_WRITE: - case STGM_READWRITE: - dwAccess = GENERIC_READ|GENERIC_WRITE; - break; - case STGM_READ: - dwAccess = GENERIC_READ; - break; - default: - return E_INVALIDARG; - } - - /* Sharing */ - switch (STGM_SHARE_MODE(dwMode)) - { - case 0: - case STGM_SHARE_DENY_NONE: - dwShare = FILE_SHARE_READ|FILE_SHARE_WRITE; - break; - case STGM_SHARE_DENY_READ: - dwShare = FILE_SHARE_WRITE; - break; - case STGM_SHARE_DENY_WRITE: - dwShare = FILE_SHARE_READ; - break; - case STGM_SHARE_EXCLUSIVE: - dwShare = 0; - break; - default: - return E_INVALIDARG; - } - - switch(STGM_CREATE_MODE(dwMode)) - { - case STGM_FAILIFTHERE: - dwCreate = bCreate ? CREATE_NEW : OPEN_EXISTING; - break; - case STGM_CREATE: - dwCreate = CREATE_ALWAYS; - break; - default: - return E_INVALIDARG; - } - - /* Open HANDLE to file */ - hFile = CreateFileW(lpszPath, dwAccess, dwShare, NULL, dwCreate, - dwAttributes, 0); - - if(hFile == INVALID_HANDLE_VALUE) - return HRESULT_FROM_WIN32(GetLastError()); - - *lppStream = IStream_Create(lpszPath, hFile, dwMode); - - if(!*lppStream) - { - CloseHandle(hFile); - return E_OUTOFMEMORY; - } - return S_OK; -} - -/************************************************************************* - * SHCreateStreamOnFileW [SHLWAPI.@] - * - * See SHCreateStreamOnFileA. - */ -HRESULT WINAPI SHCreateStreamOnFileW(LPCWSTR lpszPath, DWORD dwMode, - IStream **lppStream) -{ - TRACE("(%s,%d,%p)\n", debugstr_w(lpszPath), dwMode, lppStream); - - if (!lpszPath || !lppStream) - return E_INVALIDARG; - - if ((dwMode & (STGM_CONVERT|STGM_DELETEONRELEASE|STGM_TRANSACTED)) != 0) - return E_INVALIDARG; - - return SHCreateStreamOnFileEx(lpszPath, dwMode, 0, FALSE, NULL, lppStream); -} - -/************************************************************************* - * SHCreateStreamOnFileA [SHLWAPI.@] - * - * Create a stream on a file. - * - * PARAMS - * lpszPath [I] Path of file to create stream on - * dwMode [I] Mode to create stream in - * lppStream [O] Destination for created IStream object - * - * RETURNS - * Success: S_OK. lppStream contains the new IStream object - * Failure: E_INVALIDARG if any parameter is invalid, or an HRESULT error code - */ -HRESULT WINAPI SHCreateStreamOnFileA(LPCSTR lpszPath, DWORD dwMode, - IStream **lppStream) -{ - WCHAR szPath[MAX_PATH]; - - TRACE("(%s,%d,%p)\n", debugstr_a(lpszPath), dwMode, lppStream); - - if (!lpszPath) - return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND); - - MultiByteToWideChar(CP_ACP, 0, lpszPath, -1, szPath, MAX_PATH); - return SHCreateStreamOnFileW(szPath, dwMode, lppStream); -} - -/************************************************************************* - * @ [SHLWAPI.184] - * - * Call IStream_Read() on a stream. - * - * PARAMS - * lpStream [I] IStream object - * lpvDest [O] Destination for data read - * ulSize [I] Size of data to read - * - * RETURNS - * Success: S_OK. ulSize bytes have been read from the stream into lpvDest. - * Failure: An HRESULT error code, or E_FAIL if the read succeeded but the - * number of bytes read does not match. - */ -HRESULT WINAPI SHIStream_Read(IStream *lpStream, LPVOID lpvDest, ULONG ulSize) -{ - ULONG ulRead; - HRESULT hRet; - - TRACE("(%p,%p,%d)\n", lpStream, lpvDest, ulSize); - - hRet = IStream_Read(lpStream, lpvDest, ulSize, &ulRead); - - if (SUCCEEDED(hRet) && ulRead != ulSize) - hRet = E_FAIL; - return hRet; -} - -/************************************************************************* - * @ [SHLWAPI.166] - * - * Determine if a stream has 0 length. - * - * PARAMS - * lpStream [I] IStream object - * - * RETURNS - * TRUE: If the stream has 0 length - * FALSE: Otherwise. - */ -BOOL WINAPI SHIsEmptyStream(IStream *lpStream) -{ - STATSTG statstg; - BOOL bRet = TRUE; - - TRACE("(%p)\n", lpStream); - - memset(&statstg, 0, sizeof(statstg)); - - if(SUCCEEDED(IStream_Stat(lpStream, &statstg, 1))) - { - if(statstg.cbSize.QuadPart) - bRet = FALSE; /* Non-Zero */ - } - else - { - DWORD dwDummy; - - /* Try to read from the stream */ - if(SUCCEEDED(SHIStream_Read(lpStream, &dwDummy, sizeof(dwDummy)))) - { - LARGE_INTEGER zero; - zero.QuadPart = 0; - - IStream_Seek(lpStream, zero, 0, NULL); - bRet = FALSE; /* Non-Zero */ - } - } - return bRet; -} - -/************************************************************************* - * @ [SHLWAPI.212] - * - * Call IStream_Write() on a stream. - * - * PARAMS - * lpStream [I] IStream object - * lpvSrc [I] Source for data to write - * ulSize [I] Size of data - * - * RETURNS - * Success: S_OK. ulSize bytes have been written to the stream from lpvSrc. - * Failure: An HRESULT error code, or E_FAIL if the write succeeded but the - * number of bytes written does not match. - */ -HRESULT WINAPI SHIStream_Write(IStream *lpStream, LPCVOID lpvSrc, ULONG ulSize) -{ - ULONG ulWritten; - HRESULT hRet; - - TRACE("(%p,%p,%d)\n", lpStream, lpvSrc, ulSize); - - hRet = IStream_Write(lpStream, lpvSrc, ulSize, &ulWritten); - - if (SUCCEEDED(hRet) && ulWritten != ulSize) - hRet = E_FAIL; - - return hRet; -} - -/************************************************************************* - * @ [SHLWAPI.213] - * - * Seek to the start of a stream. - * - * PARAMS - * lpStream [I] IStream object - * - * RETURNS - * Success: S_OK. The current position within the stream is updated - * Failure: An HRESULT error code. - */ -HRESULT WINAPI IStream_Reset(IStream *lpStream) -{ - LARGE_INTEGER zero; - TRACE("(%p)\n", lpStream); - zero.QuadPart = 0; - return IStream_Seek(lpStream, zero, 0, NULL); -} - -/************************************************************************* - * @ [SHLWAPI.214] - * - * Get the size of a stream. - * - * PARAMS - * lpStream [I] IStream object - * lpulSize [O] Destination for size - * - * RETURNS - * Success: S_OK. lpulSize contains the size of the stream. - * Failure: An HRESULT error code. - */ -HRESULT WINAPI IStream_Size(IStream *lpStream, ULARGE_INTEGER* lpulSize) -{ - STATSTG statstg; - HRESULT hRet; - - TRACE("(%p,%p)\n", lpStream, lpulSize); - - memset(&statstg, 0, sizeof(statstg)); - - hRet = IStream_Stat(lpStream, &statstg, 1); - - if (SUCCEEDED(hRet) && lpulSize) - *lpulSize = statstg.cbSize; - return hRet; -} diff --git a/wrappers/extensions/shlwext/main.c b/wrappers/extensions/shlwext/main.c deleted file mode 100644 index 257a119ddb..0000000000 --- a/wrappers/extensions/shlwext/main.c +++ /dev/null @@ -1,536 +0,0 @@ -/*++ - -Copyright (c) 2024 Shorthorn Project - -Module Name: - - main.c - -Abstract: - - This module implements Win32 Shell Main Functions - -Author: - - Skulltrail 10-September-2024 - -Revision History: - ---*/ - -#include "main.h" - -WINE_DEFAULT_DEBUG_CHANNEL(shlwapi); - -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) -{ - TRACE("fdwReason %u\n", fdwReason); - - switch(fdwReason) - { - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hInstDLL); - break; - } - - return TRUE; -} - -HRESULT -WINAPI -PathMatchSpecExA( - _In_ LPCTSTR pszFile, - _In_ LPCTSTR pszSpec, - _In_ DWORD dwFlags -) -{ - return PathMatchSpecA(pszFile, pszSpec); -} - -HRESULT -WINAPI -PathMatchSpecExW( - _In_ LPWSTR pszFile, - _In_ LPWSTR pszSpec, - _In_ DWORD dwFlags -) -{ - return PathMatchSpecW(pszFile, pszSpec); -} - -HRESULT -WINAPI -SHAutoCompGetPidl( - HWND hWnd, - LPARAM windowParam, - int Unknown, - WPARAM wParam -) -{ - UINT WindowMessage; // eax@1 - LRESULT LocalResult; // eax@3 - HRESULT result; // eax@4 - LPARAM lParam; // [sp+0h] [bp-8h]@1 - int v8; // [sp+4h] [bp-4h]@1 - - WindowMessage = RegisterWindowMessageA("AC_GetPidl"); - lParam = (LPARAM)&windowParam; - v8 = Unknown; - if ( !WindowMessage ) - WindowMessage = 33070; - LocalResult = SendMessageA(hWnd, WindowMessage, wParam, (LPARAM)&lParam); - if ( LocalResult ) - result = LocalResult != 1 ? LocalResult : 0; - else - result = 0x80070057u; - return result; -} - -/************************************************************************* - * PathCreateFromUrlAlloc [SHLWAPI.@] - */ -HRESULT -WINAPI -PathCreateFromUrlAlloc( - LPCWSTR pszUrl, - LPWSTR *pszPath, - DWORD dwReserved -) -{ - WCHAR pathW[MAX_PATH]; - DWORD size; - HRESULT hr; - - size = MAX_PATH; - hr = PathCreateFromUrlW(pszUrl, pathW, &size, dwReserved); - if (SUCCEEDED(hr)) - { - /* Yes, this is supposed to crash if pszPath is NULL */ - *pszPath = StrDupW(pathW); - } - return hr; -} - -static void FillNumberFmt(NUMBERFMTW *fmt, LPWSTR decimal_buffer, int decimal_bufwlen, - LPWSTR thousand_buffer, int thousand_bufwlen) -{ - WCHAR grouping[64]; - WCHAR *c; - - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_ILZERO|LOCALE_RETURN_NUMBER, (LPWSTR)&fmt->LeadingZero, sizeof(fmt->LeadingZero)/sizeof(WCHAR)); - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_INEGNUMBER|LOCALE_RETURN_NUMBER, (LPWSTR)&fmt->NegativeOrder, sizeof(fmt->NegativeOrder)/sizeof(WCHAR)); - fmt->NumDigits = 0; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal_buffer, decimal_bufwlen); - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousand_buffer, thousand_bufwlen); - fmt->lpThousandSep = thousand_buffer; - fmt->lpDecimalSep = decimal_buffer; - - /* - * Converting grouping string to number as described on - * http://blogs.msdn.com/oldnewthing/archive/2006/04/18/578251.aspx - */ - fmt->Grouping = 0; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, grouping, ARRAY_SIZE(grouping)); - for (c = grouping; *c; c++) - if (*c >= '0' && *c < '9') - { - fmt->Grouping *= 10; - fmt->Grouping += *c - '0'; - } - - if (fmt->Grouping % 10 == 0) - fmt->Grouping /= 10; - else - fmt->Grouping *= 10; -} - -/************************************************************************* - * FormatDouble [internal] - * - * Format an integer according to the current locale. Prints the specified number of digits - * after the decimal point - * - * RETURNS - * The number of characters written on success or 0 on failure - */ -static int FormatDouble(double value, int decimals, LPWSTR pszBuf, int cchBuf) -{ - static const WCHAR flfmt[] = {'%','f',0}; - WCHAR buf[64]; - NUMBERFMTW fmt; - WCHAR decimal[8], thousand[8]; - - swprintf(buf, flfmt, value); - - FillNumberFmt(&fmt, decimal, ARRAY_SIZE(decimal), thousand, ARRAY_SIZE(thousand)); - fmt.NumDigits = decimals; - return GetNumberFormatW(LOCALE_USER_DEFAULT, 0, buf, &fmt, pszBuf, cchBuf); -} - -/************************************************************************* - * StrFormatByteSizeEx [SHLWAPI.@] - * - */ - -HRESULT WINAPI StrFormatByteSizeEx(LONGLONG llBytes, SFBS_FLAGS flags, LPWSTR lpszDest, - UINT cchMax) -{ -#define KB ((ULONGLONG)1024) -#define MB (KB*KB) -#define GB (KB*KB*KB) -#define TB (KB*KB*KB*KB) -#define PB (KB*KB*KB*KB*KB) - - static SHLWAPI_BYTEFORMATS bfFormats[] = - { - { 10*KB, 10.24, 100.0, 2, 'K' }, /* 10 KB */ - { 100*KB, 102.4, 10.0, 1, 'K' }, /* 100 KB */ - { 1000*KB, 1024.0, 1.0, 0, 'K' }, /* 1000 KB */ - { 10*MB, 10485.76, 100.0, 2, 'M' }, /* 10 MB */ - { 100*MB, 104857.6, 10.0, 1, 'M' }, /* 100 MB */ - { 1000*MB, 1048576.0, 1.0, 0, 'M' }, /* 1000 MB */ - { 10*GB, 10737418.24, 100.0, 2, 'G' }, /* 10 GB */ - { 100*GB, 107374182.4, 10.0, 1, 'G' }, /* 100 GB */ - { 1000*GB, 1073741824.0, 1.0, 0, 'G' }, /* 1000 GB */ - { 10*TB, 10485.76, 100.0, 2, 'T' }, /* 10 TB */ - { 100*TB, 104857.6, 10.0, 1, 'T' }, /* 100 TB */ - { 1000*TB, 1048576.0, 1.0, 0, 'T' }, /* 1000 TB */ - { 10*PB, 10737418.24, 100.00, 2, 'P' }, /* 10 PB */ - { 100*PB, 107374182.4, 10.00, 1, 'P' }, /* 100 PB */ - { 1000*PB, 1073741824.0, 1.00, 0, 'P' }, /* 1000 PB */ - { 0, 10995116277.76, 100.00, 2, 'E' } /* EB's, catch all */ - }; - WCHAR wszAdd[] = {' ','?','B',0}; - double dBytes; - UINT i = 0; - HINSTANCE hInst = LoadLibraryW(L"shlwapibase.dll"); - - TRACE("(0x%s,%d,%p,%d)\n", wine_dbgstr_longlong(llBytes), flags, lpszDest, cchMax); - - if (!cchMax) - return E_INVALIDARG; - - if (llBytes < 1024) /* 1K */ - { - WCHAR wszBytesFormat[64]; - LoadStringW(hInst, IDS_BYTES_FORMAT, wszBytesFormat, 64); - swprintf(lpszDest, wszBytesFormat, (int)llBytes); - return S_OK; - } - - /* Note that if this loop completes without finding a match, i will be - * pointing at the last entry, which is a catch all for > 1000 PB - */ - while (i < ARRAY_SIZE(bfFormats) - 1) - { - if (llBytes < bfFormats[i].dLimit) - break; - i++; - } - /* Above 1 TB we encounter problems with FP accuracy. So for amounts above - * this number we integer shift down by 1 MB first. The table above has - * the divisors scaled down from the '< 10 TB' entry onwards, to account - * for this. We also add a small fudge factor to get the correct result for - * counts that lie exactly on a 1024 byte boundary. - */ - if (i > 8) - dBytes = (double)(llBytes >> 20) + 0.001; /* Scale down by 1 MB */ - else - dBytes = (double)llBytes + 0.00001; - - switch(flags) - { - case SFBS_FLAGS_ROUND_TO_NEAREST_DISPLAYED_DIGIT: - dBytes = round(dBytes / bfFormats[i].dDivisor) / bfFormats[i].dNormaliser; - break; - case SFBS_FLAGS_TRUNCATE_UNDISPLAYED_DECIMAL_DIGITS: - dBytes = floor(dBytes / bfFormats[i].dDivisor) / bfFormats[i].dNormaliser; - break; - default: - return E_INVALIDARG; - } - - if (!FormatDouble(dBytes, bfFormats[i].nDecimals, lpszDest, cchMax)) - return E_FAIL; - - wszAdd[1] = bfFormats[i].wPrefix; - StrCatBuffW(lpszDest, wszAdd, cchMax); - return S_OK; -} - -DWORD __stdcall GetLastErrorError() -{ - DWORD result; // eax - - result = GetLastError(); - if ( !result ) - return 1; - return result; -} - -HRESULT WINAPI HRESULTFromLastErrorError() -{ - signed int result; // eax - - result = GetLastErrorError(); - if ( result > 0 ) - return (unsigned __int16)result | 0x80070000; - return result; -} - -HRESULT GetModuleResourceData(HMODULE hModule, LPCWSTR lpName, LPCWSTR lpType, DWORD *a4, DWORD *a5) -{ - HRSRC ResourceW; // eax - HRSRC v6; // esi - DWORD v7; // edi - HGLOBAL Resource; // eax - LPVOID v9; // eax - - ResourceW = FindResourceW(hModule, lpName, lpType); - v6 = ResourceW; - if ( !ResourceW ) - return HRESULTFromLastErrorError(); - v7 = SizeofResource(hModule, ResourceW); - if ( !v7 ) - return HRESULTFromLastErrorError(); - Resource = LoadResource(hModule, v6); - if ( !Resource ) - return HRESULTFromLastErrorError(); - v9 = LockResource(Resource); - if ( !v9 ) - return HRESULTFromLastErrorError(); - *a4 = (DWORD)v9; - *a5 = v7; - return 0; -} - -HRESULT WINAPI CreateStreamSTOnModuleResource(HMODULE hModule, BYTE *pInit, const WCHAR *cbInit, IStream **a4) -{ - HRESULT ModuleResourceData; // esi - IStream *Stream; // eax - - ModuleResourceData = GetModuleResourceData(hModule, (LPCWSTR)pInit, cbInit, (DWORD*)&pInit, (DWORD*)&cbInit); - if ( ModuleResourceData >= 0 ) - { - Stream = SHCreateMemStream(pInit, (UINT)cbInit); - *a4 = Stream; - if ( !Stream ) - return 0x8007000E; - } - return ModuleResourceData; -} - -#ifdef _M_IX86 -HRESULT WINAPI SHCreateStreamOnModuleResourceW(HMODULE a1, BYTE *a2, const WCHAR *a3, IStream **a4) -{ - return CreateStreamSTOnModuleResource(a1, a2, a3, a4); -} -#else -HRESULT WINAPI SHCreateStreamOnModuleResourceW(HMODULE hModule, BYTE *pInit, const WCHAR *cbInit, PVOID **Cstream) -{ - HRESULT ModuleResourceData; // esi - PVOID *Stream; // eax - - ModuleResourceData = GetModuleResourceData(hModule, (LPCWSTR)pInit, cbInit, (DWORD*)&pInit, (DWORD*)&cbInit); - if ( ModuleResourceData >= 0 ) - { - Stream = (PVOID*)SHCreateMemStream(pInit, (UINT)cbInit); - *Cstream = Stream; - if ( !Stream ) - return 0x8007000E; - } - return ModuleResourceData; -} -#endif - -HRESULT WINAPI IStream_Copy(IStream *pstmFrom, IStream *pstmTo, DWORD cb) -{ - HRESULT result; // eax - int v4[2]; // [esp+Ch] [ebp-Ch] BYREF - - result = ((int (__stdcall *)(IStream *, IStream *, DWORD, DWORD, DWORD, int *))pstmFrom->lpVtbl->CopyTo)( - pstmFrom, - pstmTo, - cb, - 0, - 0, - v4); - - return result; -} - -/************************************************************************* - * PathIsRootW [SHLWAPI.@] - * - * See PathIsRootA. - */ -BOOL WINAPI PathIsRootW(LPCWSTR lpszPath) -{ - TRACE("(%s)\n", debugstr_w(lpszPath)); - - if (lpszPath && *lpszPath) - { - if (*lpszPath == '\\') - { - if (!lpszPath[1]) - return TRUE; /* \ */ - else if (lpszPath[1]=='\\') - { - BOOL bSeenSlash = FALSE; - lpszPath += 2; - - /* Check for UNC root path */ - while (*lpszPath) - { - if (*lpszPath == '\\') - { - if (bSeenSlash) - return FALSE; - bSeenSlash = TRUE; - } - lpszPath++; - } - return TRUE; - } - } - else if (lpszPath[1] == ':' && lpszPath[2] == '\\' && lpszPath[3] == '\0') - return TRUE; /* X:\ */ - } - return FALSE; -} - -/************************************************************************* - * PathIsRootA [SHLWAPI.@] - * - * Determine if a path is a root path. - * - * PARAMS - * lpszPath [I] Path to check - * - * RETURNS - * TRUE If lpszPath is valid and a root path, - * FALSE Otherwise - */ -BOOL WINAPI PathIsRootA(LPCSTR lpszPath) -{ - TRACE("(%s)\n", debugstr_a(lpszPath)); - - if (lpszPath && *lpszPath) - { - if (*lpszPath == '\\') - { - if (!lpszPath[1]) - return TRUE; /* \ */ - else if (lpszPath[1]=='\\') - { - BOOL bSeenSlash = FALSE; - lpszPath += 2; - - /* Check for UNC root path */ - while (*lpszPath) - { - if (*lpszPath == '\\') - { - if (bSeenSlash) - return FALSE; - bSeenSlash = TRUE; - } - lpszPath = CharNextA(lpszPath); - } - return TRUE; - } - } - else if (lpszPath[1] == ':' && lpszPath[2] == '\\' && lpszPath[3] == '\0') - return TRUE; /* X:\ */ - } - return FALSE; -} - -/************************************************************************* - * PathRemoveFileSpecW [SHLWAPI.@] - * - * See PathRemoveFileSpecA. - */ -BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath) -{ - LPWSTR lpszFileSpec = lpszPath; - BOOL bModified = FALSE; - - TRACE("(%s)\n",debugstr_w(lpszPath)); - - if(lpszPath) - { - /* Skip directory or UNC path */ - if (*lpszPath == '\\') - lpszFileSpec = ++lpszPath; - if (*lpszPath == '\\') - lpszFileSpec = ++lpszPath; - - while (*lpszPath) - { - if(*lpszPath == '\\') - lpszFileSpec = lpszPath; /* Skip dir */ - else if(*lpszPath == ':') - { - lpszFileSpec = ++lpszPath; /* Skip drive */ - if (*lpszPath == '\\') - lpszFileSpec++; - } - lpszPath++; - } - - if (*lpszFileSpec) - { - *lpszFileSpec = '\0'; - bModified = TRUE; - } - } - return bModified; -} - -/************************************************************************* - * PathStripToRootW [SHLWAPI.@] - * - * See PathStripToRootA. - */ -BOOL WINAPI PathStripToRootW(LPWSTR lpszPath) -{ - TRACE("(%s)\n", debugstr_w(lpszPath)); - - if (!lpszPath) - return FALSE; - while(!PathIsRootW(lpszPath)) - if (!PathRemoveFileSpecW(lpszPath)) - return FALSE; - return TRUE; -} - -/************************************************************************* - * PathStripToRootA [SHLWAPI.@] - * - * Reduce a path to its root. - * - * PARAMS - * lpszPath [I/O] the path to reduce - * - * RETURNS - * Success: TRUE if the stripped path is a root path - * Failure: FALSE if the path cannot be stripped or is NULL - */ -BOOL WINAPI PathStripToRootA(LPSTR lpszPath) -{ - TRACE("(%s)\n", debugstr_a(lpszPath)); - - if (!lpszPath) - return FALSE; - while(!PathIsRootA(lpszPath)) - if (!PathRemoveFileSpecA(lpszPath)) - return FALSE; - return TRUE; -} - -BOOL WINAPI SHWindowsPolicy (REFGUID rpolid) -{ - SetLastError(0); - return FALSE; -} \ No newline at end of file diff --git a/wrappers/extensions/shlwext/main.h b/wrappers/extensions/shlwext/main.h deleted file mode 100644 index 475904cfba..0000000000 --- a/wrappers/extensions/shlwext/main.h +++ /dev/null @@ -1,82 +0,0 @@ -/*++ - -Copyright (c) 2024 Shorthorn Project - -Module Name: - - istream.c - -Abstract: - - This module is the main header of Shwlapi Wrapper - -Author: - - Skulltrail 10-September-2024 - -Revision History: - ---*/ - -#include - -#include -#define WIN32_NO_STATUS -#include -#include - -#define COBJMACROS -#define NONAMELESSUNION - -#include "windef.h" -#include "winbase.h" -#include -#include "winerror.h" -#include "winnls.h" -#define NO_SHLWAPI_REG -#define NO_SHLWAPI_PATH -#include -#include "shlwapi.h" -#include "wine/debug.h" -#include -#include - -#define IDS_BYTES_FORMAT 64 - -/* Structure for formatting byte strings */ -typedef struct tagSHLWAPI_BYTEFORMATS -{ - LONGLONG dLimit; - double dDivisor; - double dNormaliser; - int nDecimals; - WCHAR wPrefix; -} SHLWAPI_BYTEFORMATS; - -typedef enum { - SFBS_FLAGS_ROUND_TO_NEAREST_DISPLAYED_DIGIT = 0x00000001, - SFBS_FLAGS_TRUNCATE_UNDISPLAYED_DECIMAL_DIGITS = 0x00000002 -} SFBS_FLAGS; - -HRESULT -WINAPI -PSStrFormatByteSizeEx( - ULONGLONG ull, - SFBS_FLAGS flags, - _Out_ PWSTR pszBuf, - UINT cchBuf -); - -BOOL WINAPI PathMatchSpecA(_In_ LPCSTR, _In_ LPCSTR); -BOOL WINAPI PathMatchSpecW(_In_ LPCWSTR, _In_ LPCWSTR); - -HRESULT -WINAPI -PathCreateFromUrlW( - _In_ LPCWSTR pszUrl, - _Out_writes_to_(*pcchPath, *pcchPath) LPWSTR pszPath, - _Inout_ LPDWORD pcchPath, - DWORD dwFlags); - -BOOL WINAPI PathRemoveFileSpecA(_Inout_ LPSTR); -BOOL WINAPI PathRemoveFileSpecW(_Inout_ LPWSTR); diff --git a/wrappers/extensions/shlwext/shlwext.spec b/wrappers/extensions/shlwext/shlwext.spec deleted file mode 100644 index 38677177e8..0000000000 --- a/wrappers/extensions/shlwext/shlwext.spec +++ /dev/null @@ -1,1182 +0,0 @@ -1 stdcall ParseURLA(str ptr) -2 stdcall ParseURLW(wstr ptr) -3 stdcall -noname PathFileExistsDefExtA(str long) -4 stdcall -noname PathFileExistsDefExtW(wstr long) -5 stdcall -noname PathFindOnPathExA(str ptr long) -6 stdcall -noname PathFindOnPathExW(wstr ptr long) -7 stdcall -ordinal SHAllocShared(ptr long long) -8 stdcall -ordinal SHLockShared(long long) -9 stdcall -ordinal SHUnlockShared(ptr) -10 stdcall -ordinal SHFreeShared(long long) -11 stdcall -noname SHMapHandle(long long long long long) -12 stdcall SHCreateMemStream(ptr long) -13 stdcall -noname RegisterDefaultAcceptHeaders(ptr ptr) -14 stdcall -ordinal GetAcceptLanguagesA(ptr ptr) -15 stdcall -ordinal GetAcceptLanguagesW(ptr ptr) -16 stdcall -ordinal SHCreateThread(ptr ptr long ptr) -17 stdcall -noname SHWriteDataBlockList(ptr ptr) -18 stdcall -noname SHReadDataBlockList(ptr ptr) -19 stdcall -noname SHFreeDataBlockList(ptr) -20 stdcall -noname SHAddDataBlock(ptr ptr) -21 stdcall -noname SHRemoveDataBlock(ptr long) -22 stdcall -noname SHFindDataBlock(ptr long) -23 stdcall -noname SHStringFromGUIDA(ptr ptr long) -24 stdcall -noname SHStringFromGUIDW(ptr ptr long) -25 stdcall -noname IsCharAlphaWrapW(long) -26 stdcall -noname IsCharUpperWrapW(long) -27 stdcall -noname IsCharLowerWrapW(long) -28 stdcall -noname IsCharAlphaNumericWrapW(long) -29 stdcall -ordinal IsCharSpaceW(long) -30 stdcall -noname IsCharBlankW(long) -31 stdcall -noname IsCharPunctW(long) -32 stdcall -noname IsCharCntrlW(ptr) -33 stdcall -noname IsCharDigitW(long) -34 stdcall -noname IsCharXDigitW(long) -35 stdcall -noname GetStringType3ExW(ptr long ptr) -36 stdcall -noname AppendMenuWrapW(long long long wstr) user32.AppendMenuW -37 stdcall -noname CallWindowProcWrapW(ptr long long long long) user32.CallWindowProcW -38 stdcall -noname CharLowerWrapW(wstr) user32.CharLowerW -39 stdcall -noname CharLowerBuffWrapW(wstr long) user32.CharLowerBuffW -40 stdcall -noname CharNextWrapW(wstr) user32.CharNextW -41 stdcall -noname CharPrevWrapW(wstr wstr) user32.CharPrevW -42 stdcall -noname CharToOemWrapW(wstr) user32.CharToOemW -43 stdcall -noname CharUpperWrapW(wstr) user32.CharUpperW -44 stdcall -noname CharUpperBuffWrapW(wstr long) user32.CharUpperBuffW -45 stdcall -noname CompareStringWrapW(long long wstr long wstr long) kernel32.CompareStringW -46 stdcall -noname CopyAcceleratorTableWrapW(long ptr long) user32.CopyAcceleratorTableW -47 stdcall -noname CreateAcceleratorTableWrapW(ptr long) user32.CreateAcceleratorTableW -48 stdcall -noname CreateDCWrapW(wstr wstr wstr ptr) gdi32.CreateDCW -49 stdcall -noname CreateDialogParamWrapW(long ptr long ptr long) user32.CreateDialogParamW -50 stdcall -noname CreateDirectoryWrapW(wstr ptr) kernel32.CreateDirectoryW -51 stdcall -noname CreateEventWrapW(ptr long long wstr) kernel32.CreateEventW -52 stdcall -noname CreateFileWrapW(wstr long long ptr long long long) kernel32.CreateFileW -53 stdcall -noname CreateFontIndirectWrapW(ptr) gdi32.CreateFontIndirectW -54 stdcall -noname CreateICWrapW(wstr wstr wstr ptr) gdi32.CreateICW -55 stdcall -noname CreateWindowExWrapW(long wstr wstr long long long long long long long long ptr) user32.CreateWindowExW -56 stdcall -noname DefWindowProcWrapW(long long long long) user32.DefWindowProcW -57 stdcall -noname DeleteFileWrapW(wstr) kernel32.DeleteFileW -58 stdcall -noname DialogBoxIndirectParamWrapW(long ptr long ptr long) user32.DialogBoxIndirectParamW -59 stdcall -noname DialogBoxParamWrapW(long wstr long ptr long) user32.DialogBoxParamW -60 stdcall -noname DispatchMessageWrapW(ptr) user32.DispatchMessageW -61 stdcall -noname DrawTextWrapW(long wstr long ptr long) user32.DrawTextW -62 stdcall -noname EnumFontFamiliesWrapW(long wstr ptr long) gdi32.EnumFontFamiliesW -63 stdcall -noname EnumFontFamiliesExWrapW(long ptr ptr long long) gdi32.EnumFontFamiliesExW -64 stdcall -noname EnumResourceNamesWrapW(long wstr ptr long) kernel32.EnumResourceNamesW -65 stdcall -noname FindFirstFileWrapW(wstr ptr) kernel32.FindFirstFileW -66 stdcall -noname FindResourceWrapW(long wstr wstr) kernel32.FindResourceW -67 stdcall -noname FindWindowWrapW(wstr wstr) user32.FindWindowW -68 stdcall -noname FormatMessageWrapW(long ptr long long ptr long ptr) kernel32.FormatMessageW -69 stdcall -noname GetClassInfoWrapW(long wstr ptr) user32.GetClassInfoW -70 stdcall -noname GetClassLongWrapW(long long) user32.GetClassLongW -71 stdcall -noname GetClassNameWrapW(long ptr long) user32.GetClassNameW -72 stdcall -noname GetClipboardFormatNameWrapW(long ptr long) user32.GetClipboardFormatNameW -73 stdcall -noname GetCurrentDirectoryWrapW(long ptr) kernel32.GetCurrentDirectoryW -74 stdcall -noname GetDlgItemTextWrapW(long long wstr long) user32.GetDlgItemTextW -75 stdcall -noname GetFileAttributesWrapW(wstr) kernel32.GetFileAttributesW -76 stdcall -noname GetFullPathNameWrapW(wstr long ptr ptr) kernel32.GetFullPathNameW -77 stdcall -noname GetLocaleInfoWrapW(long long ptr long) kernel32.GetLocaleInfoW -78 stdcall -noname GetMenuStringWrapW(long long ptr long long) user32.GetMenuStringW -79 stdcall -noname GetMessageWrapW(ptr long long long) user32.GetMessageW -80 stdcall -noname GetModuleFileNameWrapW(long ptr long) kernel32.GetModuleFileNameW -81 stdcall -noname GetSystemDirectoryWrapW(ptr long) kernel32.GetSystemDirectoryW -82 stdcall -noname SearchPathWrapW(wstr wstr wstr long ptr ptr) kernel32.SearchPathW -83 stdcall -noname GetModuleHandleWrapW(wstr) kernel32.GetModuleHandleW -84 stdcall -noname GetObjectWrapW(long long ptr) gdi32.GetObjectW -85 stdcall -noname GetPrivateProfileIntWrapW(wstr wstr long wstr) kernel32.GetPrivateProfileIntW -86 stdcall -noname GetProfileStringWrapW(wstr wstr wstr ptr long) kernel32.GetProfileStringW -87 stdcall -noname GetPropWrapW(long wstr) user32.GetPropW -88 stdcall -noname GetStringTypeExWrapW(long long wstr long ptr) kernel32.GetStringTypeExW -89 stdcall -noname GetTempFileNameWrapW(wstr wstr long ptr) kernel32.GetTempFileNameW -90 stdcall -noname GetTempPathWrapW(long ptr) kernel32.GetTempPathW -91 stdcall -noname GetTextExtentPoint32WrapW(long wstr long ptr) gdi32.GetTextExtentPoint32W -92 stdcall -noname GetTextFaceWrapW(long long ptr) gdi32.GetTextFaceW -93 stdcall -noname GetTextMetricsWrapW(long ptr) gdi32.GetTextMetricsW -94 stdcall -noname GetWindowLongWrapW(long long) user32.GetWindowLongW -95 stdcall -noname GetWindowTextWrapW(long ptr long) user32.GetWindowTextW -96 stdcall -noname GetWindowTextLengthWrapW(long) user32.GetWindowTextLengthW -97 stdcall -noname GetWindowsDirectoryWrapW(ptr long) kernel32.GetWindowsDirectoryW -98 stdcall -noname InsertMenuWrapW(long long long long ptr) user32.InsertMenuW -99 stdcall -noname IsDialogMessageWrapW(long ptr) user32.IsDialogMessageW -100 stdcall -noname LoadAcceleratorsWrapW(long wstr) user32.LoadAcceleratorsW -101 stdcall -noname LoadBitmapWrapW(long wstr) user32.LoadBitmapW -102 stdcall -noname LoadCursorWrapW(long wstr) user32.LoadCursorW -103 stdcall -noname LoadIconWrapW(long wstr) user32.LoadIconW -104 stdcall -noname LoadImageWrapW(long wstr long long long long) user32.LoadImageW -105 stdcall -noname LoadLibraryExWrapW(wstr long long) kernel32.LoadLibraryExW -106 stdcall -noname LoadMenuWrapW(long wstr) user32.LoadMenuW -107 stdcall -noname LoadStringWrapW(long long ptr long) user32.LoadStringW -108 stdcall -noname MessageBoxIndirectWrapW(ptr) user32.MessageBoxIndirectW -109 stdcall -noname ModifyMenuWrapW(long long long long ptr) user32.ModifyMenuW -110 stdcall -noname GetCharWidth32WrapW(long long long long) gdi32.GetCharWidth32W -111 stdcall -noname GetCharacterPlacementWrapW(long wstr long long ptr long) gdi32.GetCharacterPlacementW -112 stdcall -noname CopyFileWrapW(wstr wstr long) kernel32.CopyFileW -113 stdcall -noname MoveFileWrapW(wstr wstr) kernel32.MoveFileW -114 stdcall -noname OemToCharWrapW(ptr ptr) user32.OemToCharW -115 stdcall -noname OutputDebugStringWrapW(wstr) kernel32.OutputDebugStringW -116 stdcall -noname PeekMessageWrapW(ptr long long long long) user32.PeekMessageW -117 stdcall -noname PostMessageWrapW(long long long long) user32.PostMessageW -118 stdcall -noname PostThreadMessageWrapW(long long long long) user32.PostThreadMessageW -119 stdcall -noname RegCreateKeyWrapW(long wstr ptr) advapi32.RegCreateKeyW -120 stdcall -noname RegCreateKeyExWrapW(long wstr long ptr long long ptr ptr ptr) advapi32.RegCreateKeyExW -121 stdcall -noname RegDeleteKeyWrapW(long wstr) advapi32.RegDeleteKeyW -122 stdcall -noname RegEnumKeyWrapW(long long ptr long) advapi32.RegEnumKeyW -123 stdcall -noname RegEnumKeyExWrapW(long long ptr ptr ptr ptr ptr ptr) advapi32.RegEnumKeyExW -124 stdcall -noname RegOpenKeyWrapW(long wstr ptr) advapi32.RegOpenKeyW -125 stdcall -noname RegOpenKeyExWrapW(long wstr long long ptr) advapi32.RegOpenKeyExW -126 stdcall -noname RegQueryInfoKeyWrapW(long ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) advapi32.RegQueryInfoKeyW -127 stdcall -noname RegQueryValueWrapW(long wstr ptr ptr) advapi32.RegQueryValueW -128 stdcall -noname RegQueryValueExWrapW(long wstr ptr ptr ptr ptr) advapi32.RegQueryValueExW -129 stdcall -noname RegSetValueWrapW(long wstr long ptr long) advapi32.RegSetValueW -130 stdcall -noname RegSetValueExWrapW(long wstr long long ptr long) advapi32.RegSetValueExW -131 stdcall -noname RegisterClassWrapW(ptr) user32.RegisterClassW -132 stdcall -noname RegisterClipboardFormatWrapW(wstr) user32.RegisterClipboardFormatW -133 stdcall -noname RegisterWindowMessageWrapW(wstr) user32.RegisterWindowMessageW -134 stdcall -noname RemovePropWrapW(long wstr) user32.RemovePropW -135 stdcall -noname SendDlgItemMessageWrapW(long long long long long) user32.SendDlgItemMessageW -136 stdcall -noname SendMessageWrapW(long long long long) user32.SendMessageW -137 stdcall -noname SetCurrentDirectoryWrapW(wstr) kernel32.SetCurrentDirectoryW -138 stdcall -noname SetDlgItemTextWrapW(long long wstr) user32.SetDlgItemTextW -139 stdcall -noname SetMenuItemInfoWrapW(long long long ptr) user32.SetMenuItemInfoW -140 stdcall -noname SetPropWrapW(long wstr long) user32.SetPropW -141 stdcall -noname SetWindowLongWrapW(long long long) user32.SetWindowLongW -142 stdcall -noname SetWindowsHookExWrapW(long long long long) user32.SetWindowsHookExW -143 stdcall -noname SetWindowTextWrapW(long wstr) user32.SetWindowTextW -144 stdcall -noname StartDocWrapW(long ptr) gdi32.StartDocW -145 stdcall -noname SystemParametersInfoWrapW(long long ptr long) user32.SystemParametersInfoW -146 stdcall -noname TranslateAcceleratorWrapW(long long ptr) user32.TranslateAcceleratorW -147 stdcall -noname UnregisterClassWrapW(wstr long) user32.UnregisterClassW -148 stdcall -noname VkKeyScanWrapW(long) user32.VkKeyScanW -149 stdcall -noname WinHelpWrapW(long wstr long long) user32.WinHelpW -150 stdcall -noname wvsprintfWrapW(ptr wstr ptr) user32.wvsprintfW -151 stdcall StrCmpNCA(str ptr long) -152 stdcall StrCmpNCW(wstr wstr long) -153 stdcall StrCmpNICA(long long long) -154 stdcall StrCmpNICW(wstr wstr long) -155 stdcall -ordinal StrCmpCA(str str) -156 stdcall -ordinal StrCmpCW(wstr wstr) -157 stdcall -ordinal StrCmpICA(str str) -158 stdcall -ordinal StrCmpICW(wstr wstr) -159 stdcall -noname CompareStringAltW(long long wstr long wstr long) kernel32.CompareStringW -160 stdcall -noname SHAboutInfoA(ptr long) -161 stdcall -noname SHAboutInfoW(ptr long) -162 stdcall -noname SHTruncateString(str long) -163 stdcall -noname IUnknown_QueryStatus(ptr ptr long ptr ptr) -164 stdcall -noname IUnknown_Exec(ptr ptr long long ptr ptr) -165 stdcall -noname SHSetWindowBits(long long long long) -166 stdcall -noname SHIsEmptyStream(ptr) -167 stdcall -noname SHSetParentHwnd(long ptr) -168 stdcall -noname ConnectToConnectionPoint(ptr ptr long ptr ptr ptr) -169 stdcall -noname IUnknown_AtomicRelease(long) -170 stdcall -noname PathSkipLeadingSlashesA(str) -171 stdcall -noname SHIsSameObject(ptr ptr) -172 stdcall -noname IUnknown_GetWindow(ptr ptr) -173 stdcall -noname IUnknown_SetOwner(ptr ptr) -174 stdcall -noname IUnknown_SetSite(ptr ptr) -175 stdcall -noname IUnknown_GetClassID(ptr ptr) -176 stdcall -noname IUnknown_QueryService(ptr ptr ptr ptr) -177 stdcall -noname SHLoadMenuPopup(ptr wstr) -178 stdcall -noname SHPropagateMessage(ptr long long long long) -179 stdcall -noname SHMenuIndexFromID(long long) -180 stdcall -noname SHRemoveAllSubMenus(long) -181 stdcall -noname SHEnableMenuItem(long long long) -182 stdcall -noname SHCheckMenuItem(long long long) -183 stdcall -noname SHRegisterClassA(ptr) -184 stdcall IStream_Read(ptr ptr long) -185 stdcall -noname SHMessageBoxCheckA(ptr str str long long str) -186 stdcall -noname SHSimulateDrop(ptr ptr long ptr ptr) -187 stdcall -noname SHLoadFromPropertyBag(ptr ptr) -188 stdcall -noname IUnknown_TranslateAcceleratorOCS(ptr ptr long) -189 stdcall -noname IUnknown_OnFocusOCS(ptr ptr) -190 stdcall -noname IUnknown_HandleIRestrict(ptr ptr ptr ptr ptr) -191 stdcall -noname SHMessageBoxCheckW(ptr wstr wstr long long wstr) -192 stdcall -noname SHGetMenuFromID(ptr long) -193 stdcall -noname SHGetCurColorRes() -194 stdcall -noname SHWaitForSendMessageThread(ptr long) -195 stdcall -noname SHIsExpandableFolder(ptr ptr) -196 stdcall -noname SHVerbExistsNA(str ptr ptr long) -197 stdcall -noname SHFillRectClr(long ptr long) -198 stdcall -noname SHSearchMapInt(ptr ptr long long) -199 stdcall -noname IUnknown_Set(ptr ptr) -200 stdcall -noname MayQSForward(ptr ptr ptr long ptr ptr) -201 stdcall -noname MayExecForward(ptr long ptr long long ptr ptr) -202 stdcall -noname IsQSForward(ptr long ptr) -203 stdcall -noname SHStripMneumonicA(str) -204 stdcall -noname SHIsChildOrSelf(long long) -205 stdcall -noname SHGetValueGoodBootA(long str str ptr ptr ptr) -206 stdcall -noname SHGetValueGoodBootW(long wstr wstr ptr ptr ptr) -207 stdcall -noname IContextMenu_Invoke(ptr ptr str long) -208 stdcall -noname FDSA_Initialize(long long ptr ptr long) -209 stdcall -noname FDSA_Destroy(ptr) -210 stdcall -noname FDSA_InsertItem(ptr long ptr) -211 stdcall -noname FDSA_DeleteItem(ptr long) -212 stdcall -noname IStream_Write(ptr ptr long) -213 stdcall -noname IStream_Reset(ptr) -214 stdcall -noname IStream_Size(ptr ptr) -215 stdcall -noname SHAnsiToUnicode(str ptr long) -216 stdcall -noname SHAnsiToUnicodeCP(long str ptr long) -217 stdcall -noname SHUnicodeToAnsi(wstr ptr ptr) -218 stdcall -noname SHUnicodeToAnsiCP(long wstr ptr long) -219 stdcall QISearch(long long long long) -220 stdcall -noname SHSetDefaultDialogFont(ptr long) -221 stdcall -noname SHRemoveDefaultDialogFont(ptr) -222 stdcall -noname SHGlobalCounterCreate(long) -223 stdcall -noname SHGlobalCounterGetValue(long) -224 stdcall -noname SHGlobalCounterIncrement(long) -225 stdcall -noname SHStripMneumonicW(wstr) -226 stdcall -noname ZoneCheckPathA(str long long ptr) -227 stdcall -noname ZoneCheckPathW(wstr long long ptr) -228 stdcall -noname ZoneCheckUrlA(str long long ptr) -229 stdcall -noname ZoneCheckUrlW(wstr long long ptr) -230 stdcall -noname ZoneCheckUrlExA(str ptr long long long long long long) -231 stdcall -noname ZoneCheckUrlExW(wstr ptr long long long long long long) -232 stdcall -noname ZoneCheckUrlExCacheA(str ptr long ptr long long long ptr ptr) -233 stdcall -noname ZoneCheckUrlExCacheW(wstr ptr long ptr long long long ptr ptr) -234 stdcall -noname ZoneCheckHost(ptr long long) -235 stdcall -noname ZoneCheckHostEx(ptr ptr long ptr long long long) -236 stdcall -noname SHPinDllOfCLSID(ptr) -237 stdcall -noname SHRegisterClassW(ptr) -238 stdcall -noname SHUnregisterClassesA(ptr ptr long) -239 stdcall -noname SHUnregisterClassesW(ptr ptr long) -240 stdcall -noname SHDefWindowProc(long long long long) -241 stdcall -noname StopWatchMode() -242 stdcall -noname StopWatchFlush() -243 stdcall -noname StopWatchA(long str long long long) -244 stdcall -noname StopWatchW(long wstr long long long) -245 stdcall -noname StopWatch_TimerHandler(ptr ptr long ptr) -246 stdcall -noname StopWatch_CheckMsg(ptr ptr str) -247 stdcall -noname StopWatch_MarkFrameStart(str) -248 stdcall -noname StopWatch_MarkSameFrameStart(ptr) -249 stdcall -noname StopWatch_MarkJavaStop(wstr ptr long) -250 stdcall -noname GetPerfTime() -251 stdcall -noname StopWatch_DispatchTime(long ptr long) -252 stdcall -noname StopWatch_SetMsgLastLocation(long) -253 stdcall -noname StopWatchExA(long str long long long long) -254 stdcall -noname StopWatchExW(long wstr long long long long) -255 stdcall -noname EventTraceHandler(long ptr) -256 stdcall -noname IUnknown_GetSite(ptr ptr ptr) -257 stdcall -noname SHCreateWorkerWindowA(long ptr long long ptr long) -258 stdcall -noname SHRegisterWaitForSingleObject(ptr ptr ptr long str long) -259 stdcall -noname SHUnregisterWait(ptr) -260 stdcall -noname SHQueueUserWorkItem(long long long long long long long) -261 stdcall -noname SHCreateTimerQueue() -262 stdcall -noname SHDeleteTimerQueue(ptr) -263 stdcall -noname SHSetTimerQueueTimer(long ptr ptr long long str long) -264 stdcall -noname SHChangeTimerQueueTimer(ptr ptr long long) -265 stdcall -noname SHCancelTimerQueueTimer(ptr ptr) -266 stdcall -noname SHRestrictionLookup(long wstr ptr ptr) -267 stdcall -noname SHWeakQueryInterface(long long long long) -268 stdcall -noname SHWeakReleaseInterface(long long) -269 stdcall -noname GUIDFromStringA(str ptr) -270 stdcall -noname GUIDFromStringW(wstr ptr) -271 stdcall -noname SHGetRestriction(wstr wstr wstr) -272 stdcall -noname SHSetThreadPoolLimits(ptr) -273 stdcall -noname SHTerminateThreadPool() -274 stdcall -noname RegisterGlobalHotkeyW(long long wstr) -275 stdcall -noname RegisterGlobalHotkeyA(long long str) -276 stdcall WhichPlatform() -277 stdcall -noname SHDialogBox(ptr wstr ptr ptr ptr) -278 stdcall -noname SHCreateWorkerWindowW(long long long long long long) -279 stdcall -noname SHInvokeDefaultCommand(ptr ptr ptr) -280 stdcall -noname SHRegGetIntW(ptr wstr long) -281 stdcall -noname SHPackDispParamsV(ptr ptr long ptr) -282 varargs -noname SHPackDispParams(ptr ptr long) -283 stdcall -noname IConnectionPoint_InvokeWithCancel(ptr long long long long) -284 stdcall -noname IConnectionPoint_SimpleInvoke(ptr long ptr) -285 stdcall -noname IConnectionPoint_OnChanged(ptr long) -286 varargs -noname IUnknown_CPContainerInvokeParam(ptr ptr long ptr long) -287 stdcall -noname IUnknown_CPContainerOnChanged(ptr long) -288 stdcall -noname IUnknown_CPContainerInvokeIndirect(ptr ptr ptr) -289 stdcall -noname PlaySoundWrapW(wstr long long) -290 stdcall -noname SHMirrorIcon(ptr ptr) -291 stdcall -noname SHMessageBoxCheckExA(ptr ptr ptr ptr ptr long str) -292 stdcall -noname SHMessageBoxCheckExW(ptr ptr ptr ptr ptr long wstr) -293 stdcall -noname SHCancelUserWorkItems(ptr long) -294 stdcall -noname SHGetIniStringW(wstr wstr ptr long wstr) -295 stdcall -noname SHSetIniStringW(wstr ptr wstr wstr) -296 stdcall -noname CreateURLFileContentsW(wstr ptr) -297 stdcall -noname CreateURLFileContentsA(str ptr) -298 stdcall -noname WritePrivateProfileStringWrapW(wstr wstr wstr wstr) kernel32.WritePrivateProfileStringW -299 stdcall -noname ExtTextOutWrapW(long long long long ptr wstr long ptr) gdi32.ExtTextOutW -300 stdcall -noname CreateFontWrapW(long long long long long long long long long long long long long wstr) gdi32.CreateFontW -301 stdcall -noname DrawTextExWrapW(long wstr long ptr long ptr) user32.DrawTextExW -302 stdcall -noname GetMenuItemInfoWrapW(long long long ptr) user32.GetMenuItemInfoW -303 stdcall -noname InsertMenuItemWrapW(long long long ptr) user32.InsertMenuItemW -304 stdcall -noname CreateMetaFileWrapW(wstr) gdi32.CreateMetaFileW -305 stdcall -noname CreateMutexWrapW(ptr long wstr) kernel32.CreateMutexW -306 stdcall -noname ExpandEnvironmentStringsWrapW(wstr ptr long) kernel32.ExpandEnvironmentStringsW -307 stdcall -noname CreateSemaphoreWrapW(ptr long long wstr) kernel32.CreateSemaphoreW -308 stdcall -noname IsBadStringPtrWrapW(ptr long) kernel32.IsBadStringPtrW -309 stdcall -noname LoadLibraryWrapW(wstr) kernel32.LoadLibraryW -310 stdcall -noname GetTimeFormatWrapW(long long ptr wstr ptr long) kernel32.GetTimeFormatW -311 stdcall -noname GetDateFormatWrapW(long long ptr wstr ptr long) kernel32.GetDateFormatW -312 stdcall -noname GetPrivateProfileStringWrapW(wstr wstr wstr ptr long wstr) kernel32.GetPrivateProfileStringW -313 stdcall -noname SHGetFileInfoWrapW(ptr long ptr long long) -314 stdcall -noname RegisterClassExWrapW(ptr) user32.RegisterClassExW -315 stdcall -noname GetClassInfoExWrapW(long wstr ptr) user32.GetClassInfoExW -316 stdcall -noname IShellFolder_GetDisplayNameOf(ptr ptr long str long) -317 stdcall -noname IShellFolder_ParseDisplayName(ptr ptr ptr str ptr ptr ptr) -318 stdcall -noname DragQueryFileWrapW(long long wstr long) -319 stdcall -noname FindWindowExWrapW(long long wstr wstr) user32.FindWindowExW -320 stdcall -noname RegisterMIMETypeForExtensionA(str str) -321 stdcall -noname RegisterMIMETypeForExtensionW(wstr wstr) -322 stdcall -noname UnregisterMIMETypeForExtensionA(str) -323 stdcall -noname UnregisterMIMETypeForExtensionW(wstr) -324 stdcall -noname RegisterExtensionForMIMETypeA(str str) -325 stdcall -noname RegisterExtensionForMIMETypeW(wstr wstr) -326 stdcall -noname UnregisterExtensionForMIMETypeA(str) -327 stdcall -noname UnregisterExtensionForMIMETypeW(wstr) -328 stdcall -noname GetMIMETypeSubKeyA(str ptr long) -329 stdcall -noname GetMIMETypeSubKeyW(wstr ptr long) -330 stdcall -noname MIME_GetExtensionA(str ptr long) -331 stdcall -noname MIME_GetExtensionW(wstr ptr long) -332 stdcall -noname CallMsgFilterWrapW(ptr long) user32.CallMsgFilterW -333 stdcall -noname SHBrowseForFolderWrapW(ptr) -334 stdcall -noname SHGetPathFromIDListWrapW(ptr ptr) -335 stdcall -noname ShellExecuteExWrapW(ptr) -336 stdcall -noname SHFileOperationWrapW(ptr) -337 stdcall -noname ExtractIconExWrapW(wstr long ptr ptr long) user32.PrivateExtractIconExW -338 stdcall -noname SetFileAttributesWrapW(wstr long) kernel32.SetFileAttributesW -339 stdcall -noname GetNumberFormatWrapW(long long wstr ptr ptr long) kernel32.GetNumberFormatW -340 stdcall -noname MessageBoxWrapW(long wstr wstr long) user32.MessageBoxW -341 stdcall -noname FindNextFileWrapW(long ptr) kernel32.FindNextFileW -342 stdcall -noname SHInterlockedCompareExchange(ptr ptr ptr) -343 stdcall -noname SHRegGetCLSIDKeyA(ptr str long long ptr) -344 stdcall -noname SHRegGetCLSIDKeyW(ptr wstr long long ptr) -345 stdcall -noname SHAnsiToAnsi(str ptr long) -346 stdcall -noname SHUnicodeToUnicode(wstr ptr long) -347 stdcall -noname RegDeleteValueWrapW(long wstr) advapi32.RegDeleteValueW -348 stdcall -noname SHGetFileDescriptionW(wstr wstr wstr wstr ptr) -349 stdcall -noname SHGetFileDescriptionA(str str str str ptr) -350 stdcall -noname GetFileVersionInfoSizeWrapW(wstr ptr) -351 stdcall -noname GetFileVersionInfoWrapW(wstr long long ptr) -352 stdcall -noname VerQueryValueWrapW(ptr wstr ptr ptr) -353 stdcall -noname SHFormatDateTimeA(ptr ptr str long) -354 stdcall -noname SHFormatDateTimeW(ptr ptr wstr long) -355 stdcall -noname IUnknown_EnableModeless(ptr long) -356 stdcall AssocCreate(int128 ptr ptr) -357 stdcall -noname SHGetNewLinkInfoWrapW(wstr wstr wstr long long) -358 stdcall -noname SHDefExtractIconWrapW(wstr long long ptr ptr long) -359 stdcall -noname OpenEventWrapW(long long wstr) kernel32.OpenEventW -360 stdcall -noname RemoveDirectoryWrapW(wstr) kernel32.RemoveDirectoryW -361 stdcall -noname GetShortPathNameWrapW(wstr ptr long) kernel32.GetShortPathNameW -362 stdcall -noname GetUserNameWrapW(ptr ptr) advapi32.GetUserNameW -363 stdcall -noname SHInvokeCommand(ptr ptr ptr long) -364 stdcall -noname DoesStringRoundTripA(str ptr long) -365 stdcall -noname DoesStringRoundTripW(wstr ptr long) -366 stdcall -noname RegEnumValueWrapW(long long ptr ptr ptr ptr ptr ptr) advapi32.RegEnumValueW -367 stdcall -noname WritePrivateProfileStructWrapW(wstr wstr ptr long wstr) kernel32.WritePrivateProfileStructW -368 stdcall -noname GetPrivateProfileStructWrapW(wstr wstr ptr long wstr) kernel32.GetPrivateProfileStructW -369 stdcall -noname CreateProcessWrapW(wstr wstr ptr ptr long long ptr wstr ptr ptr) kernel32.CreateProcessW -370 stdcall -noname ExtractIconWrapW(long wstr long) -371 stdcall -noname DdeInitializeWrapW(ptr ptr long long) user32.DdeInitializeW -372 stdcall -noname DdeCreateStringHandleWrapW(long ptr long) user32.DdeCreateStringHandleW -373 stdcall -noname DdeQueryStringWrapW(long ptr wstr long long) user32.DdeQueryStringW -374 stdcall -noname SHCheckDiskForMediaA(ptr ptr str long) -375 stdcall -noname SHCheckDiskForMediaW(ptr ptr wstr long) -376 stdcall -noname MLGetUILanguage() -377 stdcall -noname MLLoadLibraryA(str long long) -378 stdcall -noname MLLoadLibraryW(wstr long long) -379 stdcall -noname Shell_GetCachedImageIndexWrapW(wstr long long) -380 stdcall -noname Shell_GetCachedImageIndexWrapA(str long long) -381 stdcall -noname AssocCopyVerbs(ptr ptr) -382 stdcall -noname ZoneComputePaneSize(ptr) -383 stdcall -noname ZoneConfigureW(ptr wstr) -384 stdcall -noname SHRestrictedMessageBox(ptr) -385 stdcall -noname SHLoadRawAccelerators(ptr str) -386 stdcall -noname SHQueryRawAccelerator(ptr long long ptr ptr) -387 stdcall -noname SHQueryRawAcceleratorMsg(ptr ptr ptr) -388 varargs -noname ShellMessageBoxWrapW(long long wstr wstr long) -389 stdcall -noname GetSaveFileNameWrapW(ptr) -390 stdcall -noname WNetRestoreConnectionWrapW(long wstr) -391 stdcall -noname WNetGetLastErrorWrapW(ptr ptr long ptr long) -392 stdcall -noname EndDialogWrap(ptr ptr) user32.EndDialog -393 stdcall -noname CreateDialogIndirectParamWrapW(long ptr long ptr long) user32.CreateDialogIndirectParamW -394 stdcall -noname SHChangeNotifyWrap(long long ptr ptr) -395 stdcall -noname MLWinHelpA(ptr str long long) -396 stdcall -noname MLHtmlHelpA(ptr str long long long) -397 stdcall -noname MLWinHelpW(ptr wstr long long) -398 stdcall -noname MLHtmlHelpW(ptr wstr long long long) -399 stdcall -noname StrCpyNXA(ptr str long) -400 stdcall -noname StrCpyNXW(ptr wstr long) -401 stdcall -noname PageSetupDlgWrapW(ptr) -402 stdcall -noname PrintDlgWrapW(ptr) -403 stdcall -noname GetOpenFileNameWrapW(ptr) -404 stdcall -noname IShellFolder_EnumObjects(ptr ptr long ptr) -405 stdcall -noname MLBuildResURLA(str ptr long str ptr long) -406 stdcall -noname MLBuildResURLW(wstr ptr long wstr ptr long) -407 stdcall -noname AssocMakeProgid(long wstr ptr ptr) -408 stdcall -noname AssocMakeShell(long ptr wstr ptr) -409 stdcall -noname AssocMakeApplicationByKeyW(long ptr wstr) -410 stdcall -noname AssocMakeApplicationByKeyA(long ptr str) -411 stdcall -noname AssocMakeFileExtsToApplicationW(long str str) -412 stdcall -noname AssocMakeFileExtsToApplicationA(long str str) -413 stdcall -noname SHGetMachineInfo(long) -414 stdcall -noname SHHtmlHelpOnDemandW(ptr wstr long long long long) -415 stdcall -noname SHHtmlHelpOnDemandA(ptr str long long long long) -416 stdcall -noname SHWinHelpOnDemandW(long wstr long ptr long) -417 stdcall -noname SHWinHelpOnDemandA(long str long ptr long) -418 stdcall -noname MLFreeLibrary(long) -419 stdcall -noname SHFlushSFCacheWrap() -420 stdcall -noname SHPersistDataObject(ptr ptr) -421 stdcall -noname SHLoadPersistedDataObject(ptr ptr) -422 stdcall -noname SHGlobalCounterCreateNamedA(str long) -423 stdcall -noname SHGlobalCounterCreateNamedW(wstr long) -424 stdcall -noname SHGlobalCounterDecrement(long) -425 stdcall -noname DeleteMenuWrap(ptr long long) user32.DeleteMenu -426 stdcall -noname DestroyMenuWrap(long) user32.DestroyMenu -427 stdcall -noname TrackPopupMenuWrap(long long long long long long ptr) user32.TrackPopupMenu -428 stdcall -noname TrackPopupMenuExWrap(long long long long long ptr) user32.TrackPopupMenuEx -429 stdcall -noname MLIsMLHInstance(long) -430 stdcall -noname MLSetMLHInstance(long long) -431 stdcall -noname MLClearMLHInstance(long) -432 stdcall -noname SHSendMessageBroadcastA(long long long) -433 stdcall -noname SHSendMessageBroadcastW(long long long) -434 stdcall -noname SendMessageTimeoutWrapW(long long long long long long ptr) user32.SendMessageTimeoutW -435 stdcall -noname CLSIDFromProgIDWrap(wstr ptr) -436 stdcall -noname CLSIDFromStringWrap(wstr ptr) -437 stdcall IsOS(long) -438 stdcall -noname SHLoadRegUIStringA(ptr str str long) -439 stdcall -noname SHLoadRegUIStringW(ptr wstr ptr long) -440 stdcall -noname SHGetWebFolderFilePathA(str ptr long) -441 stdcall -noname SHGetWebFolderFilePathW(wstr ptr long) -442 stdcall -noname GetEnvironmentVariableWrapW(wstr ptr long) kernel32.GetEnvironmentVariableW -443 stdcall -noname SHGetSystemWindowsDirectoryA(ptr long) kernel32.GetSystemWindowsDirectoryA -444 stdcall -noname SHGetSystemWindowsDirectoryW(ptr long) kernel32.GetSystemWindowsDirectoryW -445 stdcall -noname PathFileExistsAndAttributesA(str ptr) -446 stdcall -noname PathFileExistsAndAttributesW(wstr ptr) -447 stdcall -noname FixSlashesAndColonA(str) -448 stdcall -noname FixSlashesAndColonW(wstr) -449 stdcall -noname NextPathA(str str long) -450 stdcall -noname NextPathW(wstr wstr long) -451 stdcall -noname CharUpperNoDBCSA(str) -452 stdcall -noname CharUpperNoDBCSW(wstr) -453 stdcall -noname CharLowerNoDBCSA(str) -454 stdcall -noname CharLowerNoDBCSW(wstr) -455 stdcall -noname PathIsValidCharA(long long) -456 stdcall -noname PathIsValidCharW(long long) -457 stdcall -noname GetLongPathNameWrapW(wstr ptr long) kernel32.GetLongPathNameW -458 stdcall -noname GetLongPathNameWrapA(str ptr long) kernel32.GetLongPathNameA -459 stdcall -noname SHExpandEnvironmentStringsA(str ptr long) -460 stdcall -noname SHExpandEnvironmentStringsW(wstr ptr long) -461 stdcall -noname SHGetAppCompatFlags(long) -462 stdcall UrlFixupW(wstr wstr long) -463 stdcall -noname SHExpandEnvironmentStringsForUserA(ptr str ptr long) -464 stdcall -noname SHExpandEnvironmentStringsForUserW(ptr wstr ptr long) -465 stdcall -noname PathUnExpandEnvStringsForUserA(ptr str ptr long) -466 stdcall -noname PathUnExpandEnvStringsForUserW(ptr wstr ptr long) -467 stdcall -noname SHRunIndirectRegClientCommand(ptr wstr) -468 stdcall -noname RunIndirectRegCommand(ptr ptr wstr wstr) -469 stdcall -noname RunRegCommand(ptr ptr wstr) -470 stdcall -noname IUnknown_ProfferServiceOld(ptr ptr ptr ptr ptr) -471 stdcall -noname SHCreatePropertyBagOnRegKey(long wstr long ptr ptr) -472 stdcall -noname SHCreatePropertyBagOnProfileSelection(wstr long long long long) -473 stdcall -noname SHGetIniStringUTF7W(wstr wstr wstr long wstr) -474 stdcall -noname SHSetIniStringUTF7W(wstr wstr wstr wstr) -475 stdcall -noname GetShellSecurityDescriptor(ptr long) -476 stdcall -noname SHGetObjectCompatFlags(ptr ptr) -477 stdcall -noname SHCreatePropertyBagOnMemory(long ptr ptr) -478 stdcall -noname IUnknown_TranslateAcceleratorIO(ptr ptr) -479 stdcall -noname IUnknown_UIActivateIO(ptr long ptr) -480 stdcall -noname UrlCrackW(wstr long long ptr) -481 stdcall -noname IUnknown_HasFocusIO(ptr) -482 stdcall -noname SHMessageBoxHelpA(ptr str str long long ptr long) -483 stdcall -noname SHMessageBoxHelpW(ptr wstr str long long ptr long) -484 stdcall -noname IUnknown_QueryServiceExec(ptr ptr ptr long long long ptr) -485 stdcall -noname MapWin32ErrorToSTG(long) -486 stdcall -noname ModeToCreateFileFlags(long long ptr ptr ptr) -487 stdcall -ordinal SHLoadIndirectString(wstr ptr long ptr) -488 stdcall -noname SHConvertGraphicsFile(wstr wstr long) -489 stdcall -noname GlobalAddAtomWrapW(wstr) kernel32.GlobalAddAtomW -490 stdcall -noname GlobalFindAtomWrapW(wstr) kernel32.GlobalFindAtomW -491 stdcall -noname SHGetShellKey(long long long) -492 stdcall -noname PrettifyFileDescriptionW(wstr wstr wstr) -493 stdcall -noname SHPropertyBag_ReadType(ptr wstr ptr long) -494 stdcall -noname SHPropertyBag_ReadStr(ptr wstr wstr long) -495 stdcall -noname SHPropertyBag_WriteStr(ptr wstr wstr) -496 stdcall -noname SHPropertyBag_ReadLONG(ptr wstr ptr) -497 stdcall -noname SHPropertyBag_WriteLONG(ptr wstr long) -498 stdcall -noname SHPropertyBag_ReadBOOLOld(ptr wstr long) -499 stdcall -noname SHPropertyBag_WriteBOOL(ptr wstr long) -505 stdcall -noname SHPropertyBag_ReadGUID(ptr wstr ptr) -506 stdcall -noname SHPropertyBag_WriteGUID(ptr wstr long) -507 stdcall -noname SHPropertyBag_ReadDWORD(ptr wstr ptr) -508 stdcall -noname SHPropertyBag_WriteDWORD(ptr wstr long) -509 stdcall -noname IUnknown_OnFocusChangeIS(ptr ptr long) -510 stdcall -noname SHLockSharedEx(ptr long long) -511 stdcall -noname PathFileExistsDefExtAndAttributesW(wstr ptr ptr) -512 stdcall IStream_ReadPidl(ptr ptr) -513 stdcall -noname -ordinal IStream_WritePidl(ptr ptr) -514 stdcall -noname IUnknown_ProfferService(ptr ptr ptr ptr) -515 stdcall -ordinal SHGetViewStatePropertyBag(ptr wstr long ptr ptr) -516 stdcall -noname SKGetValueW(long wstr wstr ptr ptr ptr) -517 stdcall -noname SKSetValueW(long wstr wstr long ptr long) -518 stdcall -noname SKDeleteValueW(long wstr wstr) -519 stdcall -noname SKAllocValueW(long wstr wstr ptr ptr ptr) -520 stdcall -noname SHPropertyBag_ReadBSTR(ptr wstr ptr) -521 stdcall -noname SHPropertyBag_ReadPOINTL(ptr wstr ptr) -522 stdcall -noname SHPropertyBag_WritePOINTL(ptr wstr ptr) -523 stdcall -noname SHPropertyBag_ReadRECTL(ptr wstr ptr) -524 stdcall -noname SHPropertyBag_WriteRECTL(ptr wstr ptr) -525 stdcall -noname SHPropertyBag_ReadPOINTS(ptr wstr ptr) -526 stdcall -noname SHPropertyBag_WritePOINTS(ptr wstr ptr) -527 stdcall -noname SHPropertyBag_ReadSHORT(ptr wstr ptr) -528 stdcall -noname SHPropertyBag_WriteSHORT(ptr wstr ptr) -529 stdcall -noname SHPropertyBag_ReadInt(ptr wstr ptr) -530 stdcall -noname SHPropertyBag_WriteInt(ptr wstr long) -531 stdcall -noname SHPropertyBag_ReadStream(ptr wstr ptr) -532 stdcall -noname SHPropertyBag_WriteStream(ptr wstr ptr) -533 stdcall -noname SHGetPerScreenResName(wstr long long) -534 stdcall -noname SHPropertyBag_ReadBOOL(ptr wstr ptr) -535 stdcall -noname SHPropertyBag_Delete(ptr wstr) -536 stdcall -noname IUnknown_QueryServicePropertyBag(ptr long long ptr) -537 stdcall -noname SHBoolSystemParametersInfo(long ptr) -538 stdcall -noname IUnknown_QueryServiceForWebBrowserApp(ptr ptr ptr) -539 stdcall -noname IUnknown_ShowBrowserBar(ptr long long) -540 stdcall -noname SHInvokeCommandOnContextMenu(ptr ptr ptr long str) -541 stdcall -noname SHInvokeCommandsOnContextMenu(ptr ptr ptr long str long) -542 stdcall -noname GetUIVersion() -543 stdcall -noname CreateColorSpaceWrapW(ptr) gdi32.CreateColorSpaceW -544 stdcall -noname QuerySourceCreateFromKey(ptr wstr long ptr ptr) -545 stdcall -noname SHForwardContextMenuMsg(ptr long long ptr ptr long) -546 stdcall -noname IUnknown_DoContextMenuPopup(ptr ptr long ptr) -547 stdcall DelayLoadFailureHook(str str) kernel32.DelayLoadFailureHook -548 stdcall -noname SHAreIconsEqual(ptr ptr) -549 stdcall -noname SHCoCreateInstanceAC(ptr ptr long ptr ptr) -550 stdcall -noname GetTemplateInfoFromHandle(ptr ptr ptr) -551 stdcall -noname IShellFolder_CompareIDs(ptr ptr ptr ptr) -552 stdcall -noname SHEvaluateSystemCommandTemplate(wstr wstr wstr wstr) -553 stdcall IsInternetESCEnabled() -554 stdcall -noname SHGetAllAccessSA(ptr ptr) -556 stdcall -noname SHCoExtensionAllowed(ptr ptr) -557 stdcall -noname SHCoCreateExtension(ptr ptr long long ptr ptr) -558 stdcall -noname SHCoExtensionCollectStats(ptr str long) -559 stdcall -noname SHGetSignatureInfo(wstr str ptr) -560 stdcall -noname SHWindowsPolicyGetValue(ptr ptr ptr) -561 stdcall -noname AssocGetUrlAction(wstr) -562 stdcall -noname SHGetPrivateProfileInt(wstr long long wstr) -563 stdcall -noname SHGetPrivateProfileSection(wstr long long wstr) -564 stdcall -noname SHGetPrivateProfileSectionNames(long long wstr) -565 stdcall -noname SHGetPrivateProfileString(wstr long long long long wstr) -566 stdcall -noname SHGetPrivateProfileStruct(wstr long long long wstr) - - -#This ordinal is for x86 -500 stdcall -i386 AssocGetPerceivedType(wstr ptr ptr ptr) ;shlwapibase.AssocGetPerceivedType -501 stdcall -i386 AssocIsDangerous(wstr) -502 stdcall -i386 AssocQueryKeyA(long long str str ptr) -503 stdcall -i386 AssocQueryKeyW(long long wstr wstr ptr) -504 stdcall -i386 AssocQueryStringA(long long str str ptr ptr) -555 stdcall -i386 AssocQueryStringByKeyA(long long ptr str ptr ptr) -567 stdcall -i386 AssocQueryStringByKeyW(long long ptr wstr ptr ptr) -569 stdcall -i386 ChrCmpIA(long long) -570 stdcall -i386 ChrCmpIW(long long) -571 stdcall -i386 ColorAdjustLuma(long long long) -572 stdcall -i386 ColorHLSToRGB(long long long) -573 stdcall -i386 ColorRGBToHLS(long ptr ptr ptr) -575 stdcall -i386 GetMenuPosFromID(ptr long) -576 stdcall -i386 HashData(ptr long ptr long) -577 stdcall -i386 IntlStrEqWorkerA(long str str long) StrIsIntlEqualA -578 stdcall -i386 IntlStrEqWorkerW(long wstr wstr long) StrIsIntlEqualW -579 stdcall -i386 IsCharSpaceA(long) ;shlwapibase.IsCharSpaceA -580 stdcall -i386 PathAddBackslashA(str) -581 stdcall -i386 PathAddBackslashW(wstr) -582 stdcall -i386 PathAddExtensionA(str str) -583 stdcall -i386 PathAddExtensionW(wstr wstr) -584 stdcall -i386 PathAppendA(str str) -585 stdcall -i386 PathAppendW(wstr wstr) -586 stdcall -i386 PathBuildRootA(ptr long) -587 stdcall -i386 PathBuildRootW(ptr long) -588 stdcall -i386 PathCanonicalizeA(ptr str) -589 stdcall -i386 PathCanonicalizeW(ptr wstr) -590 stdcall -i386 PathCombineA(ptr str str) -591 stdcall -i386 PathCombineW(ptr wstr wstr) -592 stdcall -i386 PathCommonPrefixA(str str ptr) -593 stdcall -i386 PathCommonPrefixW(wstr wstr ptr) -594 stdcall -i386 PathCompactPathA(long str long) -595 stdcall -i386 PathCompactPathExA(ptr str long long) -596 stdcall -i386 PathCompactPathExW(ptr wstr long long) -597 stdcall -i386 PathCompactPathW(long wstr long) -598 stdcall -i386 PathCreateFromUrlA(str ptr ptr long) -599 stdcall -i386 PathCreateFromUrlW(wstr ptr ptr long) -600 stdcall -i386 PathFileExistsA(str) -601 stdcall -i386 PathFileExistsW(wstr) -602 stdcall -i386 PathFindExtensionA(str) -603 stdcall -i386 PathFindExtensionW(wstr) -604 stdcall -i386 PathFindFileNameA(str) -605 stdcall -i386 PathFindFileNameW(wstr) -606 stdcall -i386 PathFindNextComponentA(str) -607 stdcall -i386 PathFindNextComponentW(wstr) -608 stdcall -i386 PathFindOnPathA(str ptr) -609 stdcall -i386 PathFindOnPathW(wstr ptr) -610 stdcall -i386 PathFindSuffixArrayA(str ptr long) -611 stdcall -i386 PathFindSuffixArrayW(wstr ptr long) -612 stdcall -i386 PathGetArgsA(str) -613 stdcall -i386 PathGetArgsW(wstr) -614 stdcall -i386 PathGetCharTypeA(long) -615 stdcall -i386 PathGetCharTypeW(long) -616 stdcall -i386 PathGetDriveNumberA(str) -617 stdcall -i386 PathGetDriveNumberW(wstr) -619 stdcall -i386 PathIsContentTypeW(wstr wstr) -620 stdcall -i386 PathIsDirectoryA(str) -621 stdcall -i386 PathIsDirectoryEmptyA(str) -622 stdcall -i386 PathIsDirectoryEmptyW(wstr) -623 stdcall -i386 PathIsDirectoryW(wstr) -624 stdcall -i386 PathIsFileSpecA(str) -625 stdcall -i386 PathIsFileSpecW(wstr) -626 stdcall -i386 PathIsLFNFileSpecA(str) -627 stdcall -i386 PathIsLFNFileSpecW(wstr) -629 stdcall -i386 PathIsNetworkPathW(wstr) -630 stdcall -i386 PathIsPrefixA(str str) -631 stdcall -i386 PathIsPrefixW(wstr wstr) -632 stdcall -i386 PathIsRelativeA(str) -633 stdcall -i386 PathIsRelativeW(wstr) -634 stdcall -i386 PathIsRootA(str) -635 stdcall -i386 PathIsRootW(wstr) -636 stdcall -i386 PathIsSameRootA(str str) -637 stdcall -i386 PathIsSameRootW(wstr wstr) -638 stdcall -i386 PathIsSystemFolderA(str long) -639 stdcall -i386 PathIsSystemFolderW(wstr long) -640 stdcall -i386 PathIsUNCA(str) -641 stdcall -i386 PathIsUNCServerA(str) -642 stdcall -i386 PathIsUNCServerShareA(str) -643 stdcall -i386 PathIsUNCServerShareW(wstr) -644 stdcall -i386 PathIsUNCServerW(wstr) -645 stdcall -i386 PathIsUNCW(wstr) -646 stdcall -i386 PathIsURLA(str) -647 stdcall -i386 PathIsURLW(wstr) -648 stdcall -i386 PathMakePrettyA(str) -649 stdcall -i386 PathMakePrettyW(wstr) -650 stdcall -i386 PathMakeSystemFolderA(str) -651 stdcall -i386 PathMakeSystemFolderW(wstr) -652 stdcall -i386 PathMatchSpecA(str str) -653 stdcall -i386 PathMatchSpecW(wstr wstr) -654 stdcall -i386 PathParseIconLocationA(str) -655 stdcall -i386 PathParseIconLocationW(wstr) -656 stdcall -i386 PathQuoteSpacesA(str) -657 stdcall -i386 PathQuoteSpacesW(wstr) -658 stdcall -i386 PathRelativePathToA(ptr str long str long) -659 stdcall -i386 PathRelativePathToW(ptr wstr long wstr long) -660 stdcall -i386 PathRemoveArgsA(str) -661 stdcall -i386 PathRemoveArgsW(wstr) -662 stdcall -i386 PathRemoveBackslashA(str) -663 stdcall -i386 PathRemoveBackslashW(wstr) -664 stdcall -i386 PathRemoveBlanksA(str) -665 stdcall -i386 PathRemoveBlanksW(wstr) -666 stdcall -i386 PathRemoveExtensionA(str) -667 stdcall -i386 PathRemoveExtensionW(wstr) -668 stdcall -i386 PathRemoveFileSpecA(str) -669 stdcall -i386 PathRemoveFileSpecW(wstr) -670 stdcall -i386 PathRenameExtensionA(str str) -671 stdcall -i386 PathRenameExtensionW(wstr wstr) -672 stdcall -i386 PathSearchAndQualifyA(str ptr long) -673 stdcall -i386 PathSearchAndQualifyW(wstr ptr long) -674 stdcall -i386 PathSetDlgItemPathA(long long ptr) -675 stdcall -i386 PathSetDlgItemPathW(long long ptr) -676 stdcall -i386 PathSkipRootA(str) -677 stdcall -i386 PathSkipRootW(wstr) -678 stdcall -i386 PathStripPathA(str) -679 stdcall -i386 PathStripPathW(wstr) -680 stdcall -i386 PathStripToRootA(str) -681 stdcall -i386 PathStripToRootW(wstr) -682 stdcall -i386 PathUnExpandEnvStringsA(str ptr long) -683 stdcall -i386 PathUnExpandEnvStringsW(wstr ptr long) -684 stdcall -i386 PathUndecorateA(str) -685 stdcall -i386 PathUndecorateW(wstr) -686 stdcall -i386 PathUnmakeSystemFolderA(str) -687 stdcall -i386 PathUnmakeSystemFolderW(wstr) -688 stdcall -i386 PathUnquoteSpacesA(str) -689 stdcall -i386 PathUnquoteSpacesW(wstr) -690 stdcall -i386 SHAutoComplete(ptr long) -691 stdcall -i386 SHCopyKeyA(long str long long) -692 stdcall -i386 SHCopyKeyW(long wstr long long) -693 stdcall -i386 SHCreateShellPalette(long) -694 stdcall -i386 SHCreateStreamOnFileA(str long ptr) -695 stdcall -i386 SHCreateStreamOnFileEx(wstr long long long ptr ptr) -696 stdcall -i386 SHCreateStreamOnFileW(wstr long ptr) -697 stdcall -i386 SHCreateStreamWrapper(ptr ptr long ptr) -#698 stdcall -i386 SHCreateThreadRef(ptr ptr) shlwapibase.SHCreateThreadRef -699 stdcall -i386 SHDeleteEmptyKeyA(long ptr) -700 stdcall -i386 SHDeleteEmptyKeyW(long ptr) -701 stdcall -i386 SHDeleteKeyA(long str) -702 stdcall -i386 SHDeleteKeyW(long wstr) -703 stdcall -i386 SHDeleteOrphanKeyA(long str) -704 stdcall -i386 SHDeleteOrphanKeyW(long wstr) -705 stdcall -i386 SHDeleteValueA(long str str) -706 stdcall -i386 SHDeleteValueW(long wstr wstr) -707 stdcall -i386 SHEnumKeyExA(long long str ptr) -708 stdcall -i386 SHEnumKeyExW(long long wstr ptr) -709 stdcall -i386 SHEnumValueA(long long str ptr ptr ptr ptr) -710 stdcall -i386 SHEnumValueW(long long wstr ptr ptr ptr ptr) -711 stdcall -i386 SHGetInverseCMAP(ptr long) -712 stdcall -i386 SHGetThreadRef(ptr) -713 stdcall -i386 SHGetValueA(long str str ptr ptr ptr) -714 stdcall -i386 SHGetValueW(long wstr wstr ptr ptr ptr) -715 stdcall -i386 SHIsLowMemoryMachine(long) -716 stdcall -i386 SHOpenRegStream2A(long str str long) -717 stdcall -i386 SHOpenRegStream2W(long wstr wstr long) -718 stdcall -i386 SHOpenRegStreamA(long str str long) -719 stdcall -i386 SHOpenRegStreamW(long wstr wstr long) -720 stdcall -i386 SHQueryInfoKeyA(long ptr ptr ptr ptr) -721 stdcall -i386 SHQueryInfoKeyW(long ptr ptr ptr ptr) -722 stdcall -i386 SHQueryValueExA(long str ptr ptr ptr ptr) -723 stdcall -i386 SHQueryValueExW(long wstr ptr ptr ptr ptr) -724 stdcall -i386 SHRegCloseUSKey(ptr) -725 stdcall -i386 SHRegCreateUSKeyA(str long long ptr long) -726 stdcall -i386 SHRegCreateUSKeyW(wstr long long ptr long) -727 stdcall -i386 SHRegDeleteEmptyUSKeyA(long str long) -728 stdcall -i386 SHRegDeleteEmptyUSKeyW(long wstr long) -729 stdcall -i386 SHRegDeleteUSValueA(long str long) -730 stdcall -i386 SHRegDeleteUSValueW(long wstr long) -731 stdcall -i386 SHRegDuplicateHKey(long) -732 stdcall -i386 SHRegEnumUSKeyA(long long str ptr long) -733 stdcall -i386 SHRegEnumUSKeyW(long long wstr ptr long) -734 stdcall -i386 SHRegEnumUSValueA(long long ptr ptr ptr ptr ptr long) -735 stdcall -i386 SHRegEnumUSValueW(long long ptr ptr ptr ptr ptr long) -736 stdcall -i386 SHRegGetBoolUSValueA(str str long long) -737 stdcall -i386 SHRegGetBoolUSValueW(wstr wstr long long) -738 stdcall -i386 SHRegGetPathA(long str str ptr long) -739 stdcall -i386 SHRegGetPathW(long wstr wstr ptr long) -740 stdcall -i386 SHRegGetUSValueA(str str ptr ptr ptr long ptr long) -741 stdcall -i386 SHRegGetUSValueW(wstr wstr ptr ptr ptr long ptr long) -744 stdcall -i386 SHRegOpenUSKeyA(str long long long long) -745 stdcall -i386 SHRegOpenUSKeyW(wstr long long long long) -746 stdcall -i386 SHRegQueryInfoUSKeyA(long ptr ptr ptr ptr long) -747 stdcall -i386 SHRegQueryInfoUSKeyW(long ptr ptr ptr ptr long) -748 stdcall -i386 SHRegQueryUSValueA(long str ptr ptr ptr long ptr long) -749 stdcall -i386 SHRegQueryUSValueW(long wstr ptr ptr ptr long ptr long) -750 stdcall -i386 SHRegSetPathA(long str str str long) -751 stdcall -i386 SHRegSetPathW(long wstr wstr wstr long) -752 stdcall -i386 SHRegSetUSValueA(str str long ptr long long) -753 stdcall -i386 SHRegSetUSValueW(wstr wstr long ptr long long) -754 stdcall -i386 SHRegWriteUSValueA(long str long ptr long long) -755 stdcall -i386 SHRegWriteUSValueW(long wstr long ptr long long) -756 stdcall -i386 SHRegisterValidateTemplate(wstr long) -757 stdcall -i386 SHReleaseThreadRef() -758 stdcall -i386 SHSetThreadRef(ptr) -759 stdcall -i386 SHSetValueA(long str str long ptr long) -760 stdcall -i386 SHSetValueW(long wstr wstr long ptr long) -761 stdcall -i386 SHSkipJunction(ptr ptr) -762 stdcall -i386 SHStrDupA(str ptr) -763 stdcall -i386 SHStrDupW(wstr ptr) -764 stdcall -i386 StrCSpnA(str str) -765 stdcall -i386 StrCSpnIA(str str) -766 stdcall -i386 StrCSpnIW(wstr wstr) -767 stdcall -i386 StrCSpnW(wstr wstr) -768 stdcall -i386 StrCatBuffA(str str long) -769 stdcall -i386 StrCatBuffW(wstr wstr long) -770 stdcall -i386 StrCatChainW(wstr long long wstr) -771 stdcall -i386 StrCatW(ptr wstr) -772 stdcall -i386 StrChrA(str long) -773 stdcall -i386 StrChrIA(str long) -774 stdcall -i386 StrChrIW(wstr long) -775 stdcall -i386 StrChrNIW(wstr wstr long) -776 stdcall -i386 StrChrNW(wstr long long) -777 stdcall -i386 StrChrW(wstr long) -778 stdcall -i386 StrCmpIW(wstr wstr) -779 stdcall -i386 StrCmpLogicalW(wstr wstr) -780 stdcall -i386 StrCmpNA(str str long) -781 stdcall -i386 StrCmpNIA(str str long) -782 stdcall -i386 StrCmpNIW(wstr wstr long) -783 stdcall -i386 StrCmpNW(wstr wstr long) -784 stdcall -i386 StrCmpW(wstr wstr) -785 stdcall -i386 StrCpyNW(ptr wstr long) -786 stdcall -i386 StrCpyW(ptr wstr) -787 stdcall -i386 StrDupA(str) -788 stdcall -i386 StrDupW(wstr) -789 stdcall -i386 StrFormatByteSize64A(int64 ptr long) -790 stdcall -i386 StrFormatByteSizeA(long ptr long) -791 stdcall -i386 StrFormatByteSizeW(int64 ptr long) -792 stdcall -i386 StrFormatKBSizeA(int64 str long) -793 stdcall -i386 StrFormatKBSizeW(int64 wstr long) -794 stdcall -i386 StrFromTimeIntervalA(ptr long long long) -795 stdcall -i386 StrFromTimeIntervalW(ptr long long long) -796 stdcall -i386 StrIsIntlEqualA(long str str long) -797 stdcall -i386 StrIsIntlEqualW(long wstr wstr long) -798 stdcall -i386 StrNCatA(str str long) -799 stdcall -i386 StrNCatW(wstr wstr long) -800 stdcall -i386 StrPBrkA(str str) -801 stdcall -i386 StrPBrkW(wstr wstr) -802 stdcall -i386 StrRChrA(str str long) -803 stdcall -i386 StrRChrIA(str str long) -804 stdcall -i386 StrRChrIW(wstr wstr long) -805 stdcall -i386 StrRChrW(wstr wstr long) -806 stdcall -i386 StrRStrIA(str str str) -807 stdcall -i386 StrRStrIW(wstr wstr wstr) -808 stdcall -i386 StrRetToBSTR(ptr ptr ptr) -809 stdcall -i386 StrRetToBufA(ptr ptr ptr long) -810 stdcall -i386 StrRetToBufW(ptr ptr ptr long) -811 stdcall -i386 StrRetToStrA(ptr ptr ptr) -812 stdcall -i386 StrRetToStrW(ptr ptr ptr) -813 stdcall -i386 StrSpnA(str str) -814 stdcall -i386 StrSpnW(wstr wstr) -815 stdcall -i386 StrStrA(str str) -816 stdcall -i386 StrStrIA(str str) -817 stdcall -i386 StrStrIW(wstr wstr) -818 stdcall -i386 StrStrNIW(wstr wstr long) -819 stdcall -i386 StrStrNW(wstr wstr long) -820 stdcall -i386 StrStrW(wstr wstr) -821 stdcall -i386 StrToInt64ExA(str long ptr) -822 stdcall -i386 StrToInt64ExW(wstr long ptr) -823 stdcall -i386 StrToIntA(str) -824 stdcall -i386 StrToIntExA(str long ptr) -825 stdcall -i386 StrToIntExW(wstr long ptr) -826 stdcall -i386 StrToIntW(wstr) -827 stdcall -i386 StrTrimA(str str) -828 stdcall -i386 StrTrimW(wstr wstr) -829 stdcall -i386 UrlApplySchemeA(str ptr ptr long) -830 stdcall -i386 UrlApplySchemeW(wstr ptr ptr long) -831 stdcall -i386 UrlCanonicalizeA(str ptr ptr long) -832 stdcall -i386 UrlCanonicalizeW(wstr ptr ptr long) -833 stdcall -i386 UrlCombineA(str str ptr ptr long) -834 stdcall -i386 UrlCombineW(wstr wstr ptr ptr long) -835 stdcall -i386 UrlCompareA(str str long) -836 stdcall -i386 UrlCompareW(wstr wstr long) -837 stdcall -i386 UrlCreateFromPathA(str ptr ptr long) -838 stdcall -i386 UrlCreateFromPathW(wstr ptr ptr long) -839 stdcall -i386 UrlEscapeA(str ptr ptr long) -840 stdcall -i386 UrlEscapeW(wstr ptr ptr long) -841 stdcall -i386 UrlGetLocationA(str) -842 stdcall -i386 UrlGetLocationW(wstr) -843 stdcall -i386 UrlGetPartA(str ptr ptr long long) -844 stdcall -i386 UrlGetPartW(wstr ptr ptr long long) -845 stdcall -i386 UrlHashA(str ptr long) -846 stdcall -i386 UrlHashW(wstr ptr long) -847 stdcall -i386 UrlIsA(str long) -848 stdcall -i386 UrlIsNoHistoryA(str) -849 stdcall -i386 UrlIsNoHistoryW(wstr) -850 stdcall -i386 UrlIsOpaqueA(str) -851 stdcall -i386 UrlIsOpaqueW(wstr) -852 stdcall -i386 UrlIsW(wstr long) -853 stdcall -i386 UrlUnescapeA(str ptr ptr long) -854 stdcall -i386 UrlUnescapeW(wstr ptr ptr long) -855 varargs -i386 wnsprintfA(ptr long str) -856 varargs -i386 wnsprintfW(ptr long wstr) -857 stdcall -i386 wvnsprintfA(ptr long str ptr) -858 stdcall -i386 wvnsprintfW(ptr long wstr ptr) - -#This ordinal is for x64 -500 stdcall -arch=x86_64 -noname ualstrcpynW(wstr wstr long) -501 stdcall -arch=x86_64 -noname SHLWAPI_501(wstr wstr) -502 stdcall -arch=x86_64 -noname SHLWAPI_502(wstr wstr) -503 stdcall -arch=x86_64 -noname ualstrlenW(wstr) -504 stdcall -arch=x86_64 -noname ualstrcpyW(wstr wstr) - -555 stdcall -arch=x86_64 AssocGetPerceivedType(wstr ptr ptr ptr) -567 stdcall -arch=x86_64 AssocIsDangerous(wstr) -569 stdcall -arch=x86_64 AssocQueryKeyW(long long wstr wstr ptr) -570 stdcall -arch=x86_64 AssocQueryStringA(long long str str ptr ptr) -571 stdcall -arch=x86_64 AssocQueryStringByKeyA(long long ptr str ptr ptr) -572 stdcall -arch=x86_64 AssocQueryStringByKeyW(long long ptr wstr ptr ptr) -573 stdcall -arch=x86_64 AssocQueryStringW(long long wstr wstr ptr ptr) -574 stdcall -arch=x86_64 ChrCmpIA(long long) -575 stdcall -arch=x86_64 ChrCmpIW(long long) -576 stdcall -arch=x86_64 ColorAdjustLuma(long long long) -577 stdcall -arch=x86_64 ColorHLSToRGB(long long long) -578 stdcall -arch=x86_64 ColorRGBToHLS(long ptr ptr ptr) -#579 stdcall -arch=x86_64 -private DllGetVersion(ptr) -580 stdcall -arch=x86_64 GetMenuPosFromID(ptr long) -581 stdcall -arch=x86_64 HashData(ptr long ptr long) -582 stdcall -arch=x86_64 IntlStrEqWorkerA(long str str long) StrIsIntlEqualA -583 stdcall -arch=x86_64 IntlStrEqWorkerW(long wstr wstr long) StrIsIntlEqualW -584 stdcall -arch=x86_64 IsCharSpaceA(long) -585 stdcall -arch=x86_64 PathAddBackslashA(str) -586 stdcall -arch=x86_64 PathAddBackslashW(wstr) -587 stdcall -arch=x86_64 PathAddExtensionA(str str) -588 stdcall -arch=x86_64 PathAddExtensionW(wstr wstr) -589 stdcall -arch=x86_64 PathAppendA(str str) -590 stdcall -arch=x86_64 PathAppendW(wstr wstr) -591 stdcall -arch=x86_64 PathBuildRootA(ptr long) -592 stdcall -arch=x86_64 PathBuildRootW(ptr long) -593 stdcall -arch=x86_64 PathCanonicalizeA(ptr str) -594 stdcall -arch=x86_64 PathCanonicalizeW(ptr wstr) -595 stdcall -arch=x86_64 PathCombineA(ptr str str) -596 stdcall -arch=x86_64 PathCombineW(ptr wstr wstr) -597 stdcall -arch=x86_64 PathCommonPrefixA(str str ptr) -598 stdcall -arch=x86_64 PathCommonPrefixW(wstr wstr ptr) -599 stdcall -arch=x86_64 PathCompactPathA(long str long) -600 stdcall -arch=x86_64 PathCompactPathExA(ptr str long long) -601 stdcall -arch=x86_64 PathCompactPathExW(ptr wstr long long) -602 stdcall -arch=x86_64 PathCompactPathW(long wstr long) -603 stdcall -arch=x86_64 PathCreateFromUrlA(str ptr ptr long) -604 stdcall -arch=x86_64 PathCreateFromUrlW(wstr ptr ptr long) -605 stdcall -arch=x86_64 PathFileExistsA(str) -606 stdcall -arch=x86_64 PathFileExistsW(wstr) -607 stdcall -arch=x86_64 PathFindExtensionA(str) -608 stdcall -arch=x86_64 PathFindExtensionW(wstr) -609 stdcall -arch=x86_64 PathFindFileNameA(str) -610 stdcall -arch=x86_64 PathFindFileNameW(wstr) -611 stdcall -arch=x86_64 PathFindNextComponentA(str) -612 stdcall -arch=x86_64 PathFindNextComponentW(wstr) -613 stdcall -arch=x86_64 PathFindOnPathA(str ptr) -614 stdcall -arch=x86_64 PathFindOnPathW(wstr ptr) -615 stdcall -arch=x86_64 PathFindSuffixArrayA(str ptr long) -616 stdcall -arch=x86_64 PathFindSuffixArrayW(wstr ptr long) -617 stdcall -arch=x86_64 PathGetArgsA(str) -619 stdcall -arch=x86_64 PathGetCharTypeA(long) -620 stdcall -arch=x86_64 PathGetCharTypeW(long) -621 stdcall -arch=x86_64 PathGetDriveNumberA(str) -622 stdcall -arch=x86_64 PathGetDriveNumberW(wstr) -623 stdcall -arch=x86_64 PathIsContentTypeA(str str) -624 stdcall -arch=x86_64 PathIsContentTypeW(wstr wstr) -625 stdcall -arch=x86_64 PathIsDirectoryA(str) -626 stdcall -arch=x86_64 PathIsDirectoryEmptyA(str) -627 stdcall -arch=x86_64 PathIsDirectoryEmptyW(wstr) -629 stdcall -arch=x86_64 PathIsFileSpecA(str) -630 stdcall -arch=x86_64 PathIsFileSpecW(wstr) -631 stdcall -arch=x86_64 PathIsLFNFileSpecA(str) -632 stdcall -arch=x86_64 PathIsLFNFileSpecW(wstr) -634 stdcall -arch=x86_64 PathIsNetworkPathW(wstr) -635 stdcall -arch=x86_64 PathIsPrefixA(str str) -636 stdcall -arch=x86_64 PathIsPrefixW(wstr wstr) -637 stdcall -arch=x86_64 PathIsRelativeA(str) -638 stdcall -arch=x86_64 PathIsRelativeW(wstr) -639 stdcall -arch=x86_64 PathIsRootA(str) -640 stdcall -arch=x86_64 PathIsRootW(wstr) -641 stdcall -arch=x86_64 PathIsSameRootA(str str) -642 stdcall -arch=x86_64 PathIsSameRootW(wstr wstr) -643 stdcall -arch=x86_64 PathIsSystemFolderA(str long) -644 stdcall -arch=x86_64 PathIsSystemFolderW(wstr long) -645 stdcall -arch=x86_64 PathIsUNCA(str) -646 stdcall -arch=x86_64 PathIsUNCServerA(str) -647 stdcall -arch=x86_64 PathIsUNCServerShareA(str) -648 stdcall -arch=x86_64 PathIsUNCServerShareW(wstr) -649 stdcall -arch=x86_64 PathIsUNCServerW(wstr) -650 stdcall -arch=x86_64 PathIsUNCW(wstr) -651 stdcall -arch=x86_64 PathIsURLA(str) -652 stdcall -arch=x86_64 PathIsURLW(wstr) -653 stdcall -arch=x86_64 PathMakePrettyA(str) -654 stdcall -arch=x86_64 PathMakePrettyW(wstr) -655 stdcall -arch=x86_64 PathMakeSystemFolderA(str) -656 stdcall -arch=x86_64 PathMakeSystemFolderW(wstr) -657 stdcall -arch=x86_64 PathMatchSpecA(str str) -658 stdcall -arch=x86_64 PathMatchSpecW(wstr wstr) -659 stdcall -arch=x86_64 PathParseIconLocationA(str) -660 stdcall -arch=x86_64 PathParseIconLocationW(wstr) -661 stdcall -arch=x86_64 PathQuoteSpacesA(str) -662 stdcall -arch=x86_64 PathQuoteSpacesW(wstr) -663 stdcall -arch=x86_64 PathRelativePathToA(ptr str long str long) -664 stdcall -arch=x86_64 PathRelativePathToW(ptr wstr long wstr long) -665 stdcall -arch=x86_64 PathRemoveArgsA(str) -666 stdcall -arch=x86_64 PathRemoveArgsW(wstr) -667 stdcall -arch=x86_64 PathRemoveBackslashA(str) -668 stdcall -arch=x86_64 PathRemoveBackslashW(wstr) -669 stdcall -arch=x86_64 PathRemoveBlanksA(str) -670 stdcall -arch=x86_64 PathRemoveBlanksW(wstr) -671 stdcall -arch=x86_64 PathRemoveExtensionA(str) -672 stdcall -arch=x86_64 PathRemoveExtensionW(wstr) -673 stdcall -arch=x86_64 PathRemoveFileSpecA(str) -674 stdcall -arch=x86_64 PathRemoveFileSpecW(wstr) -675 stdcall -arch=x86_64 PathRenameExtensionA(str str) -676 stdcall -arch=x86_64 PathRenameExtensionW(wstr wstr) -677 stdcall -arch=x86_64 PathSearchAndQualifyA(str ptr long) -678 stdcall -arch=x86_64 PathSearchAndQualifyW(wstr ptr long) -679 stdcall -arch=x86_64 PathSetDlgItemPathA(long long ptr) -680 stdcall -arch=x86_64 PathSetDlgItemPathW(long long ptr) -681 stdcall -arch=x86_64 PathSkipRootA(str) -682 stdcall -arch=x86_64 PathSkipRootW(wstr) -683 stdcall -arch=x86_64 PathStripPathA(str) -684 stdcall -arch=x86_64 PathStripPathW(wstr) -685 stdcall -arch=x86_64 PathStripToRootA(str) -686 stdcall -arch=x86_64 PathStripToRootW(wstr) -687 stdcall -arch=x86_64 PathUnExpandEnvStringsA(str ptr long) -688 stdcall -arch=x86_64 PathUnExpandEnvStringsW(wstr ptr long) -689 stdcall -arch=x86_64 PathUndecorateA(str) -690 stdcall -arch=x86_64 PathUndecorateW(wstr) -691 stdcall -arch=x86_64 PathUnmakeSystemFolderA(str) -692 stdcall -arch=x86_64 PathUnmakeSystemFolderW(wstr) -693 stdcall -arch=x86_64 PathUnquoteSpacesA(str) -694 stdcall -arch=x86_64 PathUnquoteSpacesW(wstr) -695 stdcall -arch=x86_64 SHAutoComplete(ptr long) -696 stdcall -arch=x86_64 SHCopyKeyA(long str long long) -697 stdcall -arch=x86_64 SHCopyKeyW(long wstr long long) -698 stdcall -arch=x86_64 SHCreateShellPalette(long) -699 stdcall -arch=x86_64 SHCreateStreamOnFileA(str long ptr) -700 stdcall -arch=x86_64 SHCreateStreamOnFileEx(wstr long long long ptr ptr) -701 stdcall -arch=x86_64 SHCreateStreamOnFileW(wstr long ptr) -702 stdcall -arch=x86_64 SHCreateStreamWrapper(ptr ptr long ptr) -703 stdcall -arch=x86_64 SHCreateThreadRef(ptr ptr) -704 stdcall -arch=x86_64 SHDeleteEmptyKeyA(long ptr) -705 stdcall -arch=x86_64 SHDeleteEmptyKeyW(long ptr) -706 stdcall -arch=x86_64 SHDeleteKeyA(long str) -707 stdcall -arch=x86_64 SHDeleteKeyW(long wstr) -708 stdcall -arch=x86_64 SHDeleteOrphanKeyA(long str) -709 stdcall -arch=x86_64 SHDeleteOrphanKeyW(long wstr) -710 stdcall -arch=x86_64 SHDeleteValueA(long str str) -711 stdcall -arch=x86_64 SHDeleteValueW(long wstr wstr) -712 stdcall -arch=x86_64 SHEnumKeyExA(long long str ptr) -713 stdcall -arch=x86_64 SHEnumKeyExW(long long wstr ptr) -714 stdcall -arch=x86_64 SHEnumValueA(long long str ptr ptr ptr ptr) -715 stdcall -arch=x86_64 SHEnumValueW(long long wstr ptr ptr ptr ptr) -716 stdcall -arch=x86_64 SHGetInverseCMAP(ptr long) -717 stdcall -arch=x86_64 SHGetThreadRef(ptr) -718 stdcall -arch=x86_64 SHGetValueA(long str str ptr ptr ptr) -719 stdcall -arch=x86_64 SHGetValueW(long wstr wstr ptr ptr ptr) -720 stdcall -arch=x86_64 SHIsLowMemoryMachine(long) -721 stdcall -arch=x86_64 SHOpenRegStream2A(long str str long) -722 stdcall -arch=x86_64 SHOpenRegStream2W(long wstr wstr long) -723 stdcall -arch=x86_64 SHOpenRegStreamA(long str str long) -724 stdcall -arch=x86_64 SHOpenRegStreamW(long wstr wstr long) -725 stdcall -arch=x86_64 SHQueryInfoKeyA(long ptr ptr ptr ptr) -726 stdcall -arch=x86_64 SHQueryInfoKeyW(long ptr ptr ptr ptr) -727 stdcall -arch=x86_64 SHQueryValueExA(long str ptr ptr ptr ptr) -728 stdcall -arch=x86_64 SHQueryValueExW(long wstr ptr ptr ptr ptr) -729 stdcall -arch=x86_64 SHRegCloseUSKey(ptr) -730 stdcall -arch=x86_64 SHRegCreateUSKeyA(str long long ptr long) -731 stdcall -arch=x86_64 SHRegCreateUSKeyW(wstr long long ptr long) -732 stdcall -arch=x86_64 SHRegDeleteEmptyUSKeyA(long str long) -733 stdcall -arch=x86_64 SHRegDeleteEmptyUSKeyW(long wstr long) -734 stdcall -arch=x86_64 SHRegDeleteUSValueA(long str long) -735 stdcall -arch=x86_64 SHRegDeleteUSValueW(long wstr long) -736 stdcall -arch=x86_64 SHRegDuplicateHKey(long) -737 stdcall -arch=x86_64 SHRegEnumUSKeyA(long long str ptr long) -738 stdcall -arch=x86_64 SHRegEnumUSKeyW(long long wstr ptr long) -739 stdcall -arch=x86_64 SHRegEnumUSValueA(long long ptr ptr ptr ptr ptr long) -740 stdcall -arch=x86_64 SHRegEnumUSValueW(long long ptr ptr ptr ptr ptr long) -741 stdcall -arch=x86_64 SHRegGetBoolUSValueA(str str long long) -742 stdcall -arch=x86_64 SHRegGetBoolUSValueW(wstr wstr long long) -743 stdcall -arch=x86_64 SHRegGetPathA(long str str ptr long) -744 stdcall -arch=x86_64 SHRegGetPathW(long wstr wstr ptr long) -745 stdcall -arch=x86_64 SHRegGetUSValueA(str str ptr ptr ptr long ptr long) -746 stdcall -arch=x86_64 SHRegGetUSValueW(wstr wstr ptr ptr ptr long ptr long) -747 stdcall -arch=x86_64 SHRegGetValueA(long str str long ptr ptr ptr) advapi32.RegGetValueA -748 stdcall -arch=x86_64 SHRegGetValueW(long wstr wstr long ptr ptr ptr) advapi32.RegGetValueW -749 stdcall -arch=x86_64 SHRegOpenUSKeyA(str long long long long) -750 stdcall -arch=x86_64 SHRegOpenUSKeyW(wstr long long long long) -751 stdcall -arch=x86_64 SHRegQueryInfoUSKeyA(long ptr ptr ptr ptr long) -752 stdcall -arch=x86_64 SHRegQueryInfoUSKeyW(long ptr ptr ptr ptr long) -753 stdcall -arch=x86_64 SHRegQueryUSValueA(long str ptr ptr ptr long ptr long) -754 stdcall -arch=x86_64 SHRegQueryUSValueW(long wstr ptr ptr ptr long ptr long) -755 stdcall -arch=x86_64 SHRegSetPathA(long str str str long) -756 stdcall -arch=x86_64 SHRegSetPathW(long wstr wstr wstr long) -757 stdcall -arch=x86_64 SHRegSetUSValueA(str str long ptr long long) -758 stdcall -arch=x86_64 SHRegSetUSValueW(wstr wstr long ptr long long) -759 stdcall -arch=x86_64 SHRegWriteUSValueA(long str long ptr long long) -760 stdcall -arch=x86_64 SHRegWriteUSValueW(long wstr long ptr long long) -761 stdcall -arch=x86_64 SHRegisterValidateTemplate(wstr long) -762 stdcall -arch=x86_64 SHReleaseThreadRef() -763 stdcall -arch=x86_64 SHSetThreadRef(ptr) -764 stdcall -arch=x86_64 SHSetValueA(long str str long ptr long) -765 stdcall -arch=x86_64 SHSetValueW(long wstr wstr long ptr long) -766 stdcall -arch=x86_64 SHSkipJunction(ptr ptr) -767 stdcall -arch=x86_64 SHStrDupA(str ptr) -768 stdcall -arch=x86_64 SHStrDupW(wstr ptr) -769 stdcall -arch=x86_64 StrCSpnA(str str) -770 stdcall -arch=x86_64 StrCSpnIA(str str) -771 stdcall -arch=x86_64 StrCSpnIW(wstr wstr) -772 stdcall -arch=x86_64 StrCSpnW(wstr wstr) -773 stdcall -arch=x86_64 StrCatBuffA(str str long) -774 stdcall -arch=x86_64 StrCatBuffW(wstr wstr long) -775 stdcall -arch=x86_64 StrCatChainW(wstr long long wstr) -776 stdcall -arch=x86_64 StrCatW(ptr wstr) -777 stdcall -arch=x86_64 StrChrA(str long) -778 stdcall -arch=x86_64 StrChrIA(str long) -779 stdcall -arch=x86_64 StrChrIW(wstr long) -780 stdcall -arch=x86_64 StrChrNIW(wstr wstr long) -781 stdcall -arch=x86_64 StrChrNW(wstr long long) -782 stdcall -arch=x86_64 StrChrW(wstr long) -783 stdcall -arch=x86_64 StrCmpIW(wstr wstr) -784 stdcall -arch=x86_64 StrCmpLogicalW(wstr wstr) -785 stdcall -arch=x86_64 StrCmpNA(str str long) -786 stdcall -arch=x86_64 StrCmpNIA(str str long) -787 stdcall -arch=x86_64 StrCmpNIW(wstr wstr long) -788 stdcall -arch=x86_64 StrCmpNW(wstr wstr long) -789 stdcall -arch=x86_64 StrCmpW(wstr wstr) -790 stdcall -arch=x86_64 StrCpyNW(ptr wstr long) -791 stdcall -arch=x86_64 StrCpyW(ptr wstr) -792 stdcall -arch=x86_64 StrDupA(str) -793 stdcall -arch=x86_64 StrDupW(wstr) -794 stdcall -arch=x86_64 StrFormatByteSize64A(int64 ptr long) -795 stdcall -arch=x86_64 StrFormatByteSizeA(long ptr long) -796 stdcall -arch=x86_64 StrFormatByteSizeW(int64 ptr long) -797 stdcall -arch=x86_64 StrFormatKBSizeA(int64 str long) -798 stdcall -arch=x86_64 StrFormatKBSizeW(int64 wstr long) -799 stdcall -arch=x86_64 StrFromTimeIntervalA(ptr long long long) -800 stdcall -arch=x86_64 StrFromTimeIntervalW(ptr long long long) -801 stdcall -arch=x86_64 StrIsIntlEqualA(long str str long) -802 stdcall -arch=x86_64 StrIsIntlEqualW(long wstr wstr long) -803 stdcall -arch=x86_64 StrNCatA(str str long) -804 stdcall -arch=x86_64 StrNCatW(wstr wstr long) -805 stdcall -arch=x86_64 StrPBrkA(str str) -806 stdcall -arch=x86_64 StrPBrkW(wstr wstr) -807 stdcall -arch=x86_64 StrRChrA(str str long) -808 stdcall -arch=x86_64 StrRChrIA(str str long) -809 stdcall -arch=x86_64 StrRChrIW(wstr wstr long) -810 stdcall -arch=x86_64 StrRChrW(wstr wstr long) -811 stdcall -arch=x86_64 StrRStrIA(str str str) -812 stdcall -arch=x86_64 StrRStrIW(wstr wstr wstr) -813 stdcall -arch=x86_64 StrRetToBSTR(ptr ptr ptr) -814 stdcall -arch=x86_64 StrRetToBufA(ptr ptr ptr long) -815 stdcall -arch=x86_64 StrRetToBufW(ptr ptr ptr long) -816 stdcall -arch=x86_64 StrRetToStrA(ptr ptr ptr) -817 stdcall -arch=x86_64 StrRetToStrW(ptr ptr ptr) -818 stdcall -arch=x86_64 StrSpnA(str str) -819 stdcall -arch=x86_64 StrSpnW(wstr wstr) -820 stdcall -arch=x86_64 StrStrA(str str) -821 stdcall -arch=x86_64 StrStrIA(str str) -822 stdcall -arch=x86_64 StrStrIW(wstr wstr) -823 stdcall -arch=x86_64 StrStrNIW(wstr wstr long) -824 stdcall -arch=x86_64 StrStrNW(wstr wstr long) -825 stdcall -arch=x86_64 StrStrW(wstr wstr) -826 stdcall -arch=x86_64 StrToInt64ExA(str long ptr) -827 stdcall -arch=x86_64 StrToInt64ExW(wstr long ptr) -828 stdcall -arch=x86_64 StrToIntA(str) -829 stdcall -arch=x86_64 StrToIntExA(str long ptr) -830 stdcall -arch=x86_64 StrToIntExW(wstr long ptr) -831 stdcall -arch=x86_64 StrToIntW(wstr) -832 stdcall -arch=x86_64 StrTrimA(str str) -833 stdcall -arch=x86_64 StrTrimW(wstr wstr) -834 stdcall -arch=x86_64 UrlApplySchemeA(str ptr ptr long) -835 stdcall -arch=x86_64 UrlApplySchemeW(wstr ptr ptr long) -836 stdcall -arch=x86_64 UrlCanonicalizeA(str ptr ptr long) -837 stdcall -arch=x86_64 UrlCanonicalizeW(wstr ptr ptr long) -838 stdcall -arch=x86_64 UrlCombineA(str str ptr ptr long) -839 stdcall -arch=x86_64 UrlCombineW(wstr wstr ptr ptr long) -840 stdcall -arch=x86_64 UrlCompareA(str str long) -841 stdcall -arch=x86_64 UrlCompareW(wstr wstr long) -842 stdcall -arch=x86_64 UrlCreateFromPathA(str ptr ptr long) -843 stdcall -arch=x86_64 UrlCreateFromPathW(wstr ptr ptr long) -844 stdcall -arch=x86_64 UrlEscapeA(str ptr ptr long) -845 stdcall -arch=x86_64 UrlEscapeW(wstr ptr ptr long) -846 stdcall -arch=x86_64 UrlGetLocationA(str) -847 stdcall -arch=x86_64 UrlGetLocationW(wstr) -848 stdcall -arch=x86_64 UrlGetPartA(str ptr ptr long long) -849 stdcall -arch=x86_64 UrlGetPartW(wstr ptr ptr long long) -850 stdcall -arch=x86_64 UrlHashA(str ptr long) -851 stdcall -arch=x86_64 UrlHashW(wstr ptr long) -852 stdcall -arch=x86_64 UrlIsA(str long) -853 stdcall -arch=x86_64 UrlIsNoHistoryA(str) -854 stdcall -arch=x86_64 UrlIsNoHistoryW(wstr) -855 stdcall -arch=x86_64 UrlIsOpaqueA(str) -856 stdcall -arch=x86_64 UrlIsOpaqueW(wstr) -857 stdcall -arch=x86_64 UrlIsW(wstr long) -858 stdcall -arch=x86_64 UrlUnescapeA(str ptr ptr long) -859 stdcall -arch=x86_64 UrlUnescapeW(wstr ptr ptr long) -860 varargs -arch=x86_64 wnsprintfA(ptr long str) -861 varargs -arch=x86_64 wnsprintfW(ptr long wstr) -862 stdcall -arch=x86_64 wvnsprintfA(ptr long str ptr) -863 stdcall -arch=x86_64 wvnsprintfW(ptr long wstr ptr) - -#Missing WinXP SP1 -742 stdcall -i386 SHRegGetValueA(long str str long ptr ptr ptr) advapi32.RegGetValueA -743 stdcall -i386 SHRegGetValueW(long wstr wstr long ptr ptr ptr) advapi32.RegGetValueW - -#Windows Vista Functions -@ stdcall PathMatchSpecExA(str str long) -@ stdcall PathMatchSpecExW(wstr wstr long) -@ stdcall PathCreateFromUrlAlloc(wstr wstr long) -@ stdcall StrFormatByteSizeEx(long long long wstr long) -;@ stdcall SHAutoCompGetPidl(ptr ptr long ptr) ;cause error on VirtulBox Machine on x64. Is from Longhorn? - -@ varargs ShellMessageBoxA(long long str str long) shell32.ShellMessageBoxA -@ varargs ShellMessageBoxW(long long wstr wstr long) shell32.ShellMessageBoxW - -#Vista functions with special ordinal -568 stdcall IStream_Copy(ptr ptr long) -618 stdcall SHWindowsPolicy(ptr) ;Change 618 ordinal from PathIsContentTypeA to SHWindowsPolicy to satisfy Windows 7 wordpad -628 stdcall SHCreateStreamOnModuleResourceW(ptr ptr wstr ptr) ;Change 628 ordinal from PathIsNetworkPathA to SHCreateStreamOnModuleResourceW to satisfy Windows 7 wordpad -@ stdcall -i386 AssocQueryStringW(long long wstr wstr ptr ptr) ;Change from ordinal 568 to standard export -@ stdcall PathIsNetworkPathA(str) ;Change from ordinal 628 (x86) to standard export -@ stdcall -i386 PathIsContentTypeA(str str) ;Change from ordinal 618 (x86) to standard export -@ stdcall -arch=x86_64 AssocQueryKeyA(long long str str ptr) ;Change from ordinal 568 (x64) to standard export -@ stdcall -arch=x86_64 PathGetArgsW(wstr) ;Change from ordinal 618 (x64) to standard export -@ stdcall -arch=x86_64 PathIsDirectoryW(wstr) ;Change from ordinal 628 (x64) to standard export \ No newline at end of file diff --git a/wrappers/extensions/shlwext/string.c b/wrappers/extensions/shlwext/string.c deleted file mode 100644 index 7d01a45e13..0000000000 --- a/wrappers/extensions/shlwext/string.c +++ /dev/null @@ -1,27 +0,0 @@ -/*++ - -Copyright (c) 2024 Shorthorn Project - -Module Name: - - string.c - -Abstract: - - This module implements Win32 Shell String Functions - -Author: - - Skulltrail 10-September-2024 - -Revision History: - ---*/ - -#include "main.h" - -BOOL WINAPI IsCharSpaceA(CHAR c) -{ - WORD CharType; - return GetStringTypeA(GetSystemDefaultLCID(), CT_CTYPE1, &c, 1, &CharType) && (CharType & C1_SPACE); -} \ No newline at end of file diff --git a/wrappers/extensions/shlwext/thread.c b/wrappers/extensions/shlwext/thread.c deleted file mode 100644 index c21f7ec7b3..0000000000 --- a/wrappers/extensions/shlwext/thread.c +++ /dev/null @@ -1,129 +0,0 @@ -/*++ - -Copyright (c) 2024 Shorthorn Project - -Module Name: - - thread.c - -Abstract: - - This module implements Win32 Shell String Functions - -Author: - - Skulltrail 10-September-2024 - -Revision History: - ---*/ - -#include "main.h" -#include - -WINE_DEFAULT_DEBUG_CHANNEL(shlwapi); - -/* Internal thread information structure */ -typedef struct tagSHLWAPI_THREAD_INFO -{ - LPTHREAD_START_ROUTINE pfnThreadProc; /* Thread start */ - LPTHREAD_START_ROUTINE pfnCallback; /* Thread initialisation */ - PVOID pData; /* Application specific data */ - BOOL bInitCom; /* Initialise COM for the thread? */ - HANDLE hEvent; /* Signal for creator to continue */ - IUnknown *refThread; /* Reference to thread creator */ - IUnknown *refIE; /* Reference to the IE process */ -} SHLWAPI_THREAD_INFO, *LPSHLWAPI_THREAD_INFO; - -typedef struct -{ - IUnknown IUnknown_iface; - LONG *ref; -} threadref; - -static inline threadref *impl_from_IUnknown(IUnknown *iface) -{ - return CONTAINING_RECORD(iface, threadref, IUnknown_iface); -} - -static HRESULT WINAPI threadref_QueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj) -{ - threadref * This = impl_from_IUnknown(iface); - - TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObj); - - if (ppvObj == NULL) - return E_POINTER; - - if (IsEqualGUID(&IID_IUnknown, riid)) { - TRACE("(%p)->(IID_IUnknown %p)\n", This, ppvObj); - *ppvObj = This; - IUnknown_AddRef((IUnknown*)*ppvObj); - return S_OK; - } - - *ppvObj = NULL; - FIXME("(%p, %s, %p) interface not supported\n", This, debugstr_guid(riid), ppvObj); - return E_NOINTERFACE; -} - -static ULONG WINAPI threadref_AddRef(IUnknown *iface) -{ - threadref * This = impl_from_IUnknown(iface); - - TRACE("(%p)\n", This); - return InterlockedIncrement(This->ref); -} - -static ULONG WINAPI threadref_Release(IUnknown *iface) -{ - LONG refcount; - threadref * This = impl_from_IUnknown(iface); - - TRACE("(%p)\n", This); - - refcount = InterlockedDecrement(This->ref); - if (!refcount) - HeapFree(GetProcessHeap(), 0, This); - - return refcount; -} - -/* VTable */ -static const IUnknownVtbl threadref_vt = -{ - threadref_QueryInterface, - threadref_AddRef, - threadref_Release, -}; - -/************************************************************************* - * SHCreateThreadRef [SHLWAPI.@] - * - * Create a per-thread IUnknown object - * - * PARAMS - * lprefcount [I] Pointer to a LONG to be used as refcount - * lppUnknown [O] Destination to receive the created object reference - * - * RETURNS - * Success: S_OK. lppUnknown is set to the object reference. - * Failure: E_INVALIDARG, if a parameter is NULL - */ -HRESULT WINAPI SHCreateThreadRef(LONG *lprefcount, IUnknown **lppUnknown) -{ - threadref * This; - TRACE("(%p, %p)\n", lprefcount, lppUnknown); - - if (!lprefcount || !lppUnknown) - return E_INVALIDARG; - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(threadref)); - This->IUnknown_iface.lpVtbl = &threadref_vt; - This->ref = lprefcount; - - *lprefcount = 1; - *lppUnknown = &This->IUnknown_iface; - TRACE("=> returning S_OK with %p\n", This); - return S_OK; -} \ No newline at end of file diff --git a/wrappers/extensions/shlwext/version.rc b/wrappers/extensions/shlwext/version.rc deleted file mode 100644 index 90ed56915f..0000000000 --- a/wrappers/extensions/shlwext/version.rc +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2009 Henri Verbeet for CodeWeavers - * - * 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 - */ - -#define WINE_FILEDESCRIPTION_STR "Shell Light-weight Utility Library Wrapper for One-Core-API" -#define WINE_FILENAME_STR "shlwapi.dll" - -#include "common_wrappers_ver.rc" diff --git a/wrappers/extensions/userenvext/main.c b/wrappers/extensions/userenvext/main.c index b1571a69be..d4adfac6f2 100644 --- a/wrappers/extensions/userenvext/main.c +++ b/wrappers/extensions/userenvext/main.c @@ -1,28 +1,22 @@ -/* - * ReactOS kernel - * Copyright (C) 2004 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * FILE: dll/win32/userenv/userenv.c - * PURPOSE: DLL initialization code - * PROGRAMMER: Eric Kohl - */ +/*++ + +Copyright (c) 2024 Shorthorn Project + +Module Name: + + main.c + +Abstract: + + Implement Windows 8 functions for Userenv + +Author: + + Skulltrail 16-November-2024 + +Revision History: + +--*/ #include "precomp.h" @@ -45,97 +39,97 @@ DllMain(HINSTANCE hinstDLL, return TRUE; } - HRESULT - WINAPI - CreateAppContainerProfile( - _In_ PCWSTR _szAppContainerName, - _In_ PCWSTR _szDisplayName, - _In_ PCWSTR _szDescription, - _In_reads_opt_(_uCapabilityCount) PSID_AND_ATTRIBUTES _pCapabilities, - _In_ DWORD _uCapabilityCount, - _Outptr_ PSID* _ppSidAppContainerSid - ) - { +HRESULT +WINAPI +CreateAppContainerProfile( + _In_ PCWSTR _szAppContainerName, + _In_ PCWSTR _szDisplayName, + _In_ PCWSTR _szDescription, + _In_reads_opt_(_uCapabilityCount) PSID_AND_ATTRIBUTES _pCapabilities, + _In_ DWORD _uCapabilityCount, + _Outptr_ PSID* _ppSidAppContainerSid +) +{ // if (const auto _pfnCreateAppContainerProfile = try_get_CreateAppContainerProfile()) // { // return _pfnCreateAppContainerProfile(_szAppContainerName, _szDisplayName, _szDescription, _pCapabilities, _uCapabilityCount, _ppSidAppContainerSid); // } - if (!_ppSidAppContainerSid) - return E_INVALIDARG; - *_ppSidAppContainerSid = NULL; - return E_NOTIMPL; - } - - // 最低受支持的客户端 Windows 8 [仅限桌面应用] - // 最低受支持的服务器 Windows Server 2012[仅限桌面应用] - HRESULT - WINAPI - DeleteAppContainerProfile( - _In_ PCWSTR _szAppContainerName - ) - { - // if (const auto _pfnDeleteAppContainerProfile = try_get_DeleteAppContainerProfile()) - // { - // return _pfnDeleteAppContainerProfile(_szAppContainerName); - // } + if (!_ppSidAppContainerSid) + return E_INVALIDARG; + *_ppSidAppContainerSid = NULL; + return S_OK; +} - return E_NOTIMPL; - } - - // 最低受支持的客户端 Windows 8 [仅限桌面应用] - // 最低受支持的服务器 Windows Server 2012[仅限桌面应用] - HRESULT - WINAPI - DeriveAppContainerSidFromAppContainerName( - _In_ PCWSTR _szAppContainerName, - _Outptr_ PSID* _ppsidAppContainerSid - ) - { - // if (const auto _pfnDeriveAppContainerSidFromAppContainerName = try_get_DeriveAppContainerSidFromAppContainerName()) - // { - // return _pfnDeriveAppContainerSidFromAppContainerName(_szAppContainerName, _ppsidAppContainerSid); - // } - if (!_ppsidAppContainerSid) - return E_INVALIDARG; - *_ppsidAppContainerSid = NULL; - return E_NOTIMPL; - } - - // 最低受支持的客户端 Windows 8 [仅限桌面应用] - // 最低受支持的服务器 Windows Server 2012[仅限桌面应用] - HRESULT - WINAPI - GetAppContainerFolderPath( - _In_ PCWSTR _szAppContainerSid, - _Outptr_ PWSTR* _ppszPath - ) - { - // if (const auto _pfnGetAppContainerFolderPath = try_get_GetAppContainerFolderPath()) - // { - // return _pfnGetAppContainerFolderPath(_szAppContainerSid, _ppszPath); - // } - if (!_ppszPath) - return E_INVALIDARG; - *_ppszPath = NULL; - return E_NOTIMPL; - } - - // 最低受支持的客户端 Windows 8 [仅限桌面应用] - // 最低受支持的服务器 Windows Server 2012[仅限桌面应用] - HRESULT - WINAPI - GetAppContainerRegistryLocation( - _In_ REGSAM _DesiredAccess, - _Outptr_ PHKEY _phAppContainerKey - ) - { - // if (const auto _pfnGetAppContainerRegistryLocation = try_get_GetAppContainerRegistryLocation()) - // { - // return _pfnGetAppContainerRegistryLocation(_DesiredAccess, _phAppContainerKey); - // } - if (!_phAppContainerKey) - return E_INVALIDARG; - *_phAppContainerKey = NULL; - return E_NOTIMPL; - } \ No newline at end of file +// 最低受支持的客户端 Windows 8 [仅限桌面应用] +// 最低受支持的服务器 Windows Server 2012[仅限桌面应用] +HRESULT +WINAPI +DeleteAppContainerProfile( + _In_ PCWSTR _szAppContainerName +) +{ + // if (const auto _pfnDeleteAppContainerProfile = try_get_DeleteAppContainerProfile()) + // { + // return _pfnDeleteAppContainerProfile(_szAppContainerName); + // } + + return S_OK; +} + +// 最低受支持的客户端 Windows 8 [仅限桌面应用] +// 最低受支持的服务器 Windows Server 2012[仅限桌面应用] +HRESULT +WINAPI +DeriveAppContainerSidFromAppContainerName( + _In_ PCWSTR _szAppContainerName, + _Outptr_ PSID* _ppsidAppContainerSid +) +{ + // if (const auto _pfnDeriveAppContainerSidFromAppContainerName = try_get_DeriveAppContainerSidFromAppContainerName()) + // { + // return _pfnDeriveAppContainerSidFromAppContainerName(_szAppContainerName, _ppsidAppContainerSid); + // } + if (!_ppsidAppContainerSid) + return E_INVALIDARG; + *_ppsidAppContainerSid = NULL; + return S_OK; +} + +// 最低受支持的客户端 Windows 8 [仅限桌面应用] +// 最低受支持的服务器 Windows Server 2012[仅限桌面应用] +HRESULT +WINAPI +GetAppContainerFolderPath( + _In_ PCWSTR _szAppContainerSid, + _Outptr_ PWSTR* _ppszPath +) +{ + // if (const auto _pfnGetAppContainerFolderPath = try_get_GetAppContainerFolderPath()) + // { + // return _pfnGetAppContainerFolderPath(_szAppContainerSid, _ppszPath); + // } + if (!_ppszPath) + return E_INVALIDARG; + *_ppszPath = NULL; + return S_OK; +} + +// 最低受支持的客户端 Windows 8 [仅限桌面应用] +// 最低受支持的服务器 Windows Server 2012[仅限桌面应用] +HRESULT +WINAPI +GetAppContainerRegistryLocation( + _In_ REGSAM _DesiredAccess, + _Outptr_ PHKEY _phAppContainerKey +) +{ + // if (const auto _pfnGetAppContainerRegistryLocation = try_get_GetAppContainerRegistryLocation()) + // { + // return _pfnGetAppContainerRegistryLocation(_DesiredAccess, _phAppContainerKey); + // } + if (!_phAppContainerKey) + return E_INVALIDARG; + *_phAppContainerKey = NULL; + return S_OK; +} \ No newline at end of file diff --git a/wrappers/extensions/uxthext/hooks.c b/wrappers/extensions/uxthext/hooks.c index 4c5e5b3b5f..db9e62c5b4 100644 --- a/wrappers/extensions/uxthext/hooks.c +++ b/wrappers/extensions/uxthext/hooks.c @@ -41,7 +41,9 @@ OpenThemeDataNative( LPCWSTR pszClassList ); -HTHEME WINAPI OpenThemeDataInternal( +HTHEME +WINAPI +OpenThemeDataInternal( HWND hwnd, LPCWSTR pszClassList ) diff --git a/wrappers/extensions/uxthext/main.c b/wrappers/extensions/uxthext/main.c index a0ec67a2a8..0816667ee8 100644 --- a/wrappers/extensions/uxthext/main.c +++ b/wrappers/extensions/uxthext/main.c @@ -38,6 +38,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(uxtheme_wrapper); HANDLE hHeap = 0; +HTHEME +WINAPI +OpenThemeDataInternal( + HWND hwnd, + LPCWSTR pszClassList +); + typedef HANDLE HANIMATIONBUFFER; typedef int (WINAPI *DTT_CALLBACK_PROC)( HDC, LPWSTR, int, LPRECT, UINT, LPARAM ); @@ -127,8 +134,11 @@ HRESULT WINAPI GetThemeTransitionDuration(HTHEME hTheme, int iPartId, int iState { FIXME("(%p, %u, %u, %u, %u, %p) stub\n", hTheme, iPartId, iStateIdFrom, iStateIdTo, iPropId, pdwDuration); - - return E_NOTIMPL; + if (!pdwDuration) + return E_INVALIDARG; + + *pdwDuration = 0; // No theme on Windows XP has transitions. + return S_OK; } //unimplemented @@ -508,4 +518,14 @@ HRESULT WINAPI BufferedPaintStopAllAnimations(HWND hwnd) FIXME("Stub (%p)\n", hwnd); return E_NOTIMPL; +} + +HTHEME WINAPI OpenThemeDataForDpi( + HWND hwnd, + LPCWSTR pszClassList, + UINT dpi +) +{ + return OpenThemeDataInternal(hwnd, + pszClassList); } \ No newline at end of file diff --git a/wrappers/extensions/uxthext/uxthext.spec b/wrappers/extensions/uxthext/uxthext.spec index f3e2d1ddba..c431b4972f 100644 --- a/wrappers/extensions/uxthext/uxthext.spec +++ b/wrappers/extensions/uxthext/uxthext.spec @@ -100,7 +100,7 @@ #Hooks 92 stdcall OpenThemeData(ptr wstr) OpenThemeDataInternal -#From Vista +#Vista Functions @ stdcall BeginBufferedAnimation(ptr ptr ptr long ptr ptr ptr ptr) @ stdcall BeginBufferedPaint(ptr ptr long ptr ptr) @ stdcall BufferedPaintUnInit() @@ -124,7 +124,10 @@ @ stdcall IsCompositionActive() @ stdcall SetWindowThemeAttribute(long long ptr long) -#From Win7 +#Win7 Functions @ stdcall BeginPanningFeedback(ptr) @ stdcall EndPanningFeedback(ptr long) -@ stdcall UpdatePanningFeedback(ptr long long long) \ No newline at end of file +@ stdcall UpdatePanningFeedback(ptr long long long) + +#Win10 Functions +@ stdcall OpenThemeDataForDpi(ptr wstr long) diff --git a/wrappers/extensions/ws2_ex/hooks.c b/wrappers/extensions/ws2_ex/hooks.c index 8e60c45ac5..727cbe667f 100644 --- a/wrappers/extensions/ws2_ex/hooks.c +++ b/wrappers/extensions/ws2_ex/hooks.c @@ -95,4 +95,86 @@ WSAIoctl(IN SOCKET s, /* Return with an Error */ SetLastError(ErrorCode); return SOCKET_ERROR; +} + +// Virtually every single 100% Rust-based application needs this to make any HTTP requests. +// While supported in Vista+, since Windows 8, those four I/O control codes simply return back the original socket, thus considered 'deprecated' +int WSAAPI WSAIoctlInternal( + SOCKET s, + DWORD dwIoControlCode, + LPVOID lpvInBuffer, + DWORD cbInBuffer, + LPVOID lpvOutBuffer, + DWORD cbOutBuffer, + LPDWORD lpcbBytesReturned, + LPWSAOVERLAPPED lpOverlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine +) { + if (dwIoControlCode == SIO_BASE_HANDLE + || dwIoControlCode == SIO_BSP_HANDLE + || dwIoControlCode == SIO_BSP_HANDLE_SELECT + || dwIoControlCode == SIO_BSP_HANDLE_POLL) { + if (lpvOutBuffer == NULL || lpcbBytesReturned == NULL) { + WSASetLastError(WSAEFAULT); + return SOCKET_ERROR; + } + + *(SOCKET*)lpvOutBuffer = s; + *lpcbBytesReturned = sizeof(SOCKET); + return 0; + } + // fall back into original function + return WSAIoctl(s, dwIoControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpOverlapped, lpCompletionRoutine); +} + +SOCKET WSAAPI WSASocketAInternal(int af, int type, int protocol, + LPWSAPROTOCOL_INFOA lpProtocolInfo, + GROUP g, DWORD dwFlags) +{ + SOCKET curSock; + if(dwFlags & WSA_FLAG_NO_HANDLE_INHERIT){ + + dwFlags ^= WSA_FLAG_NO_HANDLE_INHERIT; + curSock = WSASocketA(af, type, protocol, lpProtocolInfo, g, dwFlags); + if (curSock != INVALID_SOCKET) { + SetHandleInformation((HANDLE)curSock, HANDLE_FLAG_INHERIT, 0); + } + DbgPrint("WSASocketWInternal: flag is WSA_FLAG_NO_HANDLE_INHERIT\n"); + return curSock; + } + return WSASocketA(af, type, protocol, lpProtocolInfo, g, dwFlags); +} + +SOCKET WSAAPI WSASocketWInternal(int af, int type, int protocol, + LPWSAPROTOCOL_INFOW lpProtocolInfo, + GROUP g, DWORD dwFlags) +{ + SOCKET curSock; + if(dwFlags & WSA_FLAG_NO_HANDLE_INHERIT){ + + dwFlags ^= WSA_FLAG_NO_HANDLE_INHERIT; + curSock = WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags); + if (curSock != INVALID_SOCKET) { + SetHandleInformation((HANDLE)curSock, HANDLE_FLAG_INHERIT, 0); + } + DbgPrint("WSASocketWInternal: flag is WSA_FLAG_NO_HANDLE_INHERIT\n"); + return curSock; + } + return WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags); +} + +INT +WSAAPI +setsockoptInternal( + IN SOCKET s, + IN INT level, + IN INT optname, + IN CONST CHAR FAR* optval, + IN INT optlen) +{ + if(level == IPPROTO_IPV6 && optname == IPV6_V6ONLY){ + return S_OK; + } + + return setsockopt(s, level, optname, optval, optlen); } \ No newline at end of file diff --git a/wrappers/extensions/ws2_ex/ws2_ex.spec b/wrappers/extensions/ws2_ex/ws2_ex.spec index 3506a7b69b..552ed10a7f 100644 --- a/wrappers/extensions/ws2_ex/ws2_ex.spec +++ b/wrappers/extensions/ws2_ex/ws2_ex.spec @@ -76,7 +76,6 @@ @ stdcall WSAHtons(long long ptr) @ stdcall WSAInstallServiceClassA(ptr) @ stdcall WSAInstallServiceClassW(ptr) -@ stdcall WSAIoctl(long long ptr long ptr long ptr ptr ptr) @ stdcall WSAJoinLeaf(long ptr long ptr ptr ptr ptr long) @ stdcall WSALookupServiceBeginA(ptr long ptr) @ stdcall WSALookupServiceBeginW(ptr long ptr) @@ -134,6 +133,7 @@ @ stdcall setsockopt(long long long ptr long) setsockoptInternal @ stdcall WSASocketA(long long long ptr long long) WSASocketAInternal @ stdcall WSASocketW(long long long ptr long long) WSASocketWInternal +@ stdcall WSAIoctl(long long ptr long ptr long ptr ptr ptr) ;WSAIoctlInternal #Vista functions @ stdcall FreeAddrInfoEx(ptr) diff --git a/wrappers/new-dlls/CMakeLists.txt b/wrappers/new-dlls/CMakeLists.txt index 008dc42c6b..be05ceb04d 100644 --- a/wrappers/new-dlls/CMakeLists.txt +++ b/wrappers/new-dlls/CMakeLists.txt @@ -33,6 +33,7 @@ add_subdirectory(sas) add_subdirectory(secbase) #add_subdirectory(sechost) add_subdirectory(shcore) +add_subdirectory(slc) add_subdirectory(sppc) #add_subdirectory(srvcli) add_subdirectory(sspicli) diff --git a/wrappers/new-dlls/combase/CMakeLists.txt b/wrappers/new-dlls/combase/CMakeLists.txt index c0f006d67a..aa2a21a02c 100644 --- a/wrappers/new-dlls/combase/CMakeLists.txt +++ b/wrappers/new-dlls/combase/CMakeLists.txt @@ -26,12 +26,13 @@ add_rpcproxy_files( list(APPEND SOURCE apartment.c + combase.c main.c mta.c roapi.c string.c #marshal.c - #rpc.c + rpc.c version.rc # ${CMAKE_CURRENT_BINARY_DIR}/dcom_i.c ${CMAKE_CURRENT_BINARY_DIR}/combase_stubs.c diff --git a/wrappers/new-dlls/combase/combase.spec b/wrappers/new-dlls/combase/combase.spec index a75a7163ad..33aa068420 100644 --- a/wrappers/new-dlls/combase/combase.spec +++ b/wrappers/new-dlls/combase/combase.spec @@ -17,8 +17,10 @@ @ stdcall CoCreateGuid(ptr) @ stdcall CoCreateInstance(ptr ptr long ptr ptr) @ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr) +@ stdcall CoCreateInstanceFromApp(ptr ptr long ptr long ptr) @ stdcall CoCreateObjectInContext(ptr ptr ptr ptr) ole32.CoCreateObjectInContext @ stdcall CoDeactivateObject(long long) ole32.CoDeactivateObject +@ stdcall CoDecodeProxy(long int64 ptr) @ stdcall CoDisableCallCancellation(ptr) @ stdcall CoDisconnectObject(ptr long) @ stdcall CoDosDateTimeToFileTime(long long ptr) kernel32.DosDateTimeToFileTime @@ -329,11 +331,6 @@ #win Vista functions @ stdcall CoDisconnectContext(long) -#Comment because link with propsys cause a error on Office 2010 installation -; @ stdcall PropVariantToVariant(ptr ptr) propsys.PropVariantToVariant -; @ stdcall StgDeserializePropVariant(ptr long ptr) propsys.StgDeserializePropVariant -; @ stdcall StgSerializePropVariant(ptr ptr ptr) propsys.StgSerializePropVariant -; @ stdcall VariantToPropVariant(ptr ptr) propsys.VariantToPropVariant #win7 functions @ stdcall CoDecrementMTAUsage(ptr) @@ -435,6 +432,9 @@ @ stdcall HRGN_UserSize(ptr long ptr) ole32.HRGN_UserSize @ stdcall HRGN_UserUnmarshal(ptr ptr ptr) ole32.HRGN_UserUnmarshal +;Win8.1 functions +@ stdcall RoGetAgileReference(long ptr ptr ptr) + #combase specific functions @ stdcall GetRestrictedErrorInfo(ptr) @ stdcall RoInitialize(long) diff --git a/wrappers/new-dlls/combase/main.c b/wrappers/new-dlls/combase/main.c index ea8fd00a58..b84dba5492 100644 --- a/wrappers/new-dlls/combase/main.c +++ b/wrappers/new-dlls/combase/main.c @@ -53,22 +53,6 @@ CoDisconnectContext( return S_OK; } -/*********************************************************************** - * CoGetActivationState (ole32.@) - */ -HRESULT WINAPI CoGetActivationState(GUID guid, DWORD unknown, DWORD *unknown2) -{ - return E_NOTIMPL; -} - -/*********************************************************************** - * CoGetCallState (ole32.@) - */ -HRESULT WINAPI CoGetCallState(int unknown, PULONG unknown2) -{ - return E_NOTIMPL; -} - /*********************************************************************** * InternalTlsAllocData (combase.@) */ diff --git a/wrappers/new-dlls/combase/main.h b/wrappers/new-dlls/combase/main.h index 4c37fb0d2f..aab2f5944f 100644 --- a/wrappers/new-dlls/combase/main.h +++ b/wrappers/new-dlls/combase/main.h @@ -31,6 +31,7 @@ #include "wine/debug.h" #include "wine/exception.h" #include "servprov.h" +#include "combaseapi.h" #define APTTYPEQUALIFIER_APPLICATION_STA 6 #define APTTYPEQUALIFIER_RESERVED_1 7 diff --git a/wrappers/new-dlls/combase/roapi.c b/wrappers/new-dlls/combase/roapi.c index 17e09367cf..b32fc1961d 100644 --- a/wrappers/new-dlls/combase/roapi.c +++ b/wrappers/new-dlls/combase/roapi.c @@ -29,6 +29,23 @@ Revision History: #include "roerrorapi.h" #include "winstring.h" +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "initguid.h" +#include "ocidl.h" +#include "shellscalingapi.h" +#include "shlwapi.h" +#include "unknwn.h" + +#include "wine/debug.h" +#include "wine/heap.h" + #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(combase); @@ -317,3 +334,245 @@ BOOL WINAPI RoOriginateLanguageException(HRESULT error, HSTRING message, IUnknow FIXME("%#lx, %s, %p: stub\n", error, message, language_exception); return TRUE; } + +DEFINE_GUID(IID_IUnknown, 0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); + +static struct list registered_classes = LIST_INIT(registered_classes); + +typedef interface IUnknown IActivationFilter; + +IActivationFilter globalActivationFilter = {0}; + +static CRITICAL_SECTION registered_classes_cs; +static CRITICAL_SECTION_DEBUG registered_classes_cs_debug = +{ + 0, 0, ®istered_classes_cs, + { ®istered_classes_cs_debug.ProcessLocksList, ®istered_classes_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": registered_classes_cs") } +}; +static CRITICAL_SECTION registered_classes_cs = { ®istered_classes_cs_debug, -1, 0, 0, 0, 0 }; + +/* will create if necessary */ +static inline struct oletls *COM_CurrentInfo(void) +{ + if (!NtCurrentTeb()->ReservedForOle) + NtCurrentTeb()->ReservedForOle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct oletls)); + + return NtCurrentTeb()->ReservedForOle; +} + +HRESULT WINAPI CoRegisterActivationFilter(IActivationFilter *pActivationFilter) +{ + IActivationFilter *activationFilter; // rax + + if ( !pActivationFilter ) + return 0x80070057; + activationFilter = (IActivationFilter *)_InterlockedCompareExchange64( + (signed __int64*)&globalActivationFilter, + (signed __int64)pActivationFilter, + 0i64); + if ( !activationFilter || activationFilter == pActivationFilter ) + return 0; + else + return 0x80004021; +} + +typedef interface IAgileReferenceW7 IAgileReferenceW7; + +/***************************************************************************** + * IAgileReference interface + */ +#ifndef __IAgileReference_INTERFACE_DEFINED__ +#define __IAgileReference_INTERFACE_DEFINED__ + +DEFINE_GUID(IID_IAgileReference, 0xc03f6a43, 0x65a4, 0x9818, 0x98,0x7e, 0xe0,0xb8,0x10,0xd2,0xa6,0xf2); +#if defined(__cplusplus) && !defined(CINTERFACE) +MIDL_INTERFACE("c03f6a43-65a4-9818-987e-e0b810d2a6f2") +IAgileReferenceW7 : public IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE Resolve( + REFIID riid, + void **ppv) = 0; + +}; +#ifdef __CRT_UUID_DECL +__CRT_UUID_DECL(IAgileReferenceW7, 0xc03f6a43, 0x65a4, 0x9818, 0x98,0x7e, 0xe0,0xb8,0x10,0xd2,0xa6,0xf2) +#endif +#else +typedef struct IAgileReferenceVtblW7 { + BEGIN_INTERFACE + + /*** IUnknown methods ***/ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IAgileReferenceW7 *This, + REFIID riid, + void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IAgileReferenceW7 *This); + + ULONG (STDMETHODCALLTYPE *Release)( + IAgileReferenceW7 *This); + + /*** IAgileReference methods ***/ + HRESULT (STDMETHODCALLTYPE *Resolve)( + IAgileReferenceW7 *This, + REFIID riid, + void **ppv); + + END_INTERFACE +} IAgileReferenceVtblW7; + +interface IAgileReferenceW7 { + IAgileReferenceVtblW7 lpVtbl; + ULONG cRef; + IUnknown *agileObject; +}; + +#endif +#endif + +STDMETHODIMP IAgileReferenceW7_QueryInterface(IAgileReferenceW7 *lpMyObj, REFIID riid, + LPVOID *lppvObj); + +STDMETHODIMP IAgileReferenceW7_QueryInterface(IAgileReferenceW7 *lpMyObj, REFIID riid, + LPVOID *lppvObj) +{ + if (!lpMyObj) + return HRESULT_FROM_WIN32(E_INVALIDARG); + + if (!riid) + return HRESULT_FROM_WIN32(E_INVALIDARG); + + if (IsEqualIID(riid, &IID_IAgileReference) || + IsEqualIID(riid, &IID_IUnknown) + ) { + InterlockedIncrement(&(lpMyObj->cRef)); + *lppvObj = lpMyObj; + return 0; + } + return HRESULT_FROM_WIN32(E_NOINTERFACE); +} + +STDMETHODIMP_(ULONG) IAgileReferenceW7_AddRef(IAgileReferenceW7 *lpMyObj) +{ + return InterlockedIncrement(&(lpMyObj->cRef)); +} + +STDMETHODIMP_(ULONG) IAgileReferenceW7_Release(IAgileReferenceW7 *lpMyObj) +{ + ULONG NewRef = InterlockedDecrement(&(lpMyObj->cRef)); + if (NewRef == 0) { + IUnknown_Release(lpMyObj->agileObject); + CoTaskMemFree(lpMyObj); + } + return NewRef; +} + +STDMETHODIMP IAgileReferenceW7_Resolve(IAgileReferenceW7 *lpMyObj, + REFIID Ref, + void **ppvObjectReference) +{ + return IUnknown_QueryInterface(lpMyObj->agileObject, Ref, ppvObjectReference); +} + +static IAgileReferenceVtblW7 vTable = { + IAgileReferenceW7_QueryInterface, + IAgileReferenceW7_AddRef, + IAgileReferenceW7_Release, + IAgileReferenceW7_Resolve +}; + +typedef interface INoMarshal INoMarshal; + +#ifndef __INoMarshal_INTERFACE_DEFINED__ +#define __INoMarshal_INTERFACE_DEFINED__ + +DEFINE_GUID(IID_INoMarshal, 0xecc8691b, 0xc1db, 0x4dc0, 0x85,0x5e, 0x65,0xf6,0xc5,0x51,0xaf,0x49); +#if defined(__cplusplus) && !defined(CINTERFACE) +MIDL_INTERFACE("ecc8691b-c1db-4dc0-855e-65f6c551af49") +INoMarshal : public IUnknown +{ +}; +#ifdef __CRT_UUID_DECL +__CRT_UUID_DECL(INoMarshal, 0xecc8691b, 0xc1db, 0x4dc0, 0x85,0x5e, 0x65,0xf6,0xc5,0x51,0xaf,0x49) +#endif +#else +typedef struct INoMarshalVtbl { + BEGIN_INTERFACE + + /*** IUnknown methods ***/ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + INoMarshal* This, + REFIID riid, + void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + INoMarshal* This); + + ULONG (STDMETHODCALLTYPE *Release)( + INoMarshal* This); + + END_INTERFACE +} INoMarshalVtbl; +interface INoMarshal { + CONST_VTBL INoMarshalVtbl* lpVtbl; + +}; + +#endif +#endif + +#ifdef COBJMACROS +#ifndef WIDL_C_INLINE_WRAPPERS +/*** IUnknown methods ***/ +#define INoMarshal_QueryInterface(This,riid,ppvObject) (This)->lpVtbl->QueryInterface(This,riid,ppvObject) +#define INoMarshal_AddRef(This) (This)->lpVtbl->AddRef(This) +#define INoMarshal_Release(This) (This)->lpVtbl->Release(This) +#else +/*** IUnknown methods ***/ +static FORCEINLINE HRESULT INoMarshal_QueryInterface(INoMarshal* This,REFIID riid,void **ppvObject) { + return This->lpVtbl->QueryInterface(This,riid,ppvObject); +} +static FORCEINLINE ULONG INoMarshal_AddRef(INoMarshal* This) { + return This->lpVtbl->AddRef(This); +} +static FORCEINLINE ULONG INoMarshal_Release(INoMarshal* This) { + return This->lpVtbl->Release(This); +} +#endif +#endif + +// The function itself. +HRESULT +WINAPI +RoGetAgileReference( + int options, // Ignored + REFIID riid, // Ignored also + IUnknown *pUnk, + IAgileReferenceW7 **ppAgileReference +) +{ + INoMarshal *INo; + IAgileReferenceW7 *Reference; + if (pUnk == 0) + return E_INVALIDARG; + if (ppAgileReference == 0) + return E_INVALIDARG; + + if (IUnknown_QueryInterface(pUnk, &IID_INoMarshal, &INo)) { + INoMarshal_Release(INo); + return CO_E_NOT_SUPPORTED; + } + // Allocate a memory pointer. + Reference = CoTaskMemAlloc(sizeof(IAgileReferenceW7)); + if (Reference == 0) { + return E_OUTOFMEMORY; + } + Reference->cRef = 1; + Reference->lpVtbl = vTable; + Reference->agileObject = pUnk; + IUnknown_AddRef(pUnk); + *ppAgileReference = Reference; + return 0; +} \ No newline at end of file diff --git a/wrappers/new-dlls/combase/rpc.c b/wrappers/new-dlls/combase/rpc.c index ece1ede229..8ebfba17f8 100644 --- a/wrappers/new-dlls/combase/rpc.c +++ b/wrappers/new-dlls/combase/rpc.c @@ -20,7 +20,10 @@ Revision History: #include "main.h" -WINE_DEFAULT_DEBUG_CHANNEL(ole32); +WINE_DEFAULT_DEBUG_CHANNEL(rpc); + +static struct list registered_classes; +static CRITICAL_SECTION registered_classes_cs; static RPC_BINDING_HANDLE get_rpc_handle(unsigned short *protseq, unsigned short *endpoint) { @@ -114,7 +117,7 @@ static BOOL start_rpcss(void) if (StartServiceW(service, 0, NULL) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) { - ULONGLONG start_time = GetTickCount64(); + ULONGLONG start_time = GetTickCount(); do { DWORD dummy; @@ -126,7 +129,7 @@ static BOOL start_rpcss(void) ret = TRUE; break; } - if (GetTickCount64() - start_time > 30000) break; + if (GetTickCount() - start_time > 30000) break; Sleep( 100 ); } while (status.dwCurrentState == SERVICE_START_PENDING); @@ -145,4 +148,14 @@ static BOOL start_rpcss(void) static LONG WINAPI rpc_filter(EXCEPTION_POINTERS *eptr) { return I_RpcExceptionFilter(eptr->ExceptionRecord->ExceptionCode); -} \ No newline at end of file +} + + +/****************************************************************************** + * CoDecodeProxy (combase.@) + */ +HRESULT WINAPI CoDecodeProxy(DWORD client_pid, UINT64 proxy_addr, ServerInformation *server_info) +{ + FIXME("%lx, %s, %p.\n", client_pid, proxy_addr, server_info); + return E_NOTIMPL; +} diff --git a/wrappers/new-dlls/dwmapi/dwmapi_main.c b/wrappers/new-dlls/dwmapi/dwmapi_main.c index 056335aea2..88b0da300e 100644 --- a/wrappers/new-dlls/dwmapi/dwmapi_main.c +++ b/wrappers/new-dlls/dwmapi/dwmapi_main.c @@ -38,6 +38,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwmapi); DPI_AWARENESS_CONTEXT WINAPI SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT context ); +typedef struct DWM_COLORIZATION_PARAMS { + DWORD clrColor; + DWORD clrAfterGlow; + DWORD nIntensity; + DWORD clrAfterGlowBalance; + DWORD clrBlurBalance; + DWORD clrGlassReflectionIntensity; + BOOLEAN fOpaque; +}DWM_COLORIZATION_PARAMS; + /********************************************************************** * DwmIsCompositionEnabled (DWMAPI.@) */ @@ -95,15 +105,27 @@ HRESULT WINAPI DwmExtendFrameIntoClientArea(HWND hwnd, const MARGINS* margins) */ HRESULT WINAPI DwmGetColorizationColor(DWORD *colorization, BOOL opaque_blend) { - //FIXME("(%p, %d) stub\n", colorization, opaque_blend); + *colorization = 0x6874B8FC; // Default Windows Vista theme color. TODO: infer from XP theme color + return S_OK; +} - BOOL isCompositionEnabled; - DwmIsCompositionEnabled(&isCompositionEnabled); - - if (isCompositionEnabled) - return S_OK; - else - return DWM_E_COMPOSITIONDISABLED; +static int get_display_frequency(void) +{ + DEVMODEW mode; + BOOL ret; + + memset(&mode, 0, sizeof(mode)); + mode.dmSize = sizeof(mode); + ret = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &mode, 0); + if (ret && mode.dmFields & DM_DISPLAYFREQUENCY && mode.dmDisplayFrequency) + { + return mode.dmDisplayFrequency; + } + else + { + WARN("Failed to query display frequency, returning a fallback value.\n"); + return 60; + } } /********************************************************************** @@ -340,25 +362,6 @@ HRESULT WINAPI DwmRegisterThumbnail(HWND dest, HWND src, PHTHUMBNAIL thumbnail_i return DWM_E_COMPOSITIONDISABLED; } -static int get_display_frequency(void) -{ - DEVMODEW mode; - BOOL ret; - - memset(&mode, 0, sizeof(mode)); - mode.dmSize = sizeof(mode); - ret = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &mode, 0); - if (ret && mode.dmFields & DM_DISPLAYFREQUENCY && mode.dmDisplayFrequency) - { - return mode.dmDisplayFrequency; - } - else - { - WARN("Failed to query display frequency, returning a fallback value.\n"); - return 60; - } -} - /********************************************************************** * DwmGetCompositionTimingInfo (DWMAPI.@) */ @@ -399,13 +402,12 @@ HRESULT WINAPI DwmGetCompositionTimingInfo(HWND hwnd, DWM_TIMING_INFO *info) HRESULT WINAPI DwmAttachMilContent(HWND hwnd) { //FIXME("(%p) stub\n", hwnd); - BOOL isCompositionEnabled; - DwmIsCompositionEnabled(&isCompositionEnabled); + return S_OK; - if (isCompositionEnabled) - return S_OK; - else - return DWM_E_COMPOSITIONDISABLED; + // if (isCompositionEnabled) + // return S_OK; + // else + // return DWM_E_COMPOSITIONDISABLED; } /********************************************************************** @@ -486,14 +488,9 @@ HRESULT WINAPI DwmSetIconicThumbnail(HWND hwnd, HBITMAP hbmp, DWORD flags) /********************************************************************** * DwmpGetColorizationParameters (DWMAPI.@) */ -HRESULT WINAPI DwmpGetColorizationParameters(void *params) -{ - //FIXME("(%p) stub\n", params); - BOOL isCompositionEnabled; - DwmIsCompositionEnabled(&isCompositionEnabled); - - if (isCompositionEnabled) - return S_OK; - else - return DWM_E_COMPOSITIONDISABLED; -} \ No newline at end of file +HRESULT WINAPI DwmpGetColorizationParameters(DWM_COLORIZATION_PARAMS *parameters) { + memset(parameters, 0, sizeof(DWM_COLORIZATION_PARAMS)); + parameters->clrColor = 0x6874B8FC; + parameters->fOpaque = TRUE; + return S_OK; +} \ No newline at end of file diff --git a/wrappers/new-dlls/mmdevapi/CMakeLists.txt b/wrappers/new-dlls/mmdevapi/CMakeLists.txt index f06b2b63e8..1cda15a8c5 100644 --- a/wrappers/new-dlls/mmdevapi/CMakeLists.txt +++ b/wrappers/new-dlls/mmdevapi/CMakeLists.txt @@ -6,16 +6,14 @@ add_definitions(-D__WINESRC__) include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(mmdevapi.dll mmdevapi.spec ADD_IMPORTLIB) -set(baseaddress_mmdevapi 0x62470000) - list(APPEND SOURCE audiovolume.c devenum.c main.c - mmdevapi.h + precomp.h ${CMAKE_CURRENT_BINARY_DIR}/mmdevapi_stubs.c) -add_library(mmdevapi SHARED +add_library(mmdevapi MODULE ${SOURCE} guid.c mmdevapi.rc @@ -24,6 +22,6 @@ add_library(mmdevapi SHARED set_module_type(mmdevapi win32dll) target_link_libraries(mmdevapi uuid wine) add_importlibs(mmdevapi ole32 oleaut32 user32 advapi32 msvcrt kernel32 ntdll) -add_pch(mmdevapi mmdevapi.h SOURCE) +add_pch(mmdevapi precomp.h SOURCE) add_dependencies(mmdevapi dxsdk) add_cd_file(TARGET mmdevapi DESTINATION reactos/system32 FOR all) diff --git a/wrappers/new-dlls/mmdevapi/audiovolume.c b/wrappers/new-dlls/mmdevapi/audiovolume.c index 22613fe33e..24d210a1c8 100644 --- a/wrappers/new-dlls/mmdevapi/audiovolume.c +++ b/wrappers/new-dlls/mmdevapi/audiovolume.c @@ -16,8 +16,28 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS + +#include + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winreg.h" +#include "wine/debug.h" + +#include "ole2.h" +#include "mmdeviceapi.h" +#include "mmsystem.h" +#include "dsound.h" +#include "audioclient.h" +#include "endpointvolume.h" +#include "audiopolicy.h" + #include "mmdevapi.h" +WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi); + typedef struct AEVImpl { IAudioEndpointVolumeEx IAudioEndpointVolumeEx_iface; LONG ref; diff --git a/wrappers/new-dlls/mmdevapi/devenum.c b/wrappers/new-dlls/mmdevapi/devenum.c index e811714065..82e1bb96c2 100644 --- a/wrappers/new-dlls/mmdevapi/devenum.c +++ b/wrappers/new-dlls/mmdevapi/devenum.c @@ -16,15 +16,30 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "mmdevapi.h" +#include + +#define NONAMELESSUNION +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winreg.h" +#include "wine/debug.h" +#include "wine/list.h" + +#include "initguid.h" +#include "ole2.h" +#include "mmdeviceapi.h" +#include "dshow.h" +#include "dsound.h" +#include "audioclient.h" +#include "endpointvolume.h" +#include "audiopolicy.h" -#include +#include "mmdevapi.h" +#include "devpkey.h" -#include -#include -#define _WINDOWS_H -#include -#include +WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi); static const WCHAR software_mmdevapi[] = { 'S','o','f','t','w','a','r','e','\\', @@ -320,7 +335,7 @@ static MMDevice *MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD st cur->state = state; cur->devguid = *id; - StringFromGUID2(&cur->devguid, guidstr, sizeof(guidstr)/sizeof(*guidstr)); + StringFromGUID2(&cur->devguid, guidstr, ARRAY_SIZE(guidstr)); if (flow == eRender) root = key_render; @@ -411,7 +426,7 @@ static HRESULT load_devices_from_reg(void) DWORD len; PROPVARIANT pv = { VT_EMPTY }; - len = sizeof(guidvalue)/sizeof(guidvalue[0]); + len = ARRAY_SIZE(guidvalue); ret = RegEnumKeyExW(cur, i++, guidvalue, &len, NULL, NULL, NULL, NULL); if (ret == ERROR_NO_MORE_ITEMS) { @@ -430,7 +445,7 @@ static HRESULT load_devices_from_reg(void) && SUCCEEDED(MMDevice_GetPropValue(&guid, curflow, (const PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &pv)) && pv.vt == VT_LPWSTR) { - DWORD size_bytes = (strlenW(pv.u.pwszVal) + 1) * sizeof(WCHAR); + DWORD size_bytes = (lstrlenW(pv.u.pwszVal) + 1) * sizeof(WCHAR); WCHAR *name = HeapAlloc(GetProcessHeap(), 0, size_bytes); memcpy(name, pv.u.pwszVal, size_bytes); MMDevice_Create(name, &guid, curflow, @@ -595,7 +610,7 @@ static HRESULT WINAPI MMDevice_Activate(IMMDevice *iface, REFIID riid, DWORD cls if (SUCCEEDED(hr)) { IPersistPropertyBag *ppb; - hr = IUnknown_QueryInterface((IUnknown*)*ppv, &IID_IPersistPropertyBag, (void*)&ppb); + hr = IUnknown_QueryInterface((IUnknown*)*ppv, &IID_IPersistPropertyBag, (void **)&ppb); if (SUCCEEDED(hr)) { /* ::Load cannot assume the interface stays alive after the function returns, @@ -1377,7 +1392,7 @@ static HRESULT WINAPI MMDevPropStore_GetCount(IPropertyStore *iface, DWORD *npro return hr; *nprops = 0; do { - DWORD len = sizeof(buffer)/sizeof(*buffer); + DWORD len = ARRAY_SIZE(buffer); if (RegEnumValueW(propkey, i, buffer, &len, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) break; i++; @@ -1392,7 +1407,7 @@ static HRESULT WINAPI MMDevPropStore_GetAt(IPropertyStore *iface, DWORD prop, PR { MMDevPropStore *This = impl_from_IPropertyStore(iface); WCHAR buffer[50]; - DWORD len = sizeof(buffer)/sizeof(*buffer); + DWORD len = ARRAY_SIZE(buffer); HRESULT hr; HKEY propkey; @@ -1413,7 +1428,7 @@ static HRESULT WINAPI MMDevPropStore_GetAt(IPropertyStore *iface, DWORD prop, PR RegCloseKey(propkey); buffer[38] = 0; CLSIDFromString(buffer, &key->fmtid); - key->pid = atoiW(&buffer[39]); + key->pid = wcstol(&buffer[39], NULL, 10); return S_OK; } @@ -1512,7 +1527,7 @@ static HRESULT WINAPI PB_Read(IPropertyBag *iface, LPCOLESTR name, VARIANT *var, if (!lstrcmpW(name, dsguid)) { WCHAR guidstr[39]; - StringFromGUID2(&This->devguid, guidstr,sizeof(guidstr)/sizeof(*guidstr)); + StringFromGUID2(&This->devguid, guidstr,ARRAY_SIZE(guidstr)); var->n1.n2.vt = VT_BSTR; var->n1.n2.n3.bstrVal = SysAllocString(guidstr); return S_OK; diff --git a/wrappers/new-dlls/mmdevapi/main.c b/wrappers/new-dlls/mmdevapi/main.c index 9677761356..7680b45138 100644 --- a/wrappers/new-dlls/mmdevapi/main.c +++ b/wrappers/new-dlls/mmdevapi/main.c @@ -17,9 +17,31 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" + +#include "ole2.h" +#include "olectl.h" +#include "rpcproxy.h" +#include "propsys.h" +#include "propkeydef.h" +#include "mmdeviceapi.h" +#include "mmsystem.h" +#include "dsound.h" +#include "audioclient.h" +#include "endpointvolume.h" +#include "audiopolicy.h" +#include "devpkey.h" +#include "winreg.h" + #include "mmdevapi.h" +#include "wine/debug.h" -#include +WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi); static HINSTANCE instance; @@ -82,20 +104,17 @@ static BOOL load_driver(const WCHAR *name, DriverFuncs *driver) return TRUE; } -static BOOL init_driver(void) +static BOOL WINAPI init_driver(INIT_ONCE *once, void *param, void **context) { static const WCHAR drv_value[] = {'A','u','d','i','o',0}; static WCHAR default_list[] = {'p','u','l','s','e',',','a','l','s','a',',','o','s','s',',', - 'c','o','r','e','a','u','d','i','o',0}; + 'c','o','r','e','a','u','d','i','o',',','a','n','d','r','o','i','d',0}; DriverFuncs driver; HKEY key; WCHAR reg_list[256], *p, *next, *driver_list = default_list; - if(drvs.module) - return TRUE; - if(RegOpenKeyW(HKEY_CURRENT_USER, drv_keyW, &key) == ERROR_SUCCESS){ DWORD size = sizeof(reg_list); @@ -115,7 +134,7 @@ static BOOL init_driver(void) TRACE("Loading driver list %s\n", wine_dbgstr_w(driver_list)); for(next = p = driver_list; next; p = next + 1){ - next = strchrW(p, ','); + next = wcschr(p, ','); if(next) *next = '\0'; @@ -249,10 +268,11 @@ static IClassFactoryImpl MMDEVAPI_CF[] = { HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { + static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; unsigned int i = 0; TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); - if(!init_driver()){ + if(!InitOnceExecuteOnce(&init_once, init_driver, NULL, NULL)) { ERR("Driver initialization failed\n"); return E_FAIL; } @@ -270,7 +290,7 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) return E_NOINTERFACE; } - for (i = 0; i < sizeof(MMDEVAPI_CF)/sizeof(MMDEVAPI_CF[0]); ++i) + for (i = 0; i < ARRAY_SIZE(MMDEVAPI_CF); ++i) { if (IsEqualGUID(rclsid, MMDEVAPI_CF[i].rclsid)) { IClassFactory_AddRef(&MMDEVAPI_CF[i].IClassFactory_iface); diff --git a/wrappers/new-dlls/mmdevapi/mmdevapi.h b/wrappers/new-dlls/mmdevapi/mmdevapi.h index 4358901d13..45095b103b 100644 --- a/wrappers/new-dlls/mmdevapi/mmdevapi.h +++ b/wrappers/new-dlls/mmdevapi/mmdevapi.h @@ -43,8 +43,6 @@ #include #include -WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi); - extern HRESULT MMDevEnum_Create(REFIID riid, void **ppv) DECLSPEC_HIDDEN; extern void MMDevEnum_Free(void) DECLSPEC_HIDDEN; diff --git a/wrappers/new-dlls/mmdevapi/mmdevapi.rc b/wrappers/new-dlls/mmdevapi/mmdevapi.rc index 3d5d138b00..b613ecbc3e 100644 --- a/wrappers/new-dlls/mmdevapi/mmdevapi.rc +++ b/wrappers/new-dlls/mmdevapi/mmdevapi.rc @@ -1,25 +1 @@ -/* - * Copyright 2009 Henri Verbeet for CodeWeavers - * - * 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 - */ - - 1 WINE_REGISTRY "mmdevapi_classes.rgs" - -#define WINE_FILEDESCRIPTION_STR "Wine MMDevice API for One-Core-API" -#define WINE_FILENAME_STR "mmdevapi.dll" - -#include "common_wrappers_ver.rc" \ No newline at end of file diff --git a/wrappers/new-dlls/shcore/main.c b/wrappers/new-dlls/shcore/main.c index 378e9ee93c..6909656d81 100644 --- a/wrappers/new-dlls/shcore/main.c +++ b/wrappers/new-dlls/shcore/main.c @@ -29,6 +29,8 @@ #include "ocidl.h" #include "shellscalingapi.h" #include "shlwapi.h" +#include "featurestagingapi.h" +#include "shcore.h" #include "wine/debug.h" #include "wine/heap.h" @@ -2534,10 +2536,65 @@ BOOL WINAPI IsOS(DWORD feature) return FALSE; } +/************************************************************************* + * SubscribeFeatureStateChangeNotification [SHCORE.@] + */ +void WINAPI SubscribeFeatureStateChangeNotification(FEATURE_STATE_CHANGE_SUBSCRIPTION *subscription, + FEATURE_STATE_CHANGE_CALLBACK *callback, void *context) +{ + FIXME("(%p, %p, %p) stub\n", subscription, callback, context); +} + +/************************************************************************* + * GetFeatureEnabledState [SHCORE.@] + */ +FEATURE_ENABLED_STATE WINAPI GetFeatureEnabledState(UINT32 feature, FEATURE_CHANGE_TIME change_time) +{ + FIXME("(%u, %u) stub\n", feature, change_time); + return FEATURE_ENABLED_STATE_DEFAULT; +} + +/************************************************************************* + * RegisterScaleChangeEvent [SHCORE.@] + */ +HRESULT WINAPI RegisterScaleChangeEvent(HANDLE handle, DWORD_PTR *cookie) +{ + FIXME("(%p, %p) stub\n", handle, cookie); + return E_NOTIMPL; +} + +/************************************************************************* + * RegisterScaleChangeNotifications [SHCORE.@] + */ +HRESULT WINAPI RegisterScaleChangeNotifications(DISPLAY_DEVICE_TYPE display_device, HWND hwnd, UINT msg, DWORD *cookie) +{ + FIXME("(%d, %p, %u, %p) stub\n", display_device, hwnd, msg, cookie); + + if (cookie) *cookie = 0; + + return E_NOTIMPL; +} + +/************************************************************************* + * CreateRandomAccessStreamOverStream [SHCORE.@] + */ +HRESULT WINAPI CreateRandomAccessStreamOverStream(IStream *stream, BSOS_OPTIONS options, REFIID riid, void **ppv) +{ + FIXME("(%p, %d, %s, %p) stub\n", stream, options, debugstr_guid(riid), ppv); + return E_NOTIMPL; +} + /*********************************************************************** * DllCanUnloadNow (COMCAT.@) */ HRESULT WINAPI DllCanUnloadNow(void) { return S_FALSE; +} + +void UnsubscribeFeatureStateChangeNotification( + FEATURE_STATE_CHANGE_SUBSCRIPTION subscription +) +{ + ; } \ No newline at end of file diff --git a/wrappers/new-dlls/shcore/shcore.spec b/wrappers/new-dlls/shcore/shcore.spec index 33732b1f3b..b46faa1227 100644 --- a/wrappers/new-dlls/shcore/shcore.spec +++ b/wrappers/new-dlls/shcore/shcore.spec @@ -1,15 +1,15 @@ 1 stub -noname SHCreateReadOnlySharedMemoryStream @ stdcall CommandLineToArgvW(wstr ptr) @ stub CreateRandomAccessStreamOnFile -@ stub CreateRandomAccessStreamOverStream +@ stdcall CreateRandomAccessStreamOverStream(ptr long ptr ptr) @ stub CreateStreamOverRandomAccessStream @ stdcall -private DllCanUnloadNow() @ stub DllGetActivationFactory -@ stdcall DllGetClassObject(ptr ptr ptr) +@ stub DllGetClassObject @ stdcall GetCurrentProcessExplicitAppUserModelID(ptr) @ stdcall GetDpiForMonitor(long long ptr ptr) @ stub GetDpiForShellUIComponent -# @ stub GetFeatureEnabledState +@ stdcall GetFeatureEnabledState(long long) # @ stub GetFeatureVariant @ stdcall GetProcessDpiAwareness(long ptr) @ stdcall GetProcessReference(ptr) @@ -32,8 +32,8 @@ # @ stub IsProcessInWDAGContainer # @ stub RecordFeatureError # @ stub RecordFeatureUsage -@ stub RegisterScaleChangeEvent -@ stub RegisterScaleChangeNotifications +@ stdcall RegisterScaleChangeEvent(ptr ptr) +@ stdcall RegisterScaleChangeNotifications(long ptr long ptr) @ stub RevokeScaleChangeNotifications @ stdcall SHAnsiToAnsi(str ptr long) @ stdcall SHAnsiToUnicode(str ptr long) @@ -92,9 +92,9 @@ @ stdcall SetCurrentProcessExplicitAppUserModelID(wstr) @ stdcall SetProcessDpiAwareness(long) @ stdcall SetProcessReference(ptr) -# @ stub SubscribeFeatureStateChangeNotification +@ stdcall SubscribeFeatureStateChangeNotification(ptr ptr ptr) @ stub UnregisterScaleChangeEvent -# @ stub UnsubscribeFeatureStateChangeNotification +@ stdcall UnsubscribeFeatureStateChangeNotification(ptr) 100 stub -noname SHManagedCreateStreamOnFile 101 stub -noname SHManagedCreateFile @@ -140,22 +140,22 @@ 171 stub -noname PathIsNetworkPathA 172 stub -noname PathBuildRootW 173 stub -noname PathBuildRootA -174 stdcall -noname DriveType(long) -175 stdcall -noname IsNetDrive(long) +174 stub -noname DriveType +175 stub -noname IsNetDrive 181 stub -noname SHMapHandle -182 stdcall -noname SHAllocShared(ptr long long) +182 stub -noname SHAllocShared 183 stub -noname SHLockSharedEx -184 stdcall -noname SHLockShared(long long) +184 stub -noname SHLockShared 185 stub -noname SHGetSizeShared -186 stdcall -noname SHUnlockShared(ptr) -187 stdcall -noname SHFreeShared(long long) +186 stub -noname SHUnlockShared +187 stub -noname SHFreeShared 188 stub -noname SHCreateWorkerWindowW 189 stub -noname SHCreateOplockProvider 190 stub -noname SHWindowsPolicy 191 stub -noname SHWindowsPolicyGetValue 192 stub -noname IsAppCompatModeEnabled 193 stub -noname SHGetObjectCompatFlags -200 stdcall -noname GUIDFromStringW(wstr ptr) +200 stub -noname GUIDFromStringW 220 stub -noname GetPhysicalDpiForDevice 222 stub -noname ScaleRelativePixelsForDevice 223 stub -noname PhysicalRectFromScaledRect @@ -189,10 +189,10 @@ 261 stub -noname RelativeRectFromPhysicalRectWithScales 270 stub -noname SHCreateMemoryStreamOnSharedBuffer 280 stub -noname _CreateDirectoryHelper -281 stdcall -noname Win32CreateDirectory(wstr ptr) +281 stub -noname Win32CreateDirectory 282 stub -noname SuspendSHNotify 283 stub -noname ResumeSHNotify 284 stub -noname IsNotifySuspended -290 stdcall -noname SHCreateDirectoryExW(long wstr ptr) -291 stdcall -noname SHCreateDirectoryExA(long str ptr) +290 stub -noname SHCreateDirectoryExW +291 stub -noname SHCreateDirectoryExA 292 stub -noname SHCreateDirectory diff --git a/wrappers/new-dlls/sppc/sppc.c b/wrappers/new-dlls/sppc/sppc.c index a11278c5ad..8ebb69662e 100644 --- a/wrappers/new-dlls/sppc/sppc.c +++ b/wrappers/new-dlls/sppc/sppc.c @@ -51,9 +51,16 @@ HRESULT WINAPI SLOpen(HSLC *handle) return S_OK; } +HRESULT WINAPI SLClose(HSLC handle) +{ + FIXME("(%p) stub\n", handle ); + + return S_OK; +} + HRESULT WINAPI SLPersistApplicationPolicies(const SLID *app, const SLID *product, DWORD flags) { - FIXME("(%s,%s,%x) stub\n", wine_dbgstr_guid(app), wine_dbgstr_guid(product), flags); + FIXME("(%s,%s,%lx) stub\n", wine_dbgstr_guid(app), wine_dbgstr_guid(product), flags); if (!app) return E_INVALIDARG; diff --git a/wrappers/new-dlls/sppc/sppc.spec b/wrappers/new-dlls/sppc/sppc.spec index 3ac40c2397..6926d4d8b6 100644 --- a/wrappers/new-dlls/sppc/sppc.spec +++ b/wrappers/new-dlls/sppc/sppc.spec @@ -17,7 +17,7 @@ @ stub SLpSetActivationInProgress @ stub SLpTriggerServiceWorker @ stub SLpVLActivateProduct -@ stub SLClose +@ stdcall SLClose(ptr) @ stub SLConsumeRight @ stub SLDepositMigrationBlob @ stub SLDepositOfflineConfirmationId diff --git a/wrappers/sdk/include/wsdk/CMakeLists.txt b/wrappers/sdk/include/wsdk/CMakeLists.txt index 5849bcb738..b4ae63f2dc 100644 --- a/wrappers/sdk/include/wsdk/CMakeLists.txt +++ b/wrappers/sdk/include/wsdk/CMakeLists.txt @@ -10,6 +10,11 @@ list(APPEND SOURCE d2d1.idl d2d1_1.idl d2d1_2.idl + d2d1_3.idl + d2d1effectauthor.idl + d2d1effects.idl + d2d1effects_1.idl + d2d1effects_2.idl d3d10.idl d3d10_1.idl d3d10sdklayers.idl @@ -70,7 +75,7 @@ list(APPEND SOURCE add_iid_library(dxgi_uuids dxgi.idl dxgi1_2.idl dxgi1_3.idl dxgi1_4.idl dxgi1_5.idl dxgi1_6.idl d3d12.idl dxgi_internal.idl) -add_iid_library(d2d1_uuids d2d1.idl d2d1_1.idl d2d1_2.idl) +add_iid_library(d2d1_uuids d2d1.idl d2d1_1.idl d2d1_2.idl d2d1_3.idl d2d1effectauthor.idl d2d1effects.idl d2d1effects_1.idl d2d1effects_2.idl) add_iid_library(d3d10_uuids d3d10.idl d3d10_1.idl d3d10sdklayers.idl) add_iid_library(d3d10_1_uuids d3d10_1.idl) add_iid_library(d3d11_uuids d3d11.idl d3d11_1.idl d3d11_2.idl d3d11_3.idl d3d11_4.idl d3d11sdklayers.idl) diff --git a/wrappers/sdk/include/wsdk/d2d1_1.idl b/wrappers/sdk/include/wsdk/d2d1_1.idl index 257a970968..5560f24a38 100644 --- a/wrappers/sdk/include/wsdk/d2d1_1.idl +++ b/wrappers/sdk/include/wsdk/d2d1_1.idl @@ -17,9 +17,9 @@ */ import "d2d1.idl"; +import "d2d1effects.idl"; interface ID2D1DeviceContext; -interface ID2D1PathGeometry1; interface ID2D1Properties; interface IPrintDocumentPackageTarget; interface ID2D1PrintControl; @@ -33,6 +33,7 @@ cpp_quote("#ifndef __dwrite_h__") /* already defined in dwrite.h but needed for WIDL */ typedef struct DWRITE_GLYPH_RUN_DESCRIPTION DWRITE_GLYPH_RUN_DESCRIPTION; cpp_quote("#endif /* __dwrite_h__ */") +cpp_quote("#define D2D1_INVALID_PROPERTY_INDEX UINT_MAX") typedef enum D2D1_DEVICE_CONTEXT_OPTIONS { @@ -156,7 +157,7 @@ typedef enum D2D1_LAYER_OPTIONS1 D2D1_LAYER_OPTIONS1_FORCE_DWORD = 0xffffffff, } D2D1_LAYER_OPTIONS1; -typedef struct D2D1_PROPERTY_BINDING D2D1_PROPERTY_BINDING; +struct D2D1_PROPERTY_BINDING; typedef D2D_MATRIX_4X4_F D2D1_MATRIX_4X4_F; typedef enum D2D1_PROPERTY_TYPE @@ -348,6 +349,22 @@ interface ID2D1GdiMetafile : ID2D1Resource ); } +[ + object, + uuid(62baa2d2-ab54-41b7-b872-787e0106a421), + local, +] +interface ID2D1PathGeometry1 : ID2D1PathGeometry +{ + HRESULT ComputePointAndSegmentAtLength( + [in] float length, + [in] UINT32 start_segment, + [in, optional] const D2D1_MATRIX_3X2_F *transform, + [in] float tolerance, + [out] D2D1_POINT_DESCRIPTION *point_desc + ); +} + [ object, uuid(483473d7-cd46-4f9d-9d3a-3112aa80159d), @@ -558,7 +575,7 @@ interface ID2D1CommandSink : IUnknown [in] IDWriteRenderingParams *text_rendering_params ); HRESULT SetTransform( - [in] D2D1_MATRIX_3X2_F *transform + [in] const D2D1_MATRIX_3X2_F *transform ); HRESULT SetPrimitiveBlend( [in] D2D1_PRIMITIVE_BLEND primitive_blend @@ -606,7 +623,7 @@ interface ID2D1CommandSink : IUnknown HRESULT DrawImage( [in] ID2D1Image *image, [in] const D2D1_POINT_2F *target_offset, - [in] const D2D1_POINT_2F *image_rect, + [in] const D2D1_RECT_F *image_rect, [in] D2D1_INTERPOLATION_MODE interpolation_mode, [in] D2D1_COMPOSITE_MODE composite_mode ); @@ -781,7 +798,7 @@ interface ID2D1DeviceContext : ID2D1RenderTarget BOOL IsBufferPrecisionSupported( [in] D2D1_BUFFER_PRECISION buffer_precision ); - void GetImageLocalBounds( + HRESULT GetImageLocalBounds( [in] ID2D1Image *image, [out] D2D1_RECT_F *local_bounds ); @@ -919,14 +936,14 @@ interface ID2D1Factory1 : ID2D1Factory HRESULT RegisterEffectFromStream( [in] REFCLSID effect_id, [in] IStream *property_xml, - [in, size_is(binding_count)] const D2D1_PROPERTY_BINDING *bindings, + [in, size_is(binding_count)] const struct D2D1_PROPERTY_BINDING *bindings, [in] UINT32 binding_count, [in] PD2D1_EFFECT_FACTORY effect_factory ); HRESULT RegisterEffectFromString( [in] REFCLSID effect_id, [in] const WCHAR *property_xml, - [in, size_is(binding_count)] const D2D1_PROPERTY_BINDING *bindings, + [in, size_is(binding_count)] const struct D2D1_PROPERTY_BINDING *bindings, [in] UINT32 binding_count, [in] PD2D1_EFFECT_FACTORY effect_factory ); diff --git a/wrappers/sdk/include/wsdk/d2d1_2.idl b/wrappers/sdk/include/wsdk/d2d1_2.idl index 39e285dc22..982131667d 100644 --- a/wrappers/sdk/include/wsdk/d2d1_2.idl +++ b/wrappers/sdk/include/wsdk/d2d1_2.idl @@ -17,6 +17,7 @@ */ import "d2d1_1.idl"; +import "d2d1effects_1.idl"; typedef enum D2D1_RENDERING_PRIORITY { @@ -88,3 +89,15 @@ interface ID2D1Factory2 : ID2D1Factory1 [out] ID2D1Device1 **device ); } + +[ + object, + uuid(9eb767fd-4269-4467-b8c2-eb30cb305743), + local, +] +interface ID2D1CommandSink1 : ID2D1CommandSink +{ + HRESULT SetPrimitiveBlend1( + [in] D2D1_PRIMITIVE_BLEND primitive_blend + ); +} diff --git a/wrappers/to-synch/dll/ntdll/def/ntdll.spec b/wrappers/to-synch/dll/ntdll/def/ntdll.spec index e9d67f81bf..ebf6350346 100644 --- a/wrappers/to-synch/dll/ntdll/def/ntdll.spec +++ b/wrappers/to-synch/dll/ntdll/def/ntdll.spec @@ -124,9 +124,9 @@ @ stdcall LdrUnloadDll(ptr) @ stdcall LdrUnlockLoaderLock(long long) @ stdcall LdrVerifyImageMatchesChecksum(ptr long long long) -@ extern NlsAnsiCodePage -@ extern NlsMbCodePageTag -@ extern NlsMbOemCodePageTag +@ stdcall NlsAnsiCodePage() NlsAnsiCodePage +@ stdcall NlsMbCodePageTag() NlsMbCodePageTag +@ stdcall NlsMbOemCodePageTag() NlsMbOemCodePageTag @ stdcall NtAcceptConnectPort(ptr long ptr long long ptr) @ stdcall NtAccessCheck(ptr long long ptr ptr ptr ptr ptr) @ stdcall NtAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr) @@ -1295,7 +1295,7 @@ @ cdecl -arch=i386 _aulldvrm() @ cdecl -arch=i386 -ret64 _aullrem(double double) @ cdecl -arch=i386 _aullshr() -@ extern -arch=i386 _chkstk +@ cdecl -arch=i386 _chkstk() @ cdecl -arch=i386,x86_64,arm _fltused() @ cdecl -arch=i386 -ret64 _ftol() @ cdecl _i64toa(double ptr long) diff --git a/wrappers/to-synch/dll/win32/advapi32/advapi32.spec b/wrappers/to-synch/dll/win32/advapi32/advapi32.spec index 474002de91..86de042fd4 100644 --- a/wrappers/to-synch/dll/win32/advapi32/advapi32.spec +++ b/wrappers/to-synch/dll/win32/advapi32/advapi32.spec @@ -763,7 +763,9 @@ #For hooks -@ stdcall SetNamedSecurityInfoWNative(wstr long ptr ptr ptr ptr ptr) SetNamedSecurityInfo +@ stdcall SetNamedSecurityInfoWNative(wstr long ptr ptr ptr ptr ptr) SetNamedSecurityInfoW @ stdcall SetSecurityInfoNative(long long long ptr ptr ptr ptr) SetSecurityInfo @ stdcall GetSecurityInfoNative(long long long ptr ptr ptr ptr ptr) GetSecurityInfo -@ stdcall GetNamedSecurityInfoWNative(wstr long long ptr ptr ptr ptr ptr) GetNamedSecurityInfoW \ No newline at end of file +@ stdcall GetNamedSecurityInfoWNative(wstr long long ptr ptr ptr ptr ptr) GetNamedSecurityInfoW +@ stdcall RegGetValueWNative(long wstr wstr long ptr ptr ptr) RegGetValueW +@ stdcall RegNotifyChangeKeyValueNative(long long long long long) RegNotifyChangeKeyValue \ No newline at end of file diff --git a/wrappers/to-synch/dll/win32/bcrypt/bcrypt.spec b/wrappers/to-synch/dll/win32/bcrypt/bcrypt.spec index 7f49bf75e3..54d7908719 100644 --- a/wrappers/to-synch/dll/win32/bcrypt/bcrypt.spec +++ b/wrappers/to-synch/dll/win32/bcrypt/bcrypt.spec @@ -59,4 +59,7 @@ @ stub GetSignatureInterface @ stub BCryptDeriveKeyCapi -@ stub BCryptDeriveKeyPBKDF2 \ No newline at end of file +@ stub BCryptDeriveKeyPBKDF2 + +#For Bcrypt Hook +@ stdcall -stub BCryptCreateHashNative(ptr ptr ptr long ptr long long) \ No newline at end of file diff --git a/wrappers/to-synch/win32ss/gdi/gdi32/gdi32.spec b/wrappers/to-synch/win32ss/gdi/gdi32/gdi32.spec index 290beba125..30a95b4821 100644 --- a/wrappers/to-synch/win32ss/gdi/gdi32/gdi32.spec +++ b/wrappers/to-synch/win32ss/gdi/gdi32/gdi32.spec @@ -622,4 +622,12 @@ 618 stdcall D3DKMTDestroyDevice(ptr) 619 stdcall D3DKMTOpenAdapterFromGdiDisplayName(ptr) 620 stdcall D3DKMTSetVidPnSourceOwner(ptr) -621 stdcall D3DKMTCheckVidPnExclusiveOwnership(ptr) \ No newline at end of file +621 stdcall D3DKMTCheckVidPnExclusiveOwnership(ptr) + +@ stdcall -stub D3DKMTCheckMonitorPowerState(ptr) +@ stdcall -stub D3DKMTCheckSharedResourceAccess(ptr) +@ stdcall -stub D3DKMTOpenAdapterFromLuid(ptr) +@ stdcall -stub D3DKMTQueryStatistics(ptr) +@ stdcall -stub D3DKMTQueryVideoMemoryInfo(ptr) +@ stdcall -stub D3DKMTSetQueuedLimit(ptr) +@ stdcall -stub D3DKMTSetProcessSchedulingPriorityClass(long long) \ No newline at end of file