From 7a43a3001f1c6bd0009a135258993581cc81318b Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Tue, 9 Mar 2010 02:29:25 +0000 Subject: [PATCH 01/64] [SETUPLDR]: Fix build breakage caused by hpoussin, by linking minihal into setupldr as well. svn path=/trunk/; revision=46023 --- reactos/boot/freeldr/freeldr/setupldr.rbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/boot/freeldr/freeldr/setupldr.rbuild b/reactos/boot/freeldr/freeldr/setupldr.rbuild index 20d0c745430..0a352f48602 100644 --- a/reactos/boot/freeldr/freeldr/setupldr.rbuild +++ b/reactos/boot/freeldr/freeldr/setupldr.rbuild @@ -11,6 +11,7 @@ cmlib rtl libcntpr + mini_hal -nostartfiles -nostdlib From c03ec91188c0843d3cd9a7ffaae4de8503256da1 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Tue, 9 Mar 2010 03:48:05 +0000 Subject: [PATCH 02/64] - [User32] Fix timer crash when calling proc. svn path=/trunk/; revision=46025 --- reactos/dll/win32/user32/windows/message.c | 69 ++++++++++++++++++---- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/reactos/dll/win32/user32/windows/message.c b/reactos/dll/win32/user32/windows/message.c index bff9ee5b42c..81d0d96be09 100644 --- a/reactos/dll/win32/user32/windows/message.c +++ b/reactos/dll/win32/user32/windows/message.c @@ -1211,7 +1211,14 @@ IntCallWindowProcW(BOOL IsAnsiProc, if (PreResult) goto Exit; - Result = WndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam); + _SEH2_TRY // wine does this. + { + Result = WndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END; if (Hook && MsgOverride) { @@ -1252,7 +1259,14 @@ IntCallWindowProcW(BOOL IsAnsiProc, if (PreResult) goto Exit; - Result = WndProc(hWnd, Msg, wParam, lParam); + _SEH2_TRY + { + Result = WndProc(hWnd, Msg, wParam, lParam); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END; if (Hook && MsgOverride) { @@ -1329,7 +1343,14 @@ IntCallWindowProcA(BOOL IsAnsiProc, if (PreResult) goto Exit; - Result = WndProc(hWnd, Msg, wParam, lParam); + _SEH2_TRY + { + Result = WndProc(hWnd, Msg, wParam, lParam); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END; if (Hook && MsgOverride) { @@ -1374,8 +1395,15 @@ IntCallWindowProcA(BOOL IsAnsiProc, if (PreResult) goto Exit; - Result = WndProc(UnicodeMsg.hwnd, UnicodeMsg.message, - UnicodeMsg.wParam, UnicodeMsg.lParam); + _SEH2_TRY + { + Result = WndProc(UnicodeMsg.hwnd, UnicodeMsg.message, + UnicodeMsg.wParam, UnicodeMsg.lParam); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END; if (Hook && MsgOverride) { @@ -1573,10 +1601,18 @@ DispatchMessageA(CONST MSG *lpmsg) if ( lpmsg->message == WM_SYSTIMER ) return NtUserDispatchMessage( (PMSG)lpmsg ); - Ret = WndProc(lpmsg->hwnd, - lpmsg->message, - lpmsg->wParam, - GetTickCount()); + _SEH2_TRY // wine does this. + { + Ret = WndProc(lpmsg->hwnd, + lpmsg->message, + lpmsg->wParam, + GetTickCount()); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END; + } else if (Wnd != NULL) { @@ -1633,10 +1669,17 @@ DispatchMessageW(CONST MSG *lpmsg) if ( lpmsg->message == WM_SYSTIMER ) return NtUserDispatchMessage( (PMSG) lpmsg ); - Ret = WndProc(lpmsg->hwnd, - lpmsg->message, - lpmsg->wParam, - GetTickCount()); + _SEH2_TRY + { + Ret = WndProc(lpmsg->hwnd, + lpmsg->message, + lpmsg->wParam, + GetTickCount()); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END; } else if (Wnd != NULL) { From d5c439798c8a303ff2483c5d09d01e8cca1d96ba Mon Sep 17 00:00:00 2001 From: James Tabor Date: Tue, 9 Mar 2010 03:48:43 +0000 Subject: [PATCH 03/64] - [User32_winetest] Restore Timer test. svn path=/trunk/; revision=46026 --- rostests/winetests/user32/msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rostests/winetests/user32/msg.c b/rostests/winetests/user32/msg.c index 56c15299042..23e990ee96c 100755 --- a/rostests/winetests/user32/msg.c +++ b/rostests/winetests/user32/msg.c @@ -12424,7 +12424,7 @@ START_TEST(msg) test_interthread_messages(); test_message_conversion(); test_accelerators(); -// test_timers(); + test_timers(); test_timers_no_wnd(); if (hCBT_hook) test_set_hook(); test_DestroyWindow(); From b36899aa50e707436e6790f0f689b42546725d94 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Tue, 9 Mar 2010 09:26:46 +0000 Subject: [PATCH 04/64] [WIN32K]: Stub-plement NtUserSetInformationThread for UserInitiateShutdown and UserEndShutdown. I think we're supposed to notify Winlogon at some point, and check for races. Part of new shutdown code. svn path=/trunk/; revision=46027 --- reactos/include/reactos/win32k/ntuser.h | 26 +++++++++++++---- .../subsystems/win32/win32k/ntuser/ntstubs.c | 28 +++++++++++++------ 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index cddd15b6d55..9354faccd56 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -6,6 +6,21 @@ typedef struct _THREADINFO *PTHREADINFO; struct _DESKTOP; struct _WND; +typedef enum _USERTHREADINFOCLASS +{ + UserThreadShutdownInformation, + UserThreadFlags, + UserThreadTaskName, + UserThreadWOWInformation, + UserThreadHungStatus, + UserThreadInitiateShutdown, + UserThreadEndShutdown, + UserThreadUseActiveDesktop, + UserThreadUseDesktop, + UserThreadRestoreDesktop, + UserThreadCsrApiPort, +} USERTHREADINFOCLASS; + typedef struct _LARGE_UNICODE_STRING { ULONG Length; @@ -2618,13 +2633,14 @@ NtUserSetInformationProcess( DWORD dwUnknown3, DWORD dwUnknown4); -DWORD +NTSTATUS NTAPI NtUserSetInformationThread( - DWORD dwUnknown1, - DWORD dwUnknown2, - DWORD dwUnknown3, - DWORD dwUnknown4); + IN HANDLE ThreadHandle, + IN USERTHREADINFOCLASS ThreadInformationClass, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationLength +); DWORD NTAPI diff --git a/reactos/subsystems/win32/win32k/ntuser/ntstubs.c b/reactos/subsystems/win32/win32k/ntuser/ntstubs.c index ec680a871c9..f9104fe5faa 100644 --- a/reactos/subsystems/win32/win32k/ntuser/ntstubs.c +++ b/reactos/subsystems/win32/win32k/ntuser/ntstubs.c @@ -1029,16 +1029,28 @@ NtUserSetInformationProcess( return 0; } -DWORD +NTSTATUS APIENTRY -NtUserSetInformationThread( - DWORD dwUnknown1, - DWORD dwUnknown2, - DWORD dwUnknown3, - DWORD dwUnknown4) +NtUserSetInformationThread(IN HANDLE ThreadHandle, + IN USERTHREADINFOCLASS ThreadInformationClass, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationLength) + { - UNIMPLEMENTED; - return 0; + if (ThreadInformationClass == UserThreadInitiateShutdown) + { + DPRINT1("Shutdown initiated\n"); + } + else if (ThreadInformationClass == UserThreadEndShutdown) + { + DPRINT1("Shutdown ended\n"); + } + else + { + UNIMPLEMENTED; + } + + return STATUS_SUCCESS; } DWORD From 6b007be4cd39170ea07fcc6a1c66c4c6e041d233 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Tue, 9 Mar 2010 10:35:58 +0000 Subject: [PATCH 05/64] [NTOS]: While attempting to ressucitate the user-mode shutdown code in CSRSS (disabled since 2006), it seemed clear that one of the main steps is to obtain the caller's LUID in order to kill the right processes. This LUID is obtained from the current thread's token, and we know it's the callers since we're supposed to impersonate the caller. Unfortunately, impersonation failed, making the whole process fail. Impersonation failed because NtImpersonateThread was actually inverting the THREAD_IMPERSONATE rights, asking the client thread for the server's permissions, and vice versa. Fixing this resulted in yet another failure. Analysis of this failure showed that even opening the server (ie: current) thread for THREAD_DIRECT_IMPERSONATION failed, which is unusual since the current thread should have access to all its rights. This is determined in PspCreateThread when the ETHREAD->GrantedAccess field is set. Continuing onto this path, tracing revealed that GrantedAccess was merely 0x1607F and not 0x1F3FF as expected, meaning that not all rights were given, including the impersonate right (0x200), explaining the failure, but not the deeper reason behind it. Attempting to identify which code path set this GrantedAccess, the SepAccessCheck routine came to light. A bug there caused MAXIMUM_ALLOWED accesses to fail in certain scenarios, such as when the object had no security descriptor, because MAXIMUM_ALLOWED would be granted as an absolute value, when instead of it is a flag that should grant GENERIC_ALL. Fixing that bug, the failure continued. Further analysis identified that the Administrators SID was being found with GENERIC_READ + WRITE + EXECUTE access, and no SID was found for GENERIC_ALL access. This happened when searching the system token's default DACL, which is assigned to the kernel (but for kernel-mode callers, this check was skipped), smss, winlogon, etc. The code for creating this system token was heavily hacked, so the function to create the system token, as well as NtCreateToken were refactored to use a common piece of token-creating code. Furthermode, the system token was correctly created with Local System as the user, and Administrators as one of the groups. Finally, SeDefaultDacl was used (already setup properly) instead of a badly configured Default DACL. The new shared code also correctly sets the SE_GROUP_ENABLED flag on all SE_GROUP_MANDATORY groups, and scans tokens to set the TOKEN_HAS_ADMIN_GROUP and TOKEN_HAS_TRAVERSE_PRIVILEGE flags which were not previously set. With the correct system token and default DACL, the Local System SID was now found, but the failure continued. This was revealed to be due to an even deeper rooted problem, as the SepIsSidInToken routine checked for SE_GROUP_ENABLED before listing a SID as "present". Although this is correct for actual groups, the User SID will never have the SE_GROUP_ENABLED flag as it is not a group. This caused any granted access ACE belonging to a user (instead of a group) to be ignored, causing either access check failures, or limited rights returned (in the MAXIMUM_ALLOWED case). Upon fixing this bug, the NtImpersonateThread call finally returned success, since the rights were now correct. Promptly upon calling NtOpenThreadToken to query the LUID however, the system ASSERTED with FALSE. The code at fault was a line in NtOpenThreadTokenEx which forcefully ASSERTed if the impersonation code path was taken, presumably because this was never tested, and ReactOS would actually always fail impersonation attempts due to the bugs fixed above. This routine was thus quickly reworked to fix some mistakes (such as forgetting to actually impersonate the client, incorrect referencing/dereferencing of thread/tokens, and assumptions about DACL creation success). Having fixed the NtOpenThreadTokenEx routine, the LUID query now went through for the impersonated token, but soon causing a user-mode crash, due to an incorrect parameter reference in the CsrGetProcessLuid function in the csrsrv code by Alex (which I copy/pasted to reduce code duplication). Fixing this final bug finally allowed the correct LUID to be queried and I was able to continue development of not-yet-commited user-mode shutdown code. svn path=/trunk/; revision=46028 --- reactos/ntoskrnl/po/povolume.c | 3 - reactos/ntoskrnl/ps/security.c | 12 +- reactos/ntoskrnl/se/semgr.c | 17 +- reactos/ntoskrnl/se/token.c | 737 ++++++++++++------------ reactos/subsystems/csr/csrsrv/process.c | 2 +- 5 files changed, 397 insertions(+), 374 deletions(-) diff --git a/reactos/ntoskrnl/po/povolume.c b/reactos/ntoskrnl/po/povolume.c index 58cc3327deb..15aaebf7586 100644 --- a/reactos/ntoskrnl/po/povolume.c +++ b/reactos/ntoskrnl/po/povolume.c @@ -84,16 +84,13 @@ PoVolumeDevice(IN PDEVICE_OBJECT DeviceObject) PAGED_CODE(); /* Get dope from the device (if the device has no dope, it will receive some) */ - DPRINT1("New volume: %p\n", DeviceObject); Dope = PopGetDope(DeviceObject); if (Dope) { /* Make sure we can flush safely */ - DPRINT1("Acquiring volume lock\n"); KeAcquireGuardedMutex(&PopVolumeLock); /* Add this volume into the list of power-manager volumes */ - DPRINT1("Got DOPE: %p\n", Dope); if (!Dope->Volume.Flink) InsertTailList(&PopVolumeDevices, &Dope->Volume); /* Allow flushes to go through */ diff --git a/reactos/ntoskrnl/ps/security.c b/reactos/ntoskrnl/ps/security.c index 27895d35057..f45b09175dd 100644 --- a/reactos/ntoskrnl/ps/security.c +++ b/reactos/ntoskrnl/ps/security.c @@ -965,32 +965,32 @@ NtImpersonateThread(IN HANDLE ThreadHandle, /* Reference the thread */ Status = ObReferenceObjectByHandle(ThreadHandle, - THREAD_IMPERSONATE, + THREAD_DIRECT_IMPERSONATION, PsThreadType, PreviousMode, (PVOID*)&Thread, NULL); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { /* Reference the impersonating thead */ Status = ObReferenceObjectByHandle(ThreadToImpersonateHandle, - THREAD_DIRECT_IMPERSONATION, + THREAD_IMPERSONATE, PsThreadType, PreviousMode, (PVOID*)&ThreadToImpersonate, NULL); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { /* Create a client security context */ Status = SeCreateClientSecurity(ThreadToImpersonate, SecurityQualityOfService, 0, &ClientContext); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { /* Do the impersonation */ SeImpersonateClient(&ClientContext, Thread); - if(ClientContext.ClientToken) + if (ClientContext.ClientToken) { /* Dereference the client token if we had one */ ObDereferenceObject(ClientContext.ClientToken); diff --git a/reactos/ntoskrnl/se/semgr.c b/reactos/ntoskrnl/se/semgr.c index fdee0973027..8ed056becb8 100644 --- a/reactos/ntoskrnl/se/semgr.c +++ b/reactos/ntoskrnl/se/semgr.c @@ -279,6 +279,7 @@ SeDefaultObjectMethod(IN PVOID Object, return STATUS_SUCCESS; } +ULONG SidInTokenCalls = 0; static BOOLEAN SepSidInToken(PACCESS_TOKEN _Token, @@ -289,6 +290,9 @@ SepSidInToken(PACCESS_TOKEN _Token, PAGED_CODE(); + SidInTokenCalls++; + if (!(SidInTokenCalls % 10000)) DPRINT1("SidInToken Calls: %d\n", SidInTokenCalls); + if (Token->UserAndGroupCount == 0) { return FALSE; @@ -298,7 +302,7 @@ SepSidInToken(PACCESS_TOKEN _Token, { if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid)) { - if (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED) + if ((i == 0)|| (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)) { return TRUE; } @@ -470,7 +474,16 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, SeUnlockSubjectContext(SubjectSecurityContext); } - *GrantedAccess = DesiredAccess; + if (DesiredAccess & MAXIMUM_ALLOWED) + { + *GrantedAccess = GenericMapping->GenericAll; + *GrantedAccess |= (DesiredAccess & ~MAXIMUM_ALLOWED); + } + else + { + *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess; + } + *AccessStatus = STATUS_SUCCESS; return TRUE; } diff --git a/reactos/ntoskrnl/se/token.c b/reactos/ntoskrnl/se/token.c index 38e5012c559..c27d7f8c40a 100644 --- a/reactos/ntoskrnl/se/token.c +++ b/reactos/ntoskrnl/se/token.c @@ -22,6 +22,9 @@ POBJECT_TYPE SepTokenObjectType = NULL; ERESOURCE SepTokenLock; +TOKEN_SOURCE SeSystemTokenSource = {"*SYSTEM*", {0}}; +LUID SeSystemAuthenticationId = SYSTEM_LUID; + static GENERIC_MAPPING SepTokenMapping = {TOKEN_READ, TOKEN_WRITE, TOKEN_EXECUTE, @@ -244,7 +247,7 @@ SepDuplicateToken(PTOKEN Token, (PVOID*)&AccessToken); if (!NT_SUCCESS(Status)) { - DPRINT1("ObCreateObject() failed (Status %lx)\n"); + DPRINT1("ObCreateObject() failed (Status %lx)\n", Status); return(Status); } @@ -510,34 +513,80 @@ SeAssignPrimaryToken(IN PEPROCESS Process, ObInitializeFastReference(&Process->Token, Token); } -PTOKEN + +NTSTATUS NTAPI -SepCreateSystemProcessToken(VOID) -{ - NTSTATUS Status; - ULONG uSize; - ULONG i; - ULONG uLocalSystemLength; - ULONG uWorldLength; - ULONG uAuthUserLength; - ULONG uAdminsLength; +SepCreateToken(OUT PHANDLE TokenHandle, + IN KPROCESSOR_MODE PreviousMode, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN TOKEN_TYPE TokenType, + IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, + IN PLUID AuthenticationId, + IN PLARGE_INTEGER ExpirationTime, + IN PSID_AND_ATTRIBUTES User, + IN ULONG GroupCount, + IN PSID_AND_ATTRIBUTES Groups, + IN ULONG GroupLength, + IN ULONG PrivilegeCount, + IN PLUID_AND_ATTRIBUTES Privileges, + IN PSID Owner, + IN PSID PrimaryGroup, + IN PACL DefaultDacl, + IN PTOKEN_SOURCE TokenSource, + IN BOOLEAN SystemToken) +{ PTOKEN AccessToken; - PVOID SidArea; + LUID TokenId; + LUID ModifiedId; + PVOID EndMem; + ULONG uLength; + ULONG i; + NTSTATUS Status; + ULONG TokenFlags = 0; - PAGED_CODE(); + /* Loop all groups */ + for (i = 0; i < GroupCount; i++) + { + /* Check for mandatory groups */ + if (Groups[i].Attributes & SE_GROUP_MANDATORY) + { + /* Force them to be enabled */ + Groups[i].Attributes |= (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT); + } + + /* Check of the group is an admin group */ + if (RtlEqualSid(SeAliasAdminsSid, Groups[i].Sid)) + { + /* Remember this so we can optimize queries later */ + TokenFlags |= TOKEN_HAS_ADMIN_GROUP; + } + } - uLocalSystemLength = RtlLengthSid(SeLocalSystemSid); - uWorldLength = RtlLengthSid(SeWorldSid); - uAuthUserLength = RtlLengthSid(SeAuthenticatedUserSid); - uAdminsLength = RtlLengthSid(SeAliasAdminsSid); + /* Loop all privileges */ + for (i = 0; i < PrivilegeCount; i++) + { + /* For optimization, check for change notify and impersonate rights */ + if (((RtlEqualLuid(&Privileges[i].Luid, &SeChangeNotifyPrivilege)) && + (Privileges[i].Attributes & SE_PRIVILEGE_ENABLED))) + { + /* Remember token has traverse */ + TokenFlags |= TOKEN_HAS_TRAVERSE_PRIVILEGE; + } + } + + Status = ZwAllocateLocallyUniqueId(&TokenId); + if (!NT_SUCCESS(Status)) + return(Status); - /* - * Initialize the token - */ - Status = ObCreateObject(KernelMode, + Status = ZwAllocateLocallyUniqueId(&ModifiedId); + if (!NT_SUCCESS(Status)) + return(Status); + + Status = ObCreateObject(PreviousMode, SepTokenObjectType, - NULL, - KernelMode, + ObjectAttributes, + PreviousMode, NULL, sizeof(TOKEN), 0, @@ -545,180 +594,279 @@ SepCreateSystemProcessToken(VOID) (PVOID*)&AccessToken); if (!NT_SUCCESS(Status)) { - return NULL; + DPRINT1("ObCreateObject() failed (Status %lx)\n"); + return(Status); } /* Zero out the buffer */ RtlZeroMemory(AccessToken, sizeof(TOKEN)); - Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(AccessToken); - return NULL; - } - - Status = ExpAllocateLocallyUniqueId(&AccessToken->ModifiedId); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(AccessToken); - return NULL; - } - - Status = ExpAllocateLocallyUniqueId(&AccessToken->AuthenticationId); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(AccessToken); - return NULL; - } - AccessToken->TokenLock = &SepTokenLock; - AccessToken->TokenType = TokenPrimary; - AccessToken->ImpersonationLevel = SecurityDelegation; - memcpy(AccessToken->TokenSource.SourceName, "SeMgr\0\0\0", 8); - AccessToken->ExpirationTime.QuadPart = -1; - AccessToken->UserAndGroupCount = 4; + RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier, + &TokenSource->SourceIdentifier); + memcpy(AccessToken->TokenSource.SourceName, + TokenSource->SourceName, + sizeof(TokenSource->SourceName)); - uSize = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount; - uSize += uLocalSystemLength; - uSize += uWorldLength; - uSize += uAuthUserLength; - uSize += uAdminsLength; + RtlCopyLuid(&AccessToken->TokenId, &TokenId); + RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId); + AccessToken->ExpirationTime = *ExpirationTime; + RtlCopyLuid(&AccessToken->ModifiedId, &ModifiedId); + + AccessToken->UserAndGroupCount = GroupCount + 1; + AccessToken->PrivilegeCount = PrivilegeCount; + + AccessToken->TokenFlags = TokenFlags; + AccessToken->TokenType = TokenType; + AccessToken->ImpersonationLevel = ImpersonationLevel; + + /* + * Normally we would just point these members into the variable information + * area; however, our ObCreateObject() call can't allocate a variable information + * area, so we allocate them seperately and provide a destroy function. + */ + + uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount; + uLength += RtlLengthSid(User); + for (i = 0; i < GroupCount; i++) + uLength += RtlLengthSid(Groups[i].Sid); AccessToken->UserAndGroups = (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, - uSize, + uLength, 'uKOT'); - SidArea = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; + EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; + + Status = RtlCopySidAndAttributesArray(1, + User, + uLength, + AccessToken->UserAndGroups, + EndMem, + &EndMem, + &uLength); + if (NT_SUCCESS(Status)) + { + Status = RtlCopySidAndAttributesArray(GroupCount, + Groups, + uLength, + &AccessToken->UserAndGroups[1], + EndMem, + &EndMem, + &uLength); + } + + if (NT_SUCCESS(Status)) + { + Status = SepFindPrimaryGroupAndDefaultOwner( + AccessToken, + PrimaryGroup, + Owner); + } + + if (NT_SUCCESS(Status)) + { + uLength = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); + AccessToken->Privileges = + (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, + uLength, + 'pKOT'); + + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + RtlCopyMemory(AccessToken->Privileges, + Privileges, + PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + else + { + RtlCopyMemory(AccessToken->Privileges, + Privileges, + PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); + } + } + + if (NT_SUCCESS(Status)) + { + AccessToken->DefaultDacl = + (PACL) ExAllocatePoolWithTag(PagedPool, + DefaultDacl->AclSize, + 'kDOT'); + memcpy(AccessToken->DefaultDacl, + DefaultDacl, + DefaultDacl->AclSize); + } + + if (!SystemToken) + { + + Status = ObInsertObject ((PVOID)AccessToken, + NULL, + DesiredAccess, + 0, + NULL, + TokenHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ObInsertObject() failed (Status %lx)\n", Status); + } + } + else + { + /* Return pointer instead of handle */ + *TokenHandle = (HANDLE)AccessToken; + } + + return Status; +} + +PTOKEN +NTAPI +SepCreateSystemProcessToken(VOID) +{ + LUID_AND_ATTRIBUTES Privileges[25]; + ULONG GroupAttributes, OwnerAttributes; + SID_AND_ATTRIBUTES Groups[32]; + LARGE_INTEGER Expiration; + SID_AND_ATTRIBUTES UserSid; + ULONG GroupLength; + PSID PrimaryGroup; + OBJECT_ATTRIBUTES ObjectAttributes; + PSID Owner; + ULONG i; + PTOKEN Token; + NTSTATUS Status; + + /* Don't ever expire */ + Expiration.QuadPart = -1; + + /* All groups mandatory and enabled */ + GroupAttributes = SE_GROUP_ENABLED | SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT; + OwnerAttributes = SE_GROUP_ENABLED | SE_GROUP_OWNER | SE_GROUP_ENABLED_BY_DEFAULT; + + /* User is system */ + UserSid.Sid = SeLocalSystemSid; + UserSid.Attributes = 0; + + /* Primary group is local system */ + PrimaryGroup = SeLocalSystemSid; + + /* Owner is admins */ + Owner = SeAliasAdminsSid; + + /* Groups are admins, world, and authenticated users */ + Groups[0].Sid = SeAliasAdminsSid; + Groups[0].Attributes = OwnerAttributes; + Groups[1].Sid = SeWorldSid; + Groups[1].Attributes = GroupAttributes; + Groups[2].Sid = SeAuthenticatedUserSid; + Groups[2].Attributes = OwnerAttributes; + GroupLength = sizeof(SID_AND_ATTRIBUTES) + + SeLengthSid(Groups[0].Sid) + + SeLengthSid(Groups[1].Sid) + + SeLengthSid(Groups[2].Sid); + ASSERT(GroupLength <= sizeof(Groups)); + + /* Setup the privileges */ i = 0; - AccessToken->UserAndGroups[i].Sid = (PSID) SidArea; - AccessToken->UserAndGroups[i++].Attributes = 0; - RtlCopySid(uLocalSystemLength, SidArea, SeLocalSystemSid); - SidArea = (char*)SidArea + uLocalSystemLength; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeTcbPrivilege; - AccessToken->DefaultOwnerIndex = i; - AccessToken->UserAndGroups[i].Sid = (PSID) SidArea; - AccessToken->PrimaryGroup = (PSID) SidArea; - AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT; - Status = RtlCopySid(uAdminsLength, SidArea, SeAliasAdminsSid); - SidArea = (char*)SidArea + uAdminsLength; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeCreateTokenPrivilege; - AccessToken->UserAndGroups[i].Sid = (PSID) SidArea; - AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY; - RtlCopySid(uWorldLength, SidArea, SeWorldSid); - SidArea = (char*)SidArea + uWorldLength; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeTakeOwnershipPrivilege; - AccessToken->UserAndGroups[i].Sid = (PSID) SidArea; - AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY; - RtlCopySid(uAuthUserLength, SidArea, SeAuthenticatedUserSid); - SidArea = (char*)SidArea + uAuthUserLength; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeCreatePagefilePrivilege; - AccessToken->PrivilegeCount = 20; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeLockMemoryPrivilege; - uSize = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); - AccessToken->Privileges = - (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, - uSize, - 'pKOT'); + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege; - i = 0; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeTcbPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeIncreaseQuotaPrivilege; - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeCreateTokenPrivilege; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege; - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeTakeOwnershipPrivilege; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeCreatePermanentPrivilege; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeCreatePagefilePrivilege; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeDebugPrivilege; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeLockMemoryPrivilege; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeAuditPrivilege; - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeSecurityPrivilege; - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeIncreaseQuotaPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeSystemEnvironmentPrivilege; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeChangeNotifyPrivilege; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeCreatePermanentPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeBackupPrivilege; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeDebugPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeRestorePrivilege; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeAuditPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeShutdownPrivilege; - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeSecurityPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeLoadDriverPrivilege; - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeSystemEnvironmentPrivilege; - - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeChangeNotifyPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeBackupPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeRestorePrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeShutdownPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeLoadDriverPrivilege; - - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeProfileSingleProcessPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeSystemtimePrivilege; -#if 0 - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeUndockPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeManageVolumePrivilege; -#endif + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeProfileSingleProcessPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeSystemtimePrivilege; ASSERT(i == 20); - uSize = sizeof(ACL); - uSize += sizeof(ACE) + uLocalSystemLength; - uSize += sizeof(ACE) + uAdminsLength; - uSize = (uSize & (~3)) + 8; - AccessToken->DefaultDacl = - (PACL) ExAllocatePoolWithTag(PagedPool, - uSize, - 'kDOT'); - Status = RtlCreateAcl(AccessToken->DefaultDacl, uSize, ACL_REVISION); - if ( NT_SUCCESS(Status) ) - { - Status = RtlAddAccessAllowedAce(AccessToken->DefaultDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - } + /* Setup the object attributes */ + InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); + ASSERT(SeSystemDefaultDacl != NULL); - if ( NT_SUCCESS(Status) ) - { - Status = RtlAddAccessAllowedAce(AccessToken->DefaultDacl, ACL_REVISION, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE|READ_CONTROL, SeAliasAdminsSid); - } + /* Create the token */ + Status = SepCreateToken((PHANDLE)&Token, + KernelMode, + 0, + &ObjectAttributes, + TokenPrimary, + 0, + &SeSystemAuthenticationId, + &Expiration, + &UserSid, + 3, + Groups, + GroupLength, + 20, + Privileges, + Owner, + PrimaryGroup, + SeSystemDefaultDacl, + &SeSystemTokenSource, + TRUE); + ASSERT(Status == STATUS_SUCCESS); - if ( ! NT_SUCCESS(Status) ) - { - ObDereferenceObject(AccessToken); - return NULL; - } - - return AccessToken; + /* Return the token */ + return Token; } /* PUBLIC FUNCTIONS ***********************************************************/ @@ -1920,7 +2068,8 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, return Status; } -NTSTATUS NTAPI +NTSTATUS +NTAPI NtCreateToken(OUT PHANDLE TokenHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, @@ -1936,12 +2085,6 @@ NtCreateToken(OUT PHANDLE TokenHandle, IN PTOKEN_SOURCE TokenSource) { HANDLE hToken; - PTOKEN AccessToken; - LUID TokenId; - LUID ModifiedId; - PVOID EndMem; - ULONG uLength; - ULONG i; KPROCESSOR_MODE PreviousMode; ULONG nTokenPrivileges = 0; LARGE_INTEGER LocalExpirationTime = {{0, 0}}; @@ -1996,148 +2139,25 @@ NtCreateToken(OUT PHANDLE TokenHandle, LocalExpirationTime = *ExpirationTime; } - Status = ZwAllocateLocallyUniqueId(&TokenId); - if (!NT_SUCCESS(Status)) - return(Status); - - Status = ZwAllocateLocallyUniqueId(&ModifiedId); - if (!NT_SUCCESS(Status)) - return(Status); - - Status = ObCreateObject(PreviousMode, - SepTokenObjectType, - ObjectAttributes, + Status = SepCreateToken(&hToken, PreviousMode, - NULL, - sizeof(TOKEN), - 0, - 0, - (PVOID*)&AccessToken); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ObCreateObject() failed (Status %lx)\n"); - return(Status); - } - - /* Zero out the buffer */ - RtlZeroMemory(AccessToken, sizeof(TOKEN)); - - AccessToken->TokenLock = &SepTokenLock; - - RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier, - &TokenSource->SourceIdentifier); - memcpy(AccessToken->TokenSource.SourceName, - TokenSource->SourceName, - sizeof(TokenSource->SourceName)); - - RtlCopyLuid(&AccessToken->TokenId, &TokenId); - RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId); - AccessToken->ExpirationTime = *ExpirationTime; - RtlCopyLuid(&AccessToken->ModifiedId, &ModifiedId); - - AccessToken->UserAndGroupCount = TokenGroups->GroupCount + 1; - AccessToken->PrivilegeCount = TokenPrivileges->PrivilegeCount; - - AccessToken->TokenType = TokenType; - AccessToken->ImpersonationLevel = ((PSECURITY_QUALITY_OF_SERVICE) - (ObjectAttributes->SecurityQualityOfService))->ImpersonationLevel; - - /* - * Normally we would just point these members into the variable information - * area; however, our ObCreateObject() call can't allocate a variable information - * area, so we allocate them seperately and provide a destroy function. - */ - - uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount; - uLength += RtlLengthSid(TokenUser->User.Sid); - for (i = 0; i < TokenGroups->GroupCount; i++) - uLength += RtlLengthSid(TokenGroups->Groups[i].Sid); - - AccessToken->UserAndGroups = - (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, - uLength, - 'uKOT'); - - EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; - - Status = RtlCopySidAndAttributesArray(1, - &TokenUser->User, - uLength, - AccessToken->UserAndGroups, - EndMem, - &EndMem, - &uLength); - if (NT_SUCCESS(Status)) - { - Status = RtlCopySidAndAttributesArray(TokenGroups->GroupCount, - TokenGroups->Groups, - uLength, - &AccessToken->UserAndGroups[1], - EndMem, - &EndMem, - &uLength); - } - - if (NT_SUCCESS(Status)) - { - Status = SepFindPrimaryGroupAndDefaultOwner( - AccessToken, - TokenPrimaryGroup->PrimaryGroup, - TokenOwner->Owner); - } - - if (NT_SUCCESS(Status)) - { - uLength = TokenPrivileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); - AccessToken->Privileges = - (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, - uLength, - 'pKOT'); - - if (PreviousMode != KernelMode) - { - _SEH2_TRY - { - RtlCopyMemory(AccessToken->Privileges, - TokenPrivileges->Privileges, - nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES)); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - } - else - { - RtlCopyMemory(AccessToken->Privileges, - TokenPrivileges->Privileges, - nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES)); - } - } - - if (NT_SUCCESS(Status)) - { - AccessToken->DefaultDacl = - (PACL) ExAllocatePoolWithTag(PagedPool, - TokenDefaultDacl->DefaultDacl->AclSize, - 'kDOT'); - memcpy(AccessToken->DefaultDacl, - TokenDefaultDacl->DefaultDacl, - TokenDefaultDacl->DefaultDacl->AclSize); - } - - Status = ObInsertObject ((PVOID)AccessToken, - NULL, - DesiredAccess, - 0, - NULL, - &hToken); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ObInsertObject() failed (Status %lx)\n", Status); - } - + DesiredAccess, + ObjectAttributes, + TokenType, + ((PSECURITY_QUALITY_OF_SERVICE)(ObjectAttributes->SecurityQualityOfService))->ImpersonationLevel, + AuthenticationId, + &LocalExpirationTime, + &TokenUser->User, + TokenGroups->GroupCount, + TokenGroups->Groups, + 0, // FIXME: Should capture + nTokenPrivileges, + TokenPrivileges->Privileges, + TokenOwner->Owner, + TokenPrimaryGroup->PrimaryGroup, + TokenDefaultDacl->DefaultDacl, + TokenSource, + FALSE); if (NT_SUCCESS(Status)) { _SEH2_TRY @@ -2165,7 +2185,7 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, IN ULONG HandleAttributes, OUT PHANDLE TokenHandle) { - PETHREAD Thread; + PETHREAD Thread, NewThread; HANDLE hToken; PTOKEN Token, NewToken, PrimaryToken; BOOLEAN CopyOnOpen, EffectiveOnly; @@ -2215,12 +2235,11 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, ObDereferenceObject(Thread); return STATUS_NO_TOKEN; } - - ObDereferenceObject(Thread); - + if (ImpersonationLevel == SecurityAnonymous) { - ObDereferenceObject(Token); + PsDereferenceImpersonationToken(Token); + ObDereferenceObject(Thread); return STATUS_CANT_OPEN_ANONYMOUS; } @@ -2236,58 +2255,41 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, if (CopyOnOpen) { Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS, - PsThreadType, PreviousMode, - (PVOID*)&Thread, NULL); - if (!NT_SUCCESS(Status)) + PsThreadType, KernelMode, + (PVOID*)&NewThread, NULL); + if (NT_SUCCESS(Status)) { - ObDereferenceObject(Token); - if (OpenAsSelf) + PrimaryToken = PsReferencePrimaryToken(NewThread->ThreadsProcess); + + Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl); + + ObFastDereferenceObject(&NewThread->ThreadsProcess->Token, PrimaryToken); + + if (NT_SUCCESS(Status)) { - PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); + if (Dacl) + { + RtlCreateSecurityDescriptor(&SecurityDescriptor, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl, + FALSE); + } + + InitializeObjectAttributes(&ObjectAttributes, NULL, HandleAttributes, + NULL, Dacl ? &SecurityDescriptor : NULL); + + + Status = SepDuplicateToken(Token, &ObjectAttributes, EffectiveOnly, + TokenImpersonation, ImpersonationLevel, + KernelMode, &NewToken); + if (NT_SUCCESS(Status)) + { + ObReferenceObject(NewToken); + Status = ObInsertObject(NewToken, NULL, DesiredAccess, 0, NULL, + &hToken); + } } - return Status; } - - PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess); - Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl); - ASSERT(FALSE); - ObDereferenceObject(PrimaryToken); - ObDereferenceObject(Thread); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(Token); - if (OpenAsSelf) - { - PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); - } - return Status; - } - - RtlCreateSecurityDescriptor(&SecurityDescriptor, - SECURITY_DESCRIPTOR_REVISION); - RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl, - FALSE); - - InitializeObjectAttributes(&ObjectAttributes, NULL, HandleAttributes, - NULL, &SecurityDescriptor); - - Status = SepDuplicateToken(Token, &ObjectAttributes, EffectiveOnly, - TokenImpersonation, ImpersonationLevel, - KernelMode, &NewToken); - ExFreePool(Dacl); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(Token); - if (OpenAsSelf) - { - PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); - } - return Status; - } - - Status = ObInsertObject(NewToken, NULL, DesiredAccess, 0, NULL, - &hToken); - } else { @@ -2296,13 +2298,24 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, PreviousMode, &hToken); } - ObDereferenceObject(Token); + if (Dacl) ExFreePool(Dacl); if (OpenAsSelf) { PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); } + ObDereferenceObject(Token); + + if (NT_SUCCESS(Status) && CopyOnOpen) + { + PsImpersonateClient(Thread, NewToken, FALSE, EffectiveOnly, ImpersonationLevel); + } + + if (NewToken) ObDereferenceObject(NewToken); + + if (CopyOnOpen && NewThread) ObDereferenceObject(NewThread); + if(NT_SUCCESS(Status)) { _SEH2_TRY diff --git a/reactos/subsystems/csr/csrsrv/process.c b/reactos/subsystems/csr/csrsrv/process.c index c26a6c1d94e..1de2286b549 100644 --- a/reactos/subsystems/csr/csrsrv/process.c +++ b/reactos/subsystems/csr/csrsrv/process.c @@ -916,7 +916,7 @@ CsrGetProcessLuid(HANDLE hProcess OPTIONAL, /* Now query the information */ Status = NtQueryInformationToken(hToken, TokenStatistics, - &TokenStats, + TokenStats, Length, &Length); From f316f00072afbd0c35de094463c88e5f0a45ab52 Mon Sep 17 00:00:00 2001 From: Sylvain Petreolle Date: Tue, 9 Mar 2010 17:21:29 +0000 Subject: [PATCH 06/64] Convert battery.inf to UTF-16 Add French translation. Add battery.inf and fdc.inf to syssetup process. Floppy disk controllers and batteries now appear correctly in device manager. Dedicated to aicom ;) svn path=/trunk/; revision=46038 --- reactos/media/inf/battery.inf | Bin 1078 -> 2574 bytes reactos/media/inf/inf.rbuild | 4 +++- reactos/media/inf/syssetup.inf.tpl | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/reactos/media/inf/battery.inf b/reactos/media/inf/battery.inf index 9ac8d8995e5707d475ed1e6ecc3d881818cef6f7..33a8fb887a2bd0511ffb4e0c71a8c4d1e750e0bf 100644 GIT binary patch literal 2574 zcmbuATTc^F5Xa}aiQi$FHjmh?33O%Q-XipZU*audh}lkczCz9@m=e$VZ8!E?crL52RpgU*1Ve1~Qbk^rS0? zw!6#M8DGaTk_%2-*a_qXt0)iUJ*Qo1BL5Y=0DF7v7ENzrplahdI4u6 zB61o|#-Wu!N^B*LY*kj1kYCCx zaOXhv%U8gxr!p5vn5&G$yDj27hn0|?SRv1K`5>Fr!*jHp#{qmctUm(zgrs&v;{PW4 zUD#EQwX$8u3?}S{vVnBhwA9Kba%W&U=4YKHmS>$F;$?_mRoTYV1MXX_m~XAj$nvWd z*Z|Sxx-mto5~pW-?vFMUKaJqAwB}=~;Qui4Rtli(<8|VZ%WV~&`%D8r2Xw+{N2Dc> z_{vM&v^Psi*=vA#Las(!5%oQ06{b6l)Sfbt^)X^2xQ~iuHC4jXNu`N8Ej4NoG{ZYI@iDeZV~{;V09ANv*+w&bonR zqKmYCbhjXRNTvU&@7k6qPd0AsPyx1Bj%xG2N=8SMarDUSk-iMFVNR|0H@Lu=b z@vFPu;NHLMxo$*yK{y%o2=RSFf78*{bUuNSs7>F@X$^t(#!5aP0F zY#59HR_lQkOz>p3-B}>4vl?(`u94-3i|Ny1z91p-oroQI!l3I!rG>eYU|%ADx-r!s zA*BDGj1vT*$Ce0mh2_3hJ5Zh3H)q!w*SXdx$-jXFr>ZNYE=hBPg=`s}6%$IZni#x^ zwt%}$voZMrBGvJ1-OWaWHhPF%)vLf7X-8b|VcCJyh3%JANbOLrzJbO - audio.inf acpi.inf + audio.inf + battery.inf cdrom.inf display.inf + fdc.inf font.inf hdc.inf intl.inf diff --git a/reactos/media/inf/syssetup.inf.tpl b/reactos/media/inf/syssetup.inf.tpl index 6aaa0a2141c..f1c7ff67ce6 100644 --- a/reactos/media/inf/syssetup.inf.tpl +++ b/reactos/media/inf/syssetup.inf.tpl @@ -14,8 +14,10 @@ ClassGUID={00000000-0000-0000-0000-000000000000} [DeviceInfsToInstall] ; MS uses netnovel.inf as class-installer INF for NICs ; we use a separate one to keep things clean +battery.inf cdrom.inf display.inf +fdc.inf hdc.inf keyboard.inf machine.inf From 9c91a4dc4619cc9b0de1a898c797a449bd79c524 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Tue, 9 Mar 2010 18:22:25 +0000 Subject: [PATCH 07/64] [CSRSS]: Fix yet another bug in the unused csrss code. svn path=/trunk/; revision=46040 --- reactos/subsystems/csr/csrsrv/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/subsystems/csr/csrsrv/thread.c b/reactos/subsystems/csr/csrsrv/thread.c index ca7c632e8af..ad71435589c 100644 --- a/reactos/subsystems/csr/csrsrv/thread.c +++ b/reactos/subsystems/csr/csrsrv/thread.c @@ -157,7 +157,7 @@ CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL, NextEntry = ListHead->Flink; /* Start the Loop */ - while (NextEntry != NextEntry) + while (NextEntry != ListHead) { /* Get Thread Entry */ FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link); From e2d31e88e40eb0c191b1a3a9c06f7562b7e8b035 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Tue, 9 Mar 2010 20:13:19 +0000 Subject: [PATCH 08/64] [KERNEL32]: Bug fix CTRL-C handler registration/deregistration/notification, needed for correct console shutdown behavior. svn path=/trunk/; revision=46041 --- reactos/dll/win32/kernel32/misc/console.c | 180 +++++++++++++--------- reactos/dll/win32/kernel32/misc/dllmain.c | 10 +- 2 files changed, 111 insertions(+), 79 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/console.c b/reactos/dll/win32/kernel32/misc/console.c index 6e6f57c1ddf..13961ad6631 100644 --- a/reactos/dll/win32/kernel32/misc/console.c +++ b/reactos/dll/win32/kernel32/misc/console.c @@ -19,16 +19,17 @@ #define NDEBUG #include -extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event); -extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag); extern RTL_CRITICAL_SECTION ConsoleLock; extern BOOL ConsoleInitialized; extern BOOL WINAPI IsDebuggerPresent(VOID); /* GLOBALS *******************************************************************/ -static PHANDLER_ROUTINE* CtrlHandlers = NULL; -static ULONG NrCtrlHandlers = 0; +PHANDLER_ROUTINE InitialHandler[1]; +PHANDLER_ROUTINE* CtrlHandlers; +ULONG NrCtrlHandlers; +ULONG NrAllocatedHandlers; + #define INPUTEXENAME_BUFLEN 256 static WCHAR InputExeName[INPUTEXENAME_BUFLEN] = L""; @@ -49,7 +50,7 @@ DefaultConsoleCtrlHandler(DWORD Event) break; case CTRL_SHUTDOWN_EVENT: - DPRINT("Ctrl Shutdown Event\n"); + DPRINT1("Ctrl Shutdown Event\n"); break; case CTRL_CLOSE_EVENT: @@ -57,15 +58,14 @@ DefaultConsoleCtrlHandler(DWORD Event) break; case CTRL_LOGOFF_EVENT: - DPRINT("Ctrl Logoff Event\n"); + DPRINT1("Ctrl Logoff Event\n"); break; } - ExitProcess(0); + ExitProcess(CONTROL_C_EXIT); return TRUE; } - __declspec(noreturn) VOID CALLBACK @@ -74,7 +74,8 @@ ConsoleControlDispatcher(DWORD CodeAndFlag) DWORD nExitCode = 0; DWORD nCode = CodeAndFlag & MAXLONG; UINT i; - + EXCEPTION_RECORD erException; + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); switch(nCode) @@ -82,51 +83,77 @@ ConsoleControlDispatcher(DWORD CodeAndFlag) case CTRL_C_EVENT: case CTRL_BREAK_EVENT: { - if(IsDebuggerPresent()) + if (IsDebuggerPresent()) { - EXCEPTION_RECORD erException; - erException.ExceptionCode = - (nCode == CTRL_C_EVENT ? DBG_CONTROL_C : DBG_CONTROL_BREAK); + erException.ExceptionCode = (nCode == CTRL_C_EVENT ? + DBG_CONTROL_C : DBG_CONTROL_BREAK); erException.ExceptionFlags = 0; erException.ExceptionRecord = NULL; - erException.ExceptionAddress = &DefaultConsoleCtrlHandler; + erException.ExceptionAddress = DefaultConsoleCtrlHandler; erException.NumberParameters = 0; - RtlRaiseException(&erException); + + _SEH2_TRY + { + RtlRaiseException(&erException); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + RtlEnterCriticalSection(&ConsoleLock); + + if ((nCode != CTRL_C_EVENT) || + (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1)) + { + for (i = NrCtrlHandlers; i > 0; i--) + { + if (CtrlHandlers[i - 1](nCode)) break; + } + } + + RtlLeaveCriticalSection(&ConsoleLock); + } + _SEH2_END; + + ExitThread(0); } - - if (!ConsoleInitialized) ExitThread(0); - RtlEnterCriticalSection(&ConsoleLock); - - if (!(nCode == CTRL_C_EVENT && - NtCurrentPeb()->ProcessParameters->ConsoleFlags & 1)) - { - for(i = NrCtrlHandlers; i > 0; -- i) - if(CtrlHandlers[i - 1](nCode)) break; - } - RtlLeaveCriticalSection(&ConsoleLock); - ExitThread(0); + + break; } case CTRL_CLOSE_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: break; + + case 3: + + ExitThread(0); + break; + + case 4: + + ExitProcess(CONTROL_C_EXIT); + break; - default: ExitThread(0); + default: + + ASSERT(FALSE); + break; } - - if (!ConsoleInitialized) ExitThread(0); + + ASSERT(ConsoleInitialized); + RtlEnterCriticalSection(&ConsoleLock); - - if (!(nCode == CTRL_C_EVENT && - NtCurrentPeb()->ProcessParameters->ConsoleFlags & 1)) + nExitCode = 0; + if ((nCode != CTRL_C_EVENT) || (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1)) { - i = NrCtrlHandlers; - while (i > 0) + for (i = NrCtrlHandlers; i > 0; i--) { - if (i == 1 && (CodeAndFlag & MINLONG) && - (nCode == CTRL_LOGOFF_EVENT || nCode == CTRL_SHUTDOWN_EVENT)) + if ((i == 1) && + (CodeAndFlag & MINLONG) && + ((nCode == CTRL_LOGOFF_EVENT) || (nCode == CTRL_SHUTDOWN_EVENT))) + { break; + } if (CtrlHandlers[i - 1](nCode)) { @@ -135,14 +162,17 @@ ConsoleControlDispatcher(DWORD CodeAndFlag) case CTRL_CLOSE_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: + case 3: nExitCode = CodeAndFlag; + break; } break; } - --i; } } + RtlLeaveCriticalSection(&ConsoleLock); + ExitThread(nExitCode); } @@ -3235,38 +3265,37 @@ static BOOL AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine) { + PHANDLER_ROUTINE* NewCtrlHandlers = NULL; + if (HandlerRoutine == NULL) { NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE; - return(TRUE); + return TRUE; } - else + + if (NrCtrlHandlers == NrAllocatedHandlers) { - NrCtrlHandlers++; - if (CtrlHandlers == NULL) + NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE)); + if (NewCtrlHandlers == NULL) { - CtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - NrCtrlHandlers * sizeof(PHANDLER_ROUTINE)); - } - else - { - CtrlHandlers = RtlReAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - (PVOID)CtrlHandlers, - NrCtrlHandlers * sizeof(PHANDLER_ROUTINE)); - } - - if (CtrlHandlers == NULL) - { - NrCtrlHandlers = 0; SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - - CtrlHandlers[NrCtrlHandlers - 1] = HandlerRoutine; - return TRUE; + + memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers); + + if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers); + + CtrlHandlers = NewCtrlHandlers; + NrAllocatedHandlers += 4; } + + ASSERT(NrCtrlHandlers < NrAllocatedHandlers); + + CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine; + return TRUE; } @@ -3279,30 +3308,27 @@ RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine) if (HandlerRoutine == NULL) { NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE; - return(TRUE); + return TRUE; } - else - { - for (i = 0; i < NrCtrlHandlers; i++) - { - if ( ((void*)(CtrlHandlers[i])) == (void*)HandlerRoutine) - { - NrCtrlHandlers--; - memmove(CtrlHandlers + i, - CtrlHandlers + i + 1, - (NrCtrlHandlers - i) * sizeof(PHANDLER_ROUTINE)); - CtrlHandlers = RtlReAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - (PVOID)CtrlHandlers, - NrCtrlHandlers * sizeof(PHANDLER_ROUTINE)); - return(TRUE); + for (i = 0; i < NrCtrlHandlers; i++) + { + if (CtrlHandlers[i] == HandlerRoutine) + { + if (i < (NrCtrlHandlers - 1)) + { + memmove(&CtrlHandlers[i], + &CtrlHandlers[i+1], + (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE)); } + + NrCtrlHandlers--; + return TRUE; } } SetLastError(ERROR_INVALID_PARAMETER); - return(FALSE); + return FALSE; } diff --git a/reactos/dll/win32/kernel32/misc/dllmain.c b/reactos/dll/win32/kernel32/misc/dllmain.c index 5f9f0cb4148..7d08667205b 100644 --- a/reactos/dll/win32/kernel32/misc/dllmain.c +++ b/reactos/dll/win32/kernel32/misc/dllmain.c @@ -41,7 +41,10 @@ RTL_CRITICAL_SECTION ConsoleLock; extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event); extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag); - +extern PHANDLER_ROUTINE InitialHandler[1]; +extern PHANDLER_ROUTINE* CtrlHandlers; +extern ULONG NrCtrlHandlers; +extern ULONG NrAllocatedHandlers; extern BOOL FASTCALL NlsInit(VOID); extern VOID FASTCALL NlsUninit(VOID); BOOLEAN InWindows = FALSE; @@ -178,7 +181,10 @@ BasepInitConsole(VOID) /* Initialize Console Ctrl Handler */ ConsoleInitialized = TRUE; RtlInitializeCriticalSection(&ConsoleLock); - SetConsoleCtrlHandler(DefaultConsoleCtrlHandler, TRUE); + NrAllocatedHandlers = 1; + NrCtrlHandlers = 1; + CtrlHandlers = InitialHandler; + CtrlHandlers[0] = DefaultConsoleCtrlHandler; /* Now use the proper console handle */ Request.Data.AllocConsoleRequest.Console = Parameters->ConsoleHandle; From 4f05a88e825b5392994573d9085a0266514a170c Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Tue, 9 Mar 2010 20:23:22 +0000 Subject: [PATCH 09/64] [KERNEL32/CSRSS]: Register new Win32 threads with CSRSS. Add a bunch of lookup, creation, allocation, hashing and CSR thread management routines from the unused CSRSRV in trunk. [CSRSS]: Bang in the new thread support in a bunch of places, including creating static server threads. It's very hacked and handle duplication doesn't work 100% reliably, but it gets the job done. [CSRSS]: Add CsrGetProcessLuid, CsrImpersonateClient, CsrRevertToSelf, CsrShutdownProcesses, CsrFindProcessForShutdown required for user-mode shutdown. Right now we are able to reliably enumerate user apps (in the user LUID) and then service/system apps (in the LOCAL SYSTEM LUID). svn path=/trunk/; revision=46042 --- reactos/dll/win32/kernel32/process/procsup.c | 65 +- reactos/dll/win32/kernel32/thread/thread.c | 14 +- reactos/include/reactos/subsys/csrss/csrss.h | 8 + reactos/subsystems/win32/csrss/api/process.c | 715 ++++++++++++++++++- reactos/subsystems/win32/csrss/api/wapi.c | 77 +- reactos/subsystems/win32/csrss/include/api.h | 46 +- reactos/subsystems/win32/csrss/init.c | 17 +- 7 files changed, 899 insertions(+), 43 deletions(-) diff --git a/reactos/dll/win32/kernel32/process/procsup.c b/reactos/dll/win32/kernel32/process/procsup.c index 06b07471aa2..274d882da45 100644 --- a/reactos/dll/win32/kernel32/process/procsup.c +++ b/reactos/dll/win32/kernel32/process/procsup.c @@ -110,7 +110,38 @@ BasepNotifyCsrOfCreation(ULONG dwCreationFlags, return CsrRequest.Status; } - /* REturn Success */ + /* Return Success */ + return STATUS_SUCCESS; +} + +NTSTATUS +WINAPI +BasepNotifyCsrOfThread(IN HANDLE ThreadHandle, + IN PCLIENT_ID ClientId) +{ + ULONG Request = CREATE_THREAD; + CSR_API_MESSAGE CsrRequest; + NTSTATUS Status; + + DPRINT("BasepNotifyCsrOfThread: Thread: %lx, Handle %lx\n", + ClientId->UniqueThread, ThreadHandle); + + /* Fill out the request */ + CsrRequest.Data.CreateThreadRequest.ClientId = *ClientId; + CsrRequest.Data.CreateThreadRequest.ThreadHandle = ThreadHandle; + + /* Call CSR */ + Status = CsrClientCallServer(&CsrRequest, + NULL, + MAKE_CSR_API(Request, CSR_NATIVE), + sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status)) + { + DPRINT1("Failed to tell csrss about new thread\n"); + return CsrRequest.Status; + } + + /* Return Success */ return STATUS_SUCCESS; } @@ -164,7 +195,13 @@ BasepCreateFirstThread(HANDLE ProcessHandle, { return NULL; } - + + Status = BasepNotifyCsrOfThread(hThread, ClientId); + if (!NT_SUCCESS(Status)) + { + ASSERT(FALSE); + } + /* Success */ return hThread; } @@ -1375,6 +1412,18 @@ GetAppName: &RemoteParameters->StandardError); } + /* Notify CSRSS */ + Status = BasepNotifyCsrOfCreation(dwCreationFlags, + (HANDLE)ProcessBasicInfo.UniqueProcessId, + bInheritHandles); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSR Notification Failed"); + SetLastErrorByStatus(Status); + goto Cleanup; + } + /* Create the first thread */ DPRINT("Creating thread for process (EntryPoint = 0x%p)\n", SectionImageInfo.TransferAddress); @@ -1390,18 +1439,6 @@ GetAppName: goto Cleanup; } - /* Notify CSRSS */ - Status = BasepNotifyCsrOfCreation(dwCreationFlags, - (HANDLE)ProcessBasicInfo.UniqueProcessId, - bInheritHandles); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSR Notification Failed"); - SetLastErrorByStatus(Status); - goto Cleanup; - } - if (!(dwCreationFlags & CREATE_SUSPENDED)) { NtResumeThread(hThread, &Dummy); diff --git a/reactos/dll/win32/kernel32/thread/thread.c b/reactos/dll/win32/kernel32/thread/thread.c index 277b36c56c0..98940d59ff2 100644 --- a/reactos/dll/win32/kernel32/thread/thread.c +++ b/reactos/dll/win32/kernel32/thread/thread.c @@ -19,6 +19,11 @@ #define HIGH_PRIORITY 31 #define SXS_SUPPORT_FIXME +NTSTATUS +WINAPI +BasepNotifyCsrOfThread(IN HANDLE ThreadHandle, + IN PCLIENT_ID ClientId); + /* FUNCTIONS *****************************************************************/ static LONG BaseThreadExceptionFilter(EXCEPTION_POINTERS * ExceptionInfo) @@ -219,8 +224,13 @@ CreateRemoteThread(HANDLE hProcess, DPRINT1("RtlAllocateActivationContextStack failed %x\n", Status); } - /* FIXME: Notify CSR */ - + /* Notify CSR */ + Status = BasepNotifyCsrOfThread(hThread, &ClientId); + if (!NT_SUCCESS(Status)) + { + ASSERT(FALSE); + } + /* Success */ if(lpThreadId) *lpThreadId = (DWORD)ClientId.UniqueThread; diff --git a/reactos/include/reactos/subsys/csrss/csrss.h b/reactos/include/reactos/subsys/csrss/csrss.h index b23bf0c29e2..1f276fa16d9 100644 --- a/reactos/include/reactos/subsys/csrss/csrss.h +++ b/reactos/include/reactos/subsys/csrss/csrss.h @@ -38,6 +38,12 @@ typedef struct BOOL bInheritHandles; } CSRSS_CREATE_PROCESS, *PCSRSS_CREATE_PROCESS; +typedef struct +{ + CLIENT_ID ClientId; + HANDLE ThreadHandle; +} CSRSS_CREATE_THREAD, *PCSRSS_CREATE_THREAD; + typedef struct { ULONG Dummy; @@ -544,6 +550,7 @@ typedef struct #define GET_CONSOLE_ALIASES_EXES (0x3C) #define GET_CONSOLE_ALIASES_EXES_LENGTH (0x3D) #define GENERATE_CTRL_EVENT (0x3E) +#define CREATE_THREAD (0x3F) /* Keep in sync with definition below. */ #define CSRSS_HEADER_SIZE (sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS)) @@ -557,6 +564,7 @@ typedef struct _CSR_API_MESSAGE union { CSRSS_CREATE_PROCESS CreateProcessRequest; + CSRSS_CREATE_THREAD CreateThreadRequest; CSRSS_CONNECT_PROCESS ConnectRequest; CSRSS_WRITE_CONSOLE WriteConsoleRequest; CSRSS_READ_CONSOLE ReadConsoleRequest; diff --git a/reactos/subsystems/win32/csrss/api/process.c b/reactos/subsystems/win32/csrss/api/process.c index 1537f655ba1..1be6bdc1b00 100644 --- a/reactos/subsystems/win32/csrss/api/process.c +++ b/reactos/subsystems/win32/csrss/api/process.c @@ -24,11 +24,241 @@ RTL_CRITICAL_SECTION ProcessDataLock; /* FUNCTIONS *****************************************************************/ +#define CsrHeap RtlGetProcessHeap() + +#define CsrHashThread(t) \ + (HandleToUlong(t)&(256 - 1)) + +LIST_ENTRY CsrThreadHashTable[256]; +PCSRSS_PROCESS_DATA CsrRootProcess; + +PCSR_THREAD +NTAPI +CsrAllocateThread(IN PCSRSS_PROCESS_DATA CsrProcess) +{ + PCSR_THREAD CsrThread; + + /* Allocate the structure */ + CsrThread = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, sizeof(CSR_THREAD)); + if (!CsrThread) return(NULL); + + /* Reference the Thread and Process */ + CsrThread->ReferenceCount++; + // CsrProcess->ReferenceCount++; + + /* Set the Parent Process */ + CsrThread->Process = CsrProcess; + + /* Return Thread */ + return CsrThread; +} + +PCSR_THREAD +NTAPI +CsrLocateThreadByClientId(OUT PCSRSS_PROCESS_DATA *Process OPTIONAL, + IN PCLIENT_ID ClientId) +{ + ULONG i; + PLIST_ENTRY ListHead, NextEntry; + PCSR_THREAD FoundThread; + + /* Hash the Thread */ + i = CsrHashThread(ClientId->UniqueThread); + + /* Set the list pointers */ + ListHead = &CsrThreadHashTable[i]; + NextEntry = ListHead->Flink; + + /* Star the loop */ + while (NextEntry != ListHead) + { + /* Get the thread */ + FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks); + + /* Compare the CID */ + if (FoundThread->ClientId.UniqueThread == ClientId->UniqueThread) + { + /* Match found, return the process */ + *Process = FoundThread->Process; + + /* Return thread too */ +// DPRINT1("Found: %p %p\n", FoundThread, FoundThread->Process); + return FoundThread; + } + + /* Next */ + NextEntry = NextEntry->Flink; + } + + /* Nothing found */ + return NULL; +} + +PCSR_THREAD +NTAPI +CsrLocateThreadInProcess(IN PCSRSS_PROCESS_DATA CsrProcess OPTIONAL, + IN PCLIENT_ID Cid) +{ + PLIST_ENTRY ListHead, NextEntry; + PCSR_THREAD FoundThread = NULL; + + /* Use the Root Process if none was specified */ + if (!CsrProcess) CsrProcess = CsrRootProcess; + + /* Save the List pointers */ +// DPRINT1("Searching in: %p %d\n", CsrProcess, CsrProcess->ThreadCount); + ListHead = &CsrProcess->ThreadList; + NextEntry = ListHead->Flink; + + /* Start the Loop */ + while (NextEntry != ListHead) + { + /* Get Thread Entry */ + FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link); + + /* Check for TID Match */ + if (FoundThread->ClientId.UniqueThread == Cid->UniqueThread) break; + + /* Next entry */ + NextEntry = NextEntry->Flink; + } + + /* Return what we found */ +// DPRINT1("Found: %p\n", FoundThread); + return FoundThread; +} + +VOID +NTAPI +CsrInsertThread(IN PCSRSS_PROCESS_DATA Process, + IN PCSR_THREAD Thread) +{ + ULONG i; + + /* Insert it into the Regular List */ + InsertTailList(&Process->ThreadList, &Thread->Link); + + /* Increase Thread Count */ + Process->ThreadCount++; + + /* Hash the Thread */ + i = CsrHashThread(Thread->ClientId.UniqueThread); +// DPRINT1("TID %lx HASH: %lx\n", Thread->ClientId.UniqueThread, i); + + /* Insert it there too */ + InsertHeadList(&CsrThreadHashTable[i], &Thread->HashLinks); +} + + +#define CsrAcquireProcessLock() LOCK +#define CsrReleaseProcessLock() UNLOCK + +NTSTATUS +NTAPI +CsrCreateThreadData(IN PCSRSS_PROCESS_DATA CsrProcess, + IN HANDLE hThread, + IN PCLIENT_ID ClientId) +{ + NTSTATUS Status; + PCSR_THREAD CsrThread; + //PCSRSS_PROCESS_DATA CurrentProcess; + PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; + CLIENT_ID CurrentCid; + KERNEL_USER_TIMES KernelTimes; + +// DPRINT1("CSRSRV: %s called\n", __FUNCTION__); + + /* Get the current thread and CID */ + CurrentCid = CurrentThread->ClientId; +// DPRINT1("CALLER PID/TID: %lx/%lx\n", CurrentCid.UniqueProcess, CurrentCid.UniqueThread); + + /* Acquire the Process Lock */ + CsrAcquireProcessLock(); +#if 0 + /* Get the current Process and make sure the Thread is valid with this CID */ + CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, + &CurrentCid); + + /* Something is wrong if we get an empty thread back */ + if (!CurrentThread) + { + DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__); + CsrReleaseProcessLock(); + return STATUS_THREAD_IS_TERMINATING; + } +#endif + /* Get the Thread Create Time */ + Status = NtQueryInformationThread(hThread, + ThreadTimes, + (PVOID)&KernelTimes, + sizeof(KernelTimes), + NULL); + + /* Allocate a CSR Thread Structure */ + if (!(CsrThread = CsrAllocateThread(CsrProcess))) + { + DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__); + CsrReleaseProcessLock(); + return STATUS_NO_MEMORY; + } + + /* Save the data we have */ + CsrThread->CreateTime = KernelTimes.CreateTime; + CsrThread->ClientId = *ClientId; + CsrThread->ThreadHandle = hThread; + CsrThread->Flags = 0; + + /* Insert the Thread into the Process */ + CsrInsertThread(CsrProcess, CsrThread); + + /* Release the lock and return */ + CsrReleaseProcessLock(); + return STATUS_SUCCESS; +} + +PCSR_THREAD +NTAPI +CsrAddStaticServerThread(IN HANDLE hThread, + IN PCLIENT_ID ClientId, + IN ULONG ThreadFlags) +{ + PCSR_THREAD CsrThread; + + /* Get the Lock */ + CsrAcquireProcessLock(); + + /* Allocate the Server Thread */ + if ((CsrThread = CsrAllocateThread(CsrRootProcess))) + { + /* Setup the Object */ +// DPRINT1("New CSR thread created: %lx PID/TID: %lx/%lx\n", CsrThread, ClientId->UniqueProcess, ClientId->UniqueThread); + CsrThread->ThreadHandle = hThread; + CsrThread->ClientId = *ClientId; + CsrThread->Flags = ThreadFlags; + + /* Insert it into the Thread List */ + InsertTailList(&CsrRootProcess->ThreadList, &CsrThread->Link); + + /* Increment the thread count */ + CsrRootProcess->ThreadCount++; + } + + /* Release the Process Lock and return */ + CsrReleaseProcessLock(); + return CsrThread; +} + VOID WINAPI CsrInitProcessData(VOID) { + ULONG i; RtlZeroMemory (ProcessData, sizeof ProcessData); NrProcess = sizeof ProcessData / sizeof ProcessData[0]; RtlInitializeCriticalSection( &ProcessDataLock ); + + CsrRootProcess = CsrCreateProcessData(NtCurrentTeb()->ClientId.UniqueProcess); + + /* Initialize the Thread Hash List */ + for (i = 0; i < 256; i++) InitializeListHead(&CsrThreadHashTable[i]); } PCSRSS_PROCESS_DATA WINAPI CsrGetProcessData(HANDLE ProcessId) @@ -89,8 +319,7 @@ PCSRSS_PROCESS_DATA WINAPI CsrCreateProcessData(HANDLE ProcessId) /* using OpenProcess is not optimal due to HANDLE vs. DWORD PIDs... */ Status = NtOpenProcess(&pProcessData->Process, - PROCESS_DUP_HANDLE | PROCESS_VM_OPERATION | - PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | SYNCHRONIZE, + PROCESS_ALL_ACCESS, &ObjectAttributes, &ClientId); if (!NT_SUCCESS(Status)) @@ -122,6 +351,9 @@ PCSRSS_PROCESS_DATA WINAPI CsrCreateProcessData(HANDLE ProcessId) pProcessData->ShutdownLevel = 0x280; pProcessData->ShutdownFlags = 0; } + + pProcessData->ThreadCount = 0; + InitializeListHead(&pProcessData->ThreadList); return pProcessData; } @@ -186,33 +418,406 @@ NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid) return STATUS_INVALID_PARAMETER; } -NTSTATUS WINAPI -CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context) +VOID +NTAPI +CsrSetToNormalPriority(VOID) { - UINT Hash; - PCSRSS_PROCESS_DATA pProcessData; - NTSTATUS Status = STATUS_SUCCESS; + KPRIORITY BasePriority = (8 + 1) + 4; - LOCK; + /* Set the Priority */ + NtSetInformationProcess(NtCurrentProcess(), + ProcessBasePriority, + &BasePriority, + sizeof(KPRIORITY)); +} - for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++) +VOID +NTAPI +CsrSetToShutdownPriority(VOID) +{ + KPRIORITY SetBasePriority = (8 + 1) + 6; + BOOLEAN Old; + + /* Get the shutdown privilege */ + if (NT_SUCCESS(RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, + TRUE, + FALSE, + &Old))) { - pProcessData = ProcessData[Hash]; - while (NULL != pProcessData) + /* Set the Priority */ + NtSetInformationProcess(NtCurrentProcess(), + ProcessBasePriority, + &SetBasePriority, + sizeof(KPRIORITY)); + } +} + +NTSTATUS +NTAPI +CsrGetProcessLuid(HANDLE hProcess OPTIONAL, + PLUID Luid) +{ + HANDLE hToken = NULL; + NTSTATUS Status; + ULONG Length; + PTOKEN_STATISTICS TokenStats; + + /* Check if we have a handle to a CSR Process */ + if (!hProcess) + { + /* We don't, so try opening the Thread's Token */ + Status = NtOpenThreadToken(NtCurrentThread(), + TOKEN_QUERY, + FALSE, + &hToken); + + /* Check for success */ + if (!NT_SUCCESS(Status)) { - Status = EnumProc(pProcessData, Context); - if (STATUS_SUCCESS != Status) - { - UNLOCK; - return Status; - } - pProcessData = pProcessData->next; + /* If we got some other failure, then return and quit */ + if (Status != STATUS_NO_TOKEN) return Status; + + /* We don't have a Thread Token, use a Process Token */ + hProcess = NtCurrentProcess(); + hToken = NULL; } } - UNLOCK; + /* Check if we have a token by now */ + if (!hToken) + { + /* No token yet, so open the Process Token */ + Status = NtOpenProcessToken(hProcess, + TOKEN_QUERY, + &hToken); + if (!NT_SUCCESS(Status)) + { + /* Still no token, return the error */ + return Status; + } + } - return Status; + /* Now get the size we'll need for the Token Information */ + Status = NtQueryInformationToken(hToken, + TokenStatistics, + NULL, + 0, + &Length); + + /* Allocate memory for the Token Info */ + if (!(TokenStats = RtlAllocateHeap(CsrHeap, 0, Length))) + { + /* Fail and close the token */ + NtClose(hToken); + return STATUS_NO_MEMORY; + } + + /* Now query the information */ + Status = NtQueryInformationToken(hToken, + TokenStatistics, + TokenStats, + Length, + &Length); + + /* Close the handle */ + NtClose(hToken); + + /* Check for success */ + if (NT_SUCCESS(Status)) + { + /* Return the LUID */ + *Luid = TokenStats->AuthenticationId; + } + + /* Free the query information */ + RtlFreeHeap(CsrHeap, 0, TokenStats); + + /* Return the Status */ + return Status; +} + +SECURITY_QUALITY_OF_SERVICE CsrSecurityQos = +{ + sizeof(SECURITY_QUALITY_OF_SERVICE), + SecurityImpersonation, + SECURITY_STATIC_TRACKING, + FALSE +}; + +BOOLEAN +NTAPI +CsrImpersonateClient(IN PCSR_THREAD CsrThread) +{ + NTSTATUS Status; + PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; + + /* Use the current thread if none given */ + if (!CsrThread) CsrThread = CurrentThread; + + /* Still no thread, something is wrong */ + if (!CsrThread) + { + /* Failure */ + return FALSE; + } + + /* Make the call */ + Status = NtImpersonateThread(NtCurrentThread(), + CsrThread->ThreadHandle, + &CsrSecurityQos); + + if (!NT_SUCCESS(Status)) + { + /* Failure */ + return FALSE; + } + + /* Increase the impersonation count for the current thread */ + if (CurrentThread) ++CurrentThread->ImpersonationCount; + + /* Return Success */ + return TRUE; +} + +BOOLEAN +NTAPI +CsrRevertToSelf(VOID) +{ + NTSTATUS Status; + PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; + HANDLE ImpersonationToken = NULL; + + /* Check if we have a Current Thread */ + if (CurrentThread) + { + /* Make sure impersonation is on */ + if (!CurrentThread->ImpersonationCount) + { + return FALSE; + } + else if (--CurrentThread->ImpersonationCount > 0) + { + /* Success; impersonation count decreased but still not zero */ + return TRUE; + } + } + + /* Impersonation has been totally removed, revert to ourselves */ + Status = NtSetInformationThread(NtCurrentThread(), + ThreadImpersonationToken, + &ImpersonationToken, + sizeof(HANDLE)); + + /* Return TRUE or FALSE */ + return NT_SUCCESS(Status); +} + +PCSRSS_PROCESS_DATA +NTAPI +FindProcessForShutdown(IN PLUID CallerLuid) +{ + ULONG Hash; + PCSRSS_PROCESS_DATA CsrProcess, ReturnCsrProcess = NULL; + NTSTATUS Status; + ULONG Level = 0; + LUID ProcessLuid; + LUID SystemLuid = SYSTEM_LUID; + BOOLEAN IsSystemLuid = FALSE, IsOurLuid = FALSE; + + for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++) + { + /* Get this process hash bucket */ + CsrProcess = ProcessData[Hash]; + while (CsrProcess) + { + /* Skip this process if it's already been processed*/ + if (CsrProcess->Flags & CsrProcessSkipShutdown) goto Next; + + /* Get the LUID of this Process */ + Status = CsrGetProcessLuid(CsrProcess->Process, &ProcessLuid); + + /* Check if we didn't get access to the LUID */ + if (Status == STATUS_ACCESS_DENIED) + { + /* FIXME:Check if we have any threads */ + } + + if (!NT_SUCCESS(Status)) + { + /* We didn't have access, so skip it */ + CsrProcess->Flags |= CsrProcessSkipShutdown; + goto Next; + } + + /* Check if this is the System LUID */ + if ((IsSystemLuid = RtlEqualLuid(&ProcessLuid, &SystemLuid))) + { + /* Mark this process */ + CsrProcess->ShutdownFlags |= CsrShutdownSystem; + } + else if (!(IsOurLuid = RtlEqualLuid(&ProcessLuid, CallerLuid))) + { + /* Our LUID doesn't match with the caller's */ + CsrProcess->ShutdownFlags |= CsrShutdownOther; + } + + /* Check if we're past the previous level */ + if (CsrProcess->ShutdownLevel > Level) + { + /* Update the level */ + Level = CsrProcess->ShutdownLevel; + + /* Set the final process */ + ReturnCsrProcess = CsrProcess; + } +Next: + /* Next process */ + CsrProcess = CsrProcess->next; + } + } + + /* Check if we found a process */ + if (ReturnCsrProcess) + { + /* Skip this one next time */ + ReturnCsrProcess->Flags |= CsrProcessSkipShutdown; + } + + return ReturnCsrProcess; +} + +/* This is really "CsrShutdownProcess", mostly */ +NTSTATUS +WINAPI +CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc, + IN PVOID Context) +{ + PVOID* RealContext = (PVOID*)Context; + PLUID CallerLuid = RealContext[0]; + PCSRSS_PROCESS_DATA CsrProcess = NULL; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + BOOLEAN FirstTry = TRUE; + ULONG Result = 0; + ULONG Hash; + + /* Acquire process lock */ + CsrAcquireProcessLock(); + + /* Start the loop */ + for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++) + { + /* Get the Process */ + CsrProcess = ProcessData[Hash]; + while (CsrProcess) + { + /* Remove the skip flag, set shutdown flags to 0*/ + CsrProcess->Flags &= ~CsrProcessSkipShutdown; + CsrProcess->ShutdownFlags = 0; + + /* Move to the next */ + CsrProcess = CsrProcess->next; + } + } + + /* Set shudown Priority */ + CsrSetToShutdownPriority(); + + /* Loop all processes */ + DPRINT1("Enumerating for LUID: %lx %lx\n", CallerLuid->HighPart, CallerLuid->LowPart); + + /* Start looping */ + while (TRUE) + { + /* Find the next process to shutdown */ + if (!(CsrProcess = FindProcessForShutdown(CallerLuid))) + { + /* Done, quit */ + CsrReleaseProcessLock(); + Status = STATUS_SUCCESS; + goto Quickie; + } + +LoopAgain: + /* Release the lock, make the callback, and acquire it back */ + DPRINT1("Found process: %lx\n", CsrProcess->ProcessId); + CsrReleaseProcessLock(); + Result = (ULONG)EnumProc(CsrProcess, Context); + CsrAcquireProcessLock(); + + /* Check the result */ + DPRINT1("Result: %d\n", Result); + if (Result == CsrShutdownCsrProcess) + { + /* The callback unlocked the process */ + break; + } + else if (Result == CsrShutdownNonCsrProcess) + { + /* A non-CSR process, the callback didn't touch it */ + continue; + } + else if (Result == CsrShutdownCancelled) + { + /* Shutdown was cancelled, unlock and exit */ + CsrReleaseProcessLock(); + Status = STATUS_CANCELLED; + goto Quickie; + } + + /* No matches during the first try, so loop again */ + if (FirstTry && Result == CsrShutdownNonCsrProcess) + { + FirstTry = FALSE; + goto LoopAgain; + } + } + +Quickie: + /* Return to normal priority */ + CsrSetToNormalPriority(); + return Status; +} + +NTSTATUS +NTAPI +CsrLockProcessByClientId(IN HANDLE Pid, + OUT PCSRSS_PROCESS_DATA *CsrProcess OPTIONAL) +{ + ULONG Hash; + PCSRSS_PROCESS_DATA CurrentProcess = NULL; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + /* Acquire the lock */ + CsrAcquireProcessLock(); + + /* Start the loop */ + for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++) + { + /* Get the Process */ + CurrentProcess = ProcessData[Hash]; + while (CurrentProcess) + { + /* Check for PID match */ + if (CurrentProcess->ProcessId == Pid) + { + /* Get out of here with success */ +// DPRINT1("Found %p for PID %lx\n", CurrentProcess, Pid); + Status = STATUS_SUCCESS; + goto Found; + } + + /* Move to the next */ + CurrentProcess = CurrentProcess->next; + } + } + + /* Nothing found, release the lock */ +Found: + if (!CurrentProcess) CsrReleaseProcessLock(); + + /* Return the status and process */ + if (CsrProcess) *CsrProcess = CurrentProcess; + return Status; } /********************************************************************** @@ -255,6 +860,76 @@ CSR_API(CsrCreateProcess) return(STATUS_SUCCESS); } +CSR_API(CsrCreateThread) +{ + PCSR_THREAD CurrentThread; + HANDLE ThreadHandle; + NTSTATUS Status; + PCSRSS_PROCESS_DATA CsrProcess; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + CurrentThread = NtCurrentTeb()->CsrClientThread; + CsrProcess = CurrentThread->Process; +// DPRINT1("Current thread: %p %p\n", CurrentThread, CsrProcess); +// DPRINT1("Request CID: %lx %lx %lx\n", +// CsrProcess->ProcessId, +// NtCurrentTeb()->ClientId.UniqueProcess, + // Request->Data.CreateThreadRequest.ClientId.UniqueProcess); + + if (CsrProcess->ProcessId != Request->Data.CreateThreadRequest.ClientId.UniqueProcess) + { + if (Request->Data.CreateThreadRequest.ClientId.UniqueProcess == NtCurrentTeb()->ClientId.UniqueProcess) + { + return STATUS_SUCCESS; + } + + Status = CsrLockProcessByClientId(Request->Data.CreateThreadRequest.ClientId.UniqueProcess, + &CsrProcess); + // DPRINT1("Found matching process: %p\n", CsrProcess); + if (!NT_SUCCESS(Status)) return Status; + } + +// DPRINT1("PIDs: %lx %lx\n", CurrentThread->Process->ProcessId, CsrProcess->ProcessId); +// DPRINT1("Thread handle is: %lx Process Handle is: %lx %lx\n", + // Request->Data.CreateThreadRequest.ThreadHandle, + // CurrentThread->Process->Process, + // CsrProcess->Process); + Status = NtDuplicateObject(CsrProcess->Process, + Request->Data.CreateThreadRequest.ThreadHandle, + NtCurrentProcess(), + &ThreadHandle, + 0, + 0, + DUPLICATE_SAME_ACCESS); + //DPRINT1("Duplicate status: %lx\n", Status); + if (!NT_SUCCESS(Status)) + { + Status = NtDuplicateObject(CurrentThread->Process->Process, + Request->Data.CreateThreadRequest.ThreadHandle, + NtCurrentProcess(), + &ThreadHandle, + 0, + 0, + DUPLICATE_SAME_ACCESS); + // DPRINT1("Duplicate status: %lx\n", Status); + } + + Status = STATUS_SUCCESS; // hack + if (NT_SUCCESS(Status)) + { + Status = CsrCreateThreadData(CsrProcess, + ThreadHandle, + &Request->Data.CreateThreadRequest.ClientId); + // DPRINT1("Create status: %lx\n", Status); + } + + if (CsrProcess != CurrentThread->Process) CsrReleaseProcessLock(); + + return Status; +} + CSR_API(CsrTerminateProcess) { Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); diff --git a/reactos/subsystems/win32/csrss/api/wapi.c b/reactos/subsystems/win32/csrss/api/wapi.c index 61ca693d6a8..a37e601ee8a 100644 --- a/reactos/subsystems/win32/csrss/api/wapi.c +++ b/reactos/subsystems/win32/csrss/api/wapi.c @@ -126,6 +126,7 @@ CsrpHandleConnectionRequest (PPORT_MESSAGE Request, HANDLE ServerPort = NULL, ServerThread = NULL; PCSRSS_PROCESS_DATA ProcessData = NULL; REMOTE_PORT_VIEW LpcRead; + CLIENT_ID ClientId; LpcRead.Length = sizeof(LpcRead); ServerPort = NULL; @@ -169,19 +170,23 @@ CsrpHandleConnectionRequest (PPORT_MESSAGE Request, Status = RtlCreateUserThread(NtCurrentProcess(), NULL, - FALSE, + TRUE, 0, 0, 0, (PTHREAD_START_ROUTINE)ClientConnectionThread, ServerPort, & ServerThread, - NULL); + &ClientId); if (!NT_SUCCESS(Status)) { DPRINT1("CSR: Unable to create server thread\n"); return Status; } + + CsrAddStaticServerThread(ServerThread, &ClientId, 0); + + NtResumeThread(ServerThread, NULL); NtClose(ServerThread); @@ -190,6 +195,53 @@ CsrpHandleConnectionRequest (PPORT_MESSAGE Request, return Status; } +PCSR_THREAD +NTAPI +CsrConnectToUser(VOID) +{ + PTEB Teb = NtCurrentTeb(); + PCSR_THREAD CsrThread; +#if 0 + NTSTATUS Status; + ANSI_STRING DllName; + UNICODE_STRING TempName; + HANDLE hUser32; + STRING StartupName; + + /* Check if we didn't already find it */ + if (!CsrClientThreadSetup) + { + /* Get the DLL Handle for user32.dll */ + RtlInitAnsiString(&DllName, "user32"); + RtlAnsiStringToUnicodeString(&TempName, &DllName, TRUE); + Status = LdrGetDllHandle(NULL, + NULL, + &TempName, + &hUser32); + RtlFreeUnicodeString(&TempName); + + /* If we got teh handle, get the Client Thread Startup Entrypoint */ + if (NT_SUCCESS(Status)) + { + RtlInitAnsiString(&StartupName,"ClientThreadSetup"); + Status = LdrGetProcedureAddress(hUser32, + &StartupName, + 0, + (PVOID)&CsrClientThreadSetup); + } + } + + /* Connect to user32 */ + CsrClientThreadSetup(); +#endif + /* Save pointer to this thread in TEB */ + CsrThread = CsrLocateThreadInProcess(NULL, &Teb->ClientId); + if (CsrThread) Teb->CsrClientThread = CsrThread; + + /* Return it */ + return CsrThread; +} + VOID WINAPI ClientConnectionThread(HANDLE ServerPort) @@ -199,10 +251,20 @@ ClientConnectionThread(HANDLE ServerPort) PCSR_API_MESSAGE Request = (PCSR_API_MESSAGE)RawRequest; PCSR_API_MESSAGE Reply; PCSRSS_PROCESS_DATA ProcessData; + PCSR_THREAD ServerThread; DPRINT("CSR: %s called\n", __FUNCTION__); + + /* Connect to user32 */ + while (!CsrConnectToUser()) + { + /* Keep trying until we get a response */ + NtCurrentTeb()->Win32ClientInfo[0] = 0; + //NtDelayExecution(FALSE, &TimeOut); + } /* Reply must be NULL at the first call to NtReplyWaitReceivePort */ + ServerThread = NtCurrentTeb()->CsrClientThread; Reply = NULL; /* Loop and reply/wait for a new message */ @@ -271,7 +333,7 @@ ClientConnectionThread(HANDLE ServerPort) } if (ProcessData->Terminated) { - DPRINT1("Message %d: process %p already terminated\n", + DPRINT1("Message %d: process %d already terminated\n", Request->Type, Request->Header.ClientId.UniqueProcess); continue; } @@ -284,8 +346,17 @@ ClientConnectionThread(HANDLE ServerPort) } else { + PCSR_THREAD Thread; + PCSRSS_PROCESS_DATA Process = NULL; + + //DPRINT1("locate thread %lx/%lx\n", Request->Header.ClientId.UniqueProcess, Request->Header.ClientId.UniqueThread); + Thread = CsrLocateThreadByClientId(&Process, &Request->Header.ClientId); + //DPRINT1("Thread found: %p %p\n", Thread, Process); + /* Call the Handler */ + if (Thread) NtCurrentTeb()->CsrClientThread = Thread; CsrApiCallHandler(ProcessData, Request); + if (Thread) NtCurrentTeb()->CsrClientThread = ServerThread; } /* Send back the reply */ diff --git a/reactos/subsystems/win32/csrss/include/api.h b/reactos/subsystems/win32/csrss/include/api.h index aaec4ef8d5f..4a17341f37f 100644 --- a/reactos/subsystems/win32/csrss/include/api.h +++ b/reactos/subsystems/win32/csrss/include/api.h @@ -13,6 +13,29 @@ #include +typedef enum _SHUTDOWN_RESULT +{ + CsrShutdownCsrProcess = 1, + CsrShutdownNonCsrProcess, + CsrShutdownCancelled +} SHUTDOWN_RESULT, *PSHUTDOWN_RESULT; + +typedef enum _CSR_SHUTDOWN_FLAGS +{ + CsrShutdownSystem = 4, + CsrShutdownOther = 8 +} CSR_SHUTDOWN_FLAGS, *PCSR_SHUTDOWN_FLAGS; + +typedef enum _CSR_PROCESS_FLAGS +{ + CsrProcessTerminating = 0x1, + CsrProcessSkipShutdown = 0x2, + CsrProcessCreateNewGroup = 0x100, + CsrProcessTerminated = 0x200, + CsrProcessLastThreadTerminated = 0x400, + CsrProcessIsConsoleApp = 0x800 +} CSR_PROCESS_FLAGS, *PCSR_PROCESS_FLAGS; + typedef struct Object_tt { LONG Type; @@ -59,8 +82,25 @@ typedef struct _CSRSS_PROCESS_DATA LIST_ENTRY ProcessEntry; PCONTROLDISPATCHER CtrlDispatcher; BOOL Terminated; + ULONG Flags; + ULONG ThreadCount; + LIST_ENTRY ThreadList; } CSRSS_PROCESS_DATA, *PCSRSS_PROCESS_DATA; +typedef struct _CSR_THREAD +{ + LARGE_INTEGER CreateTime; + LIST_ENTRY Link; + LIST_ENTRY HashLinks; + CLIENT_ID ClientId; + PCSRSS_PROCESS_DATA Process; + //struct _CSR_WAIT_BLOCK *WaitBlock; + HANDLE ThreadHandle; + ULONG Flags; + ULONG ReferenceCount; + ULONG ImpersonationCount; +} CSR_THREAD, *PCSR_THREAD; + typedef VOID (WINAPI *CSR_CLEANUP_OBJECT_PROC)(Object_t *Object); typedef struct tagCSRSS_OBJECT_DEFINITION @@ -100,6 +140,7 @@ extern HANDLE hBootstrapOk; CSR_API(CsrConnectProcess); CSR_API(CsrCreateProcess); CSR_API(CsrTerminateProcess); +CSR_API(CsrCreateThread); /* print.c */ VOID WINAPI DisplayString(LPCWSTR lpwString); @@ -129,7 +170,10 @@ PCSRSS_PROCESS_DATA WINAPI CsrGetProcessData(HANDLE ProcessId); PCSRSS_PROCESS_DATA WINAPI CsrCreateProcessData(HANDLE ProcessId); NTSTATUS WINAPI CsrFreeProcessData( HANDLE Pid ); NTSTATUS WINAPI CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context); - +PCSR_THREAD NTAPI CsrAddStaticServerThread(IN HANDLE hThread, IN PCLIENT_ID ClientId, IN ULONG ThreadFlags); +PCSR_THREAD NTAPI CsrLocateThreadInProcess(IN PCSRSS_PROCESS_DATA CsrProcess OPTIONAL, IN PCLIENT_ID Cid); +PCSR_THREAD NTAPI CsrLocateThreadByClientId(OUT PCSRSS_PROCESS_DATA *Process OPTIONAL, IN PCLIENT_ID ClientId); + /* api/handle.c */ NTSTATUS FASTCALL CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions); NTSTATUS WINAPI CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object, DWORD Access, BOOL Inheritable ); diff --git a/reactos/subsystems/win32/csrss/init.c b/reactos/subsystems/win32/csrss/init.c index 4097118c738..2314ab4b8a8 100644 --- a/reactos/subsystems/win32/csrss/init.c +++ b/reactos/subsystems/win32/csrss/init.c @@ -283,6 +283,7 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp) CSRSS_API_DEFINITION NativeDefinitions[] = { CSRSS_DEFINE_API(CREATE_PROCESS, CsrCreateProcess), + CSRSS_DEFINE_API(CREATE_THREAD, CsrCreateThread), CSRSS_DEFINE_API(TERMINATE_PROCESS, CsrTerminateProcess), CSRSS_DEFINE_API(CONNECT_PROCESS, CsrConnectProcess), CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS, CsrRegisterServicesProcess), @@ -305,6 +306,8 @@ CsrpCreateListenPort (IN LPWSTR Name, NTSTATUS Status = STATUS_SUCCESS; OBJECT_ATTRIBUTES PortAttributes; UNICODE_STRING PortName; + HANDLE ServerThread; + CLIENT_ID ClientId; DPRINT("CSR: %s called\n", __FUNCTION__); @@ -327,14 +330,22 @@ CsrpCreateListenPort (IN LPWSTR Name, } Status = RtlCreateUserThread(NtCurrentProcess(), NULL, - FALSE, + TRUE, 0, 0, 0, (PTHREAD_START_ROUTINE) ListenThread, *Port, - NULL, - NULL); + &ServerThread, + &ClientId); + + if (ListenThread == (PVOID)ClientConnectionThread) + { + CsrAddStaticServerThread(ServerThread, &ClientId, 0); + } + + NtResumeThread(ServerThread, NULL); + NtClose(ServerThread); return Status; } From 2d2f8b94046da2a88bf2195fafe99c0e061c17cb Mon Sep 17 00:00:00 2001 From: James Tabor Date: Tue, 9 Mar 2010 21:14:52 +0000 Subject: [PATCH 10/64] - [User32] sync spy to wine 1.1.40 svn path=/trunk/; revision=46043 --- reactos/dll/win32/user32/windows/spy.c | 280 ++++++++++++++++--------- reactos/media/doc/README.WINE | 1 + 2 files changed, 179 insertions(+), 102 deletions(-) diff --git a/reactos/dll/win32/user32/windows/spy.c b/reactos/dll/win32/user32/windows/spy.c index a6b64edc0c8..c1450426ea2 100644 --- a/reactos/dll/win32/user32/windows/spy.c +++ b/reactos/dll/win32/user32/windows/spy.c @@ -33,6 +33,24 @@ WINE_DEFAULT_DEBUG_CHANNEL(message); #define DEBUG_SPY 0 +static const char * const ClassLongOffsetNames[] = +{ + "GCLP_MENUNAME", /* -8 */ + "GCLP_HBRBACKGROUND", /* -10 */ + "GCLP_HCURSOR", /* -12 */ + "GCLP_HICON", /* -14 */ + "GCLP_HMODULE", /* -16 */ + "GCL_CBWNDEXTRA", /* -18 */ + "GCL_CBCLSEXTRA", /* -20 */ + "?", + "GCLP_WNDPROC", /* -24 */ + "GCL_STYLE", /* -26 */ + "?", + "?", + "GCW_ATOM", /* -32 */ + "GCLP_HICONSM", /* -34 */ +}; + static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = { "WM_NULL", /* 0x00 */ @@ -208,7 +226,9 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = "EM_GETLIMITTEXT", /* 0x00d5 */ "EM_POSFROMCHAR", /* 0x00d6 */ "EM_CHARFROMPOS", /* 0x00d7 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "EM_SETIMESTATUS", /* 0x00d8 */ + "EM_GETIMESTATUS", /* 0x00d9 */ + NULL, NULL, NULL, NULL, NULL, NULL, /* 0x00E0 - Win32 Scrollbars */ "SBM_SETPOS", /* 0x00e0 */ @@ -232,7 +252,9 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = "BM_CLICK", /* 0x00f5 */ "BM_GETIMAGE", /* 0x00f6 */ "BM_SETIMAGE", /* 0x00f7 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + "WM_INPUT_DEVICE_CHANGE", /* 0x00fe */ + "WM_INPUT", /* 0x00ff */ "WM_KEYDOWN", /* 0x0100 */ "WM_KEYUP", /* 0x0101 */ @@ -243,10 +265,10 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_SYSCHAR", /* 0x0106 */ "WM_SYSDEADCHAR", /* 0x0107 */ "WM_KEYLAST", /* 0x0108 */ - NULL, - "WM_CONVERTREQUEST", - "WM_CONVERTRESULT", - "WM_INTERIM", + "WM_UNICHAR", /* 0x0109 */ + "WM_CONVERTREQUEST", /* 0x010a */ + "WM_CONVERTRESULT", /* 0x010b */ + "WM_INTERIM", /* 0x010c */ "WM_IME_STARTCOMPOSITION", /* 0x010d */ "WM_IME_ENDCOMPOSITION", /* 0x010e */ "WM_IME_COMPOSITION", /* 0x010f */ @@ -399,7 +421,9 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x01E0 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, + "MN_GETHMENU", /* 0x01E1 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x01F0 */ @@ -420,7 +444,8 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_XBUTTONDOWN", /* 0x020B */ "WM_XBUTTONUP", /* 0x020C */ "WM_XBUTTONDBLCLK", /* 0x020D */ - NULL, NULL, + "WM_MOUSEHWHEEL", /* 0x020E */ + NULL, "WM_PARENTNOTIFY", /* 0x0210 */ "WM_ENTERMENULOOP", /* 0x0211 */ @@ -561,22 +586,39 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_HOTKEY", /* 0x0312 */ "WM_POPUPSYSTEMMENU", /* 0x0313 */ NULL, NULL, NULL, - "WM_PRINT", - "WM_PRINTCLIENT", - NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "WM_PRINT", /* 0x0317 */ + "WM_PRINTCLIENT", /* 0x0318 */ + "WM_APPCOMMAND", /* 0x0319 */ + "WM_THEMECHANGED", /* 0x031A */ + NULL, NULL, + "WM_CLIPBOARDUPDATE", /* 0x031D */ + "WM_DWMCOMPOSITIONCHANGED", /* 0x031E */ + "WM_DWMNCRENDERINGCHANGED", /* 0x031F */ + + "WM_DWMCOLORIZATIONCOLORCHANGED", /* 0x0320 */ + "WM_DWMWINDOWMAXIMIZEDCHANGE", /* 0x0321 */ + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "WM_GETTITLEBARINFOEX", /* 0x033F */ /* 0x0340 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + /* 0x0350 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "WM_HANDHELDFIRST", /* 0x0358 */ + "WM_HANDHELDFIRST+1", /* 0x0359 */ + "WM_HANDHELDFIRST+2", /* 0x035A */ + "WM_HANDHELDFIRST+3", /* 0x035B */ + "WM_HANDHELDFIRST+4", /* 0x035C */ + "WM_HANDHELDFIRST+5", /* 0x035D */ + "WM_HANDHELDFIRST+6", /* 0x035E */ + "WM_HANDHELDLAST", /* 0x035F */ - "WM_QUERYAFXWNDPROC", /* 0x0360 */ + "WM_QUERYAFXWNDPROC", /* 0x0360 WM_AFXFIRST */ "WM_SIZEPARENT", /* 0x0361 */ "WM_SETMESSAGESTRING", /* 0x0362 */ "WM_IDLEUPDATECMDUI", /* 0x0363 */ @@ -603,7 +645,8 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_OCC_LOADFROMSTREAM_EX", /* 0x037A */ "WM_OCC_LOADFROMSTORAGE_EX", /* 0x037B */ - NULL,NULL,NULL,NULL, + NULL,NULL,NULL, + "WM_AFXLAST", /* 0x037F */ "WM_PENWINFIRST", /* 0x0380 */ "WM_RCRESULT", /* 0x0381 */ @@ -678,7 +721,7 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = }; -#define SPY_MAX_LVMMSGNUM 140 +#define SPY_MAX_LVMMSGNUM 182 static const char * const LVMMessageTypeNames[SPY_MAX_LVMMSGNUM + 1] = { "LVM_GETBKCOLOR", /* 1000 */ @@ -822,6 +865,49 @@ static const char * const LVMMessageTypeNames[SPY_MAX_LVMMSGNUM + 1] = NULL, "LVM_SETBKIMAGEW", "LVM_GETBKIMAGEW" /* 0x108B */ + "LVM_SETSELECTEDCOLUMN", + "LVM_SETTILEWIDTH", + "LVM_SETVIEW", + "LVM_GETVIEW", + NULL, + "LVM_INSERTGROUP", + NULL, + "LVM_SETGROUPINFO", + NULL, + "LVM_GETGROUPINFO", + "LVM_REMOVEGROUP", + "LVM_MOVEGROUP", + NULL, + NULL, + "LVM_MOVEITEMTOGROUP", + "LVM_SETGROUPMETRICS", + "LVM_GETGROUPMETRICS", + "LVM_ENABLEGROUPVIEW", + "LVM_SORTGROUPS", + "LVM_INSERTGROUPSORTED", + "LVM_REMOVEALLGROUPS", + "LVM_HASGROUP", + "LVM_SETTILEVIEWINFO", + "LVM_GETTILEVIEWINFO", + "LVM_SETTILEINFO", + "LVM_GETTILEINFO", + "LVM_SETINSERTMARK", + "LVM_GETINSERTMARK", + "LVM_INSERTMARKHITTEST", + "LVM_GETINSERTMARKRECT", + "LVM_SETINSERTMARKCOLOR", + "LVM_GETINSERTMARKCOLOR", + NULL, + "LVM_SETINFOTIP", + "LVM_GETSELECTEDCOLUMN", + "LVM_ISGROUPVIEWENABLED", + "LVM_GETOUTLINECOLOR", + "LVM_SETOUTLINECOLOR", + NULL, + "LVM_CANCELEDITLABEL", + "LVM_MAPINDEXTOID", + "LVM_MAPIDTOINDEX", + "LVM_ISITEMVISIBLE" }; @@ -1026,7 +1112,7 @@ static const char * const CCMMessageTypeNames[SPY_MAX_CCMMSGNUM + 1] = "CCM_SETNOTIFYWINDOW" }; -#define SPY_MAX_WINEMSGNUM 6 +#define SPY_MAX_WINEMSGNUM 9 static const char * const WINEMessageTypeNames[SPY_MAX_WINEMSGNUM + 1] = { "WM_WINE_DESTROYWINDOW", @@ -1035,6 +1121,9 @@ static const char * const WINEMessageTypeNames[SPY_MAX_WINEMSGNUM + 1] = "WM_WINE_SETPARENT", "WM_WINE_SETWINDOWLONG", "WM_WINE_ENABLEWINDOW" + "WM_WINE_SETACTIVEWINDOW", + "WM_WINE_KEYBOARD_LL_HOOK", + "WM_WINE_MOUSE_LL_HOOK", }; /* Virtual key names */ @@ -1069,10 +1158,10 @@ static const char * const VK_KeyNames[SPY_MAX_VKKEYSNUM + 1] = NULL, /* 0x19 */ NULL, /* 0x1A */ "VK_ESCAPE", /* 0x1B */ - NULL, /* 0x1C */ - NULL, /* 0x1D */ - NULL, /* 0x1E */ - NULL, /* 0x1F */ + "VK_CONVERT", /* 0x1C */ + "VK_NONCONVERT", /* 0x1D */ + "VK_ACCEPT", /* 0x1E */ + "VK_MODECHANGE", /* 0x1F */ "VK_SPACE", /* 0x20 */ "VK_PRIOR", /* 0x21 */ "VK_NEXT", /* 0x22 */ @@ -1136,7 +1225,7 @@ static const char * const VK_KeyNames[SPY_MAX_VKKEYSNUM + 1] = "VK_RWIN", /* 0x5C */ "VK_APPS", /* 0x5D */ NULL, /* 0x5E */ - NULL, /* 0x5F */ + "VK_SLEEP", /* 0x5F */ "VK_NUMPAD0", /* 0x60 */ "VK_NUMPAD1", /* 0x61 */ "VK_NUMPAD2", /* 0x62 */ @@ -1187,11 +1276,11 @@ static const char * const VK_KeyNames[SPY_MAX_VKKEYSNUM + 1] = NULL, /* 0x8F */ "VK_NUMLOCK", /* 0x90 */ "VK_SCROLL", /* 0x91 */ - NULL, /* 0x92 */ - NULL, /* 0x93 */ - NULL, /* 0x94 */ - NULL, /* 0x95 */ - NULL, /* 0x96 */ + "VK_OEM_NEC_EQUAL", /* 0x92 aka. VK_OEM_FJ_JISHO */ + "VK_OEM_FJ_MASSHOU", /* 0x93 */ + "VK_OEM_FJ_TOUROKU", /* 0x94 */ + "VK_OEM_FJ_LOYA", /* 0x95 */ + "VK_OEM_FJ_ROYA", /* 0x96 */ NULL, /* 0x97 */ NULL, /* 0x98 */ NULL, /* 0x99 */ @@ -1207,24 +1296,24 @@ static const char * const VK_KeyNames[SPY_MAX_VKKEYSNUM + 1] = "VK_RCONTROL", /* 0xA3 */ "VK_LMENU", /* 0xA4 */ "VK_RMENU", /* 0xA5 */ - NULL, /* 0xA6 */ - NULL, /* 0xA7 */ - NULL, /* 0xA8 */ - NULL, /* 0xA9 */ - NULL, /* 0xAA */ - NULL, /* 0xAB */ - NULL, /* 0xAC */ - NULL, /* 0xAD */ - NULL, /* 0xAE */ - NULL, /* 0xAF */ - NULL, /* 0xB0 */ - NULL, /* 0xB1 */ - NULL, /* 0xB2 */ - NULL, /* 0xB3 */ - NULL, /* 0xB4 */ - NULL, /* 0xB5 */ - NULL, /* 0xB6 */ - NULL, /* 0xB7 */ + "VK_BROWSER_BACK", /* 0xA6 */ + "VK_BROWSER_FORWARD", /* 0xA7 */ + "VK_BROWSER_REFRESH", /* 0xA8 */ + "VK_BROWSER_STOP", /* 0xA9 */ + "VK_BROWSER_SEARCH", /* 0xAA */ + "VK_BROWSER_FAVORITES", /* 0xAB */ + "VK_BROWSER_HOME", /* 0xAC */ + "VK_VOLUME_MUTE", /* 0xAD */ + "VK_VOLUME_DOWN", /* 0xAE */ + "VK_VOLUME_UP", /* 0xAF */ + "VK_MEDIA_NEXT_TRACK", /* 0xB0 */ + "VK_MEDIA_PREV_TRACK", /* 0xB1 */ + "VK_MEDIA_STOP", /* 0xB2 */ + "VK_MEDIA_PLAY_PAUSE", /* 0xB3 */ + "VK_LAUNCH_MAIL", /* 0xB4 */ + "VK_LAUNCH_MEDIA_SELECT", /* 0xB5 */ + "VK_LAUNCH_APP1", /* 0xB6 */ + "VK_LAUNCH_APP2", /* 0xB7 */ NULL, /* 0xB8 */ NULL, /* 0xB9 */ "VK_OEM_1", /* 0xBA */ @@ -1272,7 +1361,7 @@ static const char * const VK_KeyNames[SPY_MAX_VKKEYSNUM + 1] = "VK_ICO_00", /* 0xE4 */ "VK_PROCESSKEY", /* 0xE5 */ NULL, /* 0xE6 */ - NULL, /* 0xE7 */ + "VK_PACKET", /* 0xE7 */ NULL, /* 0xE8 */ NULL, /* 0xE9 */ NULL, /* 0xEA */ @@ -1459,6 +1548,7 @@ static const USER_MSG toolbar_array[] = { USM(TB_SETLISTGAP ,0), USM(TB_GETIMAGELISTCOUNT ,0), USM(TB_GETIDEALSIZE ,0), + USM(TB_UNKWN464 ,0), {0,0,0} }; static const USER_MSG tooltips_array[] = { @@ -1998,6 +2088,23 @@ static const USER_MSG *SPY_Bsearch_Msg( const USER_MSG *first, const USER_MSG *l return NULL; } +/*********************************************************************** + * SPY_GetClassLongOffsetName + * + * Gets the name of a class long offset. + */ +const char *SPY_GetClassLongOffsetName( INT offset ) +{ + INT index; + if (offset < 0 && offset % 2 == 0 && ((index = -(offset + 8) / 2) < + sizeof(ClassLongOffsetNames) / sizeof(*ClassLongOffsetNames))) + { + return ClassLongOffsetNames[index]; + } + + return "?"; +} + /*********************************************************************** * SPY_GetClassName * @@ -2349,6 +2456,23 @@ static void SPY_DumpStructure(const SPY_INSTANCE *sp_e, BOOL enter) TRACE("itemData=0x%08lx\n", lpmis->itemData); } break; + case WM_NCCREATE: + case WM_CREATE: + { + BOOL unicode; + CREATESTRUCTA *cs; + + if (!enter) break; + + unicode = IsWindowUnicode(sp_e->msg_hwnd); + cs = (CREATESTRUCTA *)sp_e->lParam; + TRACE("%s %s ex=%08x style=%08x %d,%d %dx%d parent=%p menu=%p inst=%p params=%p\n", + unicode ? debugstr_w((LPCWSTR)cs->lpszName) : debugstr_a(cs->lpszName), + unicode ? debugstr_w((LPCWSTR)cs->lpszClass) : debugstr_a(cs->lpszClass), + cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy, + cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams); + break; + } case WM_SIZE: if (!enter) break; TRACE("cx=%d cy=%d\n", LOWORD(sp_e->lParam), HIWORD(sp_e->lParam)); @@ -2445,20 +2569,12 @@ void SPY_EnterMessage( INT iFlag, HWND hWnd, UINT msg, /* each SPY_SENDMESSAGE must be complemented by call to SPY_ExitMessage */ switch(iFlag) { -#ifndef __REACTOS__ - case SPY_DISPATCHMESSAGE16: - TRACE("%*s(%04x) %-16s message [%04x] %s dispatched wp=%04lx lp=%08lx\n", - indent, "", HWND_16(hWnd), - debugstr_w(sp_e.wnd_name), msg, sp_e.msg_name, wParam, lParam); - break; -#endif case SPY_DISPATCHMESSAGE: TRACE("%*s(%p) %-16s message [%04x] %s dispatched wp=%08lx lp=%08lx\n", indent, "", hWnd, debugstr_w(sp_e.wnd_name), msg, sp_e.msg_name, wParam, lParam); break; -// case SPY_SENDMESSAGE16: case SPY_SENDMESSAGE: { char taskName[20]; @@ -2466,29 +2582,14 @@ void SPY_EnterMessage( INT iFlag, HWND hWnd, UINT msg, if (tid == GetCurrentThreadId()) strcpy( taskName, "self" ); else sprintf( taskName, "tid %04lx", GetCurrentThreadId() ); -#ifndef __REACTOS__ - if (iFlag == SPY_SENDMESSAGE16) - TRACE("%*s(%04x) %-16s message [%04x] %s sent from %s wp=%04lx lp=%08lx\n", - indent, "", HWND_16(hWnd), debugstr_w(sp_e.wnd_name), msg, - sp_e.msg_name, taskName, wParam, lParam ); - else -#endif - { TRACE("%*s(%p) %-16s message [%04x] %s sent from %s wp=%08lx lp=%08lx\n", + + TRACE("%*s(%p) %-16s message [%04x] %s sent from %s wp=%08lx lp=%08lx\n", indent, "", hWnd, debugstr_w(sp_e.wnd_name), msg, sp_e.msg_name, taskName, wParam, lParam ); SPY_DumpStructure(&sp_e, TRUE); - } } break; -#ifndef __REACTOS__ - case SPY_DEFWNDPROC16: - if( SPY_ExcludeDWP ) return; - TRACE("%*s(%04x) DefWindowProc16: %s [%04x] wp=%04lx lp=%08lx\n", - indent, "", HWND_16(hWnd), sp_e.msg_name, msg, wParam, lParam ); - break; -#endif - case SPY_DEFWNDPROC: if( SPY_ExcludeDWP ) return; TRACE("%*s(%p) DefWindowProc32: %s [%04x] wp=%08lx lp=%08lx\n", @@ -2508,6 +2609,7 @@ void SPY_ExitMessage( INT iFlag, HWND hWnd, UINT msg, LRESULT lReturn, { SPY_INSTANCE sp_e; int indent; + DWORD save_error = GetLastError(); if (!TRACE_ON(message) || SPY_EXCLUDE(msg) || (SPY_ExcludeDWP && (/*iFlag == SPY_RESULT_DEFWND16 || */iFlag == SPY_RESULT_DEFWND)) ) @@ -2528,46 +2630,19 @@ void SPY_ExitMessage( INT iFlag, HWND hWnd, UINT msg, LRESULT lReturn, switch(iFlag) { -#ifndef __REACTOS__ - case SPY_RESULT_DEFWND16: - TRACE(" %*s(%04x) DefWindowProc16: %s [%04x] returned %08lx\n", - indent, "", HWND_16(hWnd), sp_e.msg_name, msg, lReturn ); - break; -#endif - case SPY_RESULT_DEFWND: TRACE(" %*s(%p) DefWindowProc32: %s [%04x] returned %08lx\n", indent, "", hWnd, sp_e.msg_name, msg, lReturn ); break; -#ifndef __REACTOS__ - case SPY_RESULT_OK16: - TRACE(" %*s(%04x) %-16s message [%04x] %s returned %08lx\n", - indent, "", HWND_16(hWnd), debugstr_w(sp_e.wnd_name), msg, - sp_e.msg_name, lReturn ); - break; -#endif - case SPY_RESULT_OK: TRACE(" %*s(%p) %-16s message [%04x] %s returned %08lx\n", indent, "", hWnd, debugstr_w(sp_e.wnd_name), msg, sp_e.msg_name, lReturn ); SPY_DumpStructure(&sp_e, FALSE); break; - -#ifndef __REACTOS__ - case SPY_RESULT_INVALIDHWND16: - WARN(" %*s(%04x) %-16s message [%04x] %s HAS INVALID HWND\n", - indent, "", HWND_16(hWnd), debugstr_w(sp_e.wnd_name), msg, sp_e.msg_name ); - break; -#endif - - case SPY_RESULT_INVALIDHWND: - WARN(" %*s(%p) %-16s message [%04x] %s HAS INVALID HWND\n", - indent, "", hWnd, debugstr_w(sp_e.wnd_name), msg, - sp_e.msg_name ); - break; } + SetLastError( save_error ); } @@ -2576,7 +2651,8 @@ void SPY_ExitMessage( INT iFlag, HWND hWnd, UINT msg, LRESULT lReturn, */ int SPY_Init(void) { - int i, j; + int i; + UINT j; char buffer[1024]; const SPY_NOTIFY *p; const USER_MSG *q; diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 6bdb1f2b3b3..c10502a8f18 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -254,6 +254,7 @@ User32 - reactos/dll/win32/user32/windows/menu.c # Forked reactos/dll/win32/user32/windows/messagebox.c # Forked reactos/dll/win32/user32/windows/rect.c # Forked (uitools.c) + reactos/dll/win32/user32/windows/spy.c # Synced to Wine-1_1_40 reactos/dll/win32/user32/windows/text.c # Forked (lstr.c) reactos/dll/win32/user32/windows/winpos.c # Forked From 4c956b83a707f7bdc306ce463a205bc738a60340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Tue, 9 Mar 2010 22:36:52 +0000 Subject: [PATCH 11/64] Link SCSI miniport drivers only to scsiport svn path=/trunk/; revision=46044 --- .../drivers/storage/ide/atapi/atapi.rbuild | 2 -- .../storage/port/buslogic/BusLogic958.c | 34 +++++++++++++++++++ .../storage/port/buslogic/buslogic.rbuild | 2 -- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/reactos/drivers/storage/ide/atapi/atapi.rbuild b/reactos/drivers/storage/ide/atapi/atapi.rbuild index 708522b1248..2f6b428acdd 100644 --- a/reactos/drivers/storage/ide/atapi/atapi.rbuild +++ b/reactos/drivers/storage/ide/atapi/atapi.rbuild @@ -3,8 +3,6 @@ . - ntoskrnl - hal scsiport atapi.c atapi.rc diff --git a/reactos/drivers/storage/port/buslogic/BusLogic958.c b/reactos/drivers/storage/port/buslogic/BusLogic958.c index 0bf439e06b9..22c5838b99b 100644 --- a/reactos/drivers/storage/port/buslogic/BusLogic958.c +++ b/reactos/drivers/storage/port/buslogic/BusLogic958.c @@ -79,6 +79,40 @@ v1.2.0.2 // Fix PR 40284 correctly, disable interrupts in the initialization ro #include "BusLogic958.h" +int strcmp(const char* s1, const char* s2) +{ + while(*s1 == *s2) + { + if(*s1 == 0) return 0; + + s1 ++; + s2 ++; + } + + return *s1 - *s2; +} + +char * strcat(char * s, const char * append) +{ + char * save = s; + + for(; *s; ++s); + + while((*s++ = *append++)); + + return save; +} + +char * strcpy(char * to, const char * from) +{ + char *save = to; + + for (; (*to = *from); ++from, ++to); + + return save; +} + + ULONG NTAPI DriverEntry(IN PVOID DriverObject, diff --git a/reactos/drivers/storage/port/buslogic/buslogic.rbuild b/reactos/drivers/storage/port/buslogic/buslogic.rbuild index f5b652dd8e6..3a197ce05de 100644 --- a/reactos/drivers/storage/port/buslogic/buslogic.rbuild +++ b/reactos/drivers/storage/port/buslogic/buslogic.rbuild @@ -3,8 +3,6 @@ . - ntoskrnl - hal scsiport BusLogic958.c BusLogic958.rc From e6baa6f072b9e7f4b0b4555d69a3ae3f3d1e0229 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 10 Mar 2010 00:56:07 +0000 Subject: [PATCH 12/64] merge r46045 svn path=/trunk/; revision=46046 --- reactos/include/reactos/asm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/include/reactos/asm.h b/reactos/include/reactos/asm.h index 1005c1f715d..30afca482a0 100644 --- a/reactos/include/reactos/asm.h +++ b/reactos/include/reactos/asm.h @@ -6,7 +6,7 @@ * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) */ -#ifdef _MSC_VER +#ifdef _USE_ML /* Allow ".name" identifiers */ OPTION DOTNAME From cbe3e09f611c2e319b7ee17bd5f0479cf2ad2190 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Wed, 10 Mar 2010 03:32:17 +0000 Subject: [PATCH 13/64] [KERNEL32]: As indicated by the comment, kernel32 should always connect to the console server, even for non-console apps (the latter will just basically ignore the request). This is needed to (at minimum) setup the Ctrl-C handler, as otherwise, only "true console" apps will have a handler, even though internally, all apps have such a handler. This is what CSRSS needs to call internally for shutting down non-GUI apps, for example. (The default CTRL-C handler will just call ExitProcess). svn path=/trunk/; revision=46047 --- reactos/dll/win32/kernel32/misc/console.c | 6 ++- reactos/dll/win32/kernel32/misc/dllmain.c | 64 ++++++++++++----------- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/console.c b/reactos/dll/win32/kernel32/misc/console.c index 13961ad6631..e535e77f4d4 100644 --- a/reactos/dll/win32/kernel32/misc/console.c +++ b/reactos/dll/win32/kernel32/misc/console.c @@ -39,6 +39,7 @@ BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event) { + DPRINT1("Default handler called: %lx\n", Event); switch(Event) { case CTRL_C_EVENT: @@ -75,7 +76,8 @@ ConsoleControlDispatcher(DWORD CodeAndFlag) DWORD nCode = CodeAndFlag & MAXLONG; UINT i; EXCEPTION_RECORD erException; - + + DPRINT1("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); switch(nCode) @@ -152,6 +154,7 @@ ConsoleControlDispatcher(DWORD CodeAndFlag) (CodeAndFlag & MINLONG) && ((nCode == CTRL_LOGOFF_EVENT) || (nCode == CTRL_SHUTDOWN_EVENT))) { + DPRINT1("Skipping system/service apps\n"); break; } @@ -172,7 +175,6 @@ ConsoleControlDispatcher(DWORD CodeAndFlag) } RtlLeaveCriticalSection(&ConsoleLock); - ExitThread(nExitCode); } diff --git a/reactos/dll/win32/kernel32/misc/dllmain.c b/reactos/dll/win32/kernel32/misc/dllmain.c index 7d08667205b..a828f72ef5a 100644 --- a/reactos/dll/win32/kernel32/misc/dllmain.c +++ b/reactos/dll/win32/kernel32/misc/dllmain.c @@ -128,6 +128,7 @@ BasepInitConsole(VOID) CSR_API_MESSAGE Request; ULONG CsrRequest; NTSTATUS Status; + BOOLEAN NotConsole = FALSE; PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters; WCHAR lpTest[MAX_PATH]; @@ -143,39 +144,41 @@ BasepInitConsole(VOID) { DPRINT("Image is not a console application\n"); Parameters->ConsoleHandle = NULL; - return TRUE; - } - - /* Assume one is needed */ - Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE; - - /* Handle the special flags given to us by BasepInitializeEnvironment */ - if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS) - { - /* No console to create */ - DPRINT("No console to create\n"); - Parameters->ConsoleHandle = NULL; Request.Data.AllocConsoleRequest.ConsoleNeeded = FALSE; } - else if (Parameters->ConsoleHandle == HANDLE_CREATE_NEW_CONSOLE) - { - /* We'll get the real one soon */ - DPRINT("Creating new console\n"); - Parameters->ConsoleHandle = NULL; - } - else if (Parameters->ConsoleHandle == HANDLE_CREATE_NO_WINDOW) - { - /* We'll get the real one soon */ - DPRINT1("NOT SUPPORTED: HANDLE_CREATE_NO_WINDOW\n"); - Parameters->ConsoleHandle = NULL; - } else { - if (Parameters->ConsoleHandle == INVALID_HANDLE_VALUE) + /* Assume one is needed */ + Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE; + + /* Handle the special flags given to us by BasepInitializeEnvironment */ + if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS) { - Parameters->ConsoleHandle = 0; + /* No console to create */ + DPRINT("No console to create\n"); + Parameters->ConsoleHandle = NULL; + Request.Data.AllocConsoleRequest.ConsoleNeeded = FALSE; + } + else if (Parameters->ConsoleHandle == HANDLE_CREATE_NEW_CONSOLE) + { + /* We'll get the real one soon */ + DPRINT("Creating new console\n"); + Parameters->ConsoleHandle = NULL; + } + else if (Parameters->ConsoleHandle == HANDLE_CREATE_NO_WINDOW) + { + /* We'll get the real one soon */ + DPRINT1("NOT SUPPORTED: HANDLE_CREATE_NO_WINDOW\n"); + Parameters->ConsoleHandle = NULL; + } + else + { + if (Parameters->ConsoleHandle == INVALID_HANDLE_VALUE) + { + Parameters->ConsoleHandle = 0; + } + DPRINT("Using existing console: %x\n", Parameters->ConsoleHandle); } - DPRINT("Using existing console: %x\n", Parameters->ConsoleHandle); } /* Initialize Console Ctrl Handler */ @@ -185,7 +188,7 @@ BasepInitConsole(VOID) NrCtrlHandlers = 1; CtrlHandlers = InitialHandler; CtrlHandlers[0] = DefaultConsoleCtrlHandler; - + /* Now use the proper console handle */ Request.Data.AllocConsoleRequest.Console = Parameters->ConsoleHandle; @@ -194,9 +197,6 @@ BasepInitConsole(VOID) * but we don't have one yet, so we will instead simply send a create * console message to the Base Server. When we finally have a Console * Server, this code should be changed to send connection data instead. - * - * Also note that this connection should be made for any console app, even - * in the case above where -we- return. */ CsrRequest = MAKE_CSR_API(ALLOC_CONSOLE, CSR_CONSOLE); Request.Data.AllocConsoleRequest.CtrlDispatcher = ConsoleControlDispatcher; @@ -210,6 +210,8 @@ BasepInitConsole(VOID) /* We're lying here, so at least the process can load... */ return TRUE; } + + if (NotConsole) return TRUE; /* We got the handles, let's set them */ if ((Parameters->ConsoleHandle = Request.Data.AllocConsoleRequest.Console)) From 90fa1d03430e1ed42b02427a3f1d27688f5b2d5d Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Wed, 10 Mar 2010 03:35:18 +0000 Subject: [PATCH 14/64] [CSRSS]: Differentiate between first-try and second-try shutdown. In the first try, the console server should defer to the user/win32k server to attempt shutdown for a non-console app. However, if we end up with a second try because this did not happen, then the console server takes matters in its own hands and calls the CTRL-C handler (with some exceptions, such as system/service apps, or apps not belonging to the LUID). svn path=/trunk/; revision=46048 --- reactos/subsystems/win32/csrss/api/process.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/reactos/subsystems/win32/csrss/api/process.c b/reactos/subsystems/win32/csrss/api/process.c index 1be6bdc1b00..9bd3cd6ff26 100644 --- a/reactos/subsystems/win32/csrss/api/process.c +++ b/reactos/subsystems/win32/csrss/api/process.c @@ -696,7 +696,7 @@ CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc, PLUID CallerLuid = RealContext[0]; PCSRSS_PROCESS_DATA CsrProcess = NULL; NTSTATUS Status = STATUS_UNSUCCESSFUL; - BOOLEAN FirstTry = TRUE; + BOOLEAN FirstTry; ULONG Result = 0; ULONG Hash; @@ -729,6 +729,7 @@ CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc, while (TRUE) { /* Find the next process to shutdown */ + FirstTry = TRUE; if (!(CsrProcess = FindProcessForShutdown(CallerLuid))) { /* Done, quit */ @@ -741,7 +742,7 @@ LoopAgain: /* Release the lock, make the callback, and acquire it back */ DPRINT1("Found process: %lx\n", CsrProcess->ProcessId); CsrReleaseProcessLock(); - Result = (ULONG)EnumProc(CsrProcess, Context); + Result = (ULONG)EnumProc(CsrProcess, (PVOID)((ULONG_PTR)Context | FirstTry)); CsrAcquireProcessLock(); /* Check the result */ @@ -754,7 +755,7 @@ LoopAgain: else if (Result == CsrShutdownNonCsrProcess) { /* A non-CSR process, the callback didn't touch it */ - continue; + //continue; } else if (Result == CsrShutdownCancelled) { From fc4574d166d36d43d7b8b1587bce8f58e86aa48e Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Wed, 10 Mar 2010 04:12:25 +0000 Subject: [PATCH 15/64] [NTOS]: No good deed goes unpunished. Continuing the novel/saga from a couple of days ago, it seems that now that impersonation works, various code paths are being tickled into existence. For example, it would seem parts of the system now attempt setting primary tokens. This would cause an assertion, since PspAssignPrimaryToken incorrectly dereferenced the token (leading to a double-dereference) due to an off-by-! mistake. svn path=/trunk/; revision=46049 --- reactos/ntoskrnl/ps/security.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/ps/security.c b/reactos/ntoskrnl/ps/security.c index f45b09175dd..ffb894c083b 100644 --- a/reactos/ntoskrnl/ps/security.c +++ b/reactos/ntoskrnl/ps/security.c @@ -206,7 +206,7 @@ PspAssignPrimaryToken(IN PEPROCESS Process, /* Dereference Tokens and Return */ if (NT_SUCCESS(Status)) ObDereferenceObject(OldToken); - if (AccessToken) ObDereferenceObject(NewToken); + if (!AccessToken) ObDereferenceObject(NewToken); return Status; } From 1cd9cb22ef37cc00493017c1fc00af6fd7cb946d Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Wed, 10 Mar 2010 04:59:39 +0000 Subject: [PATCH 16/64] [CSRSS]: Split off CSRSS into a more Windows-friendly model. CSRSS.EXE is simply a stub which loads CSRSRV.DLL, where all the actual code is present. [CSRSRV]: Mostly moved all the current CSRSS code into CSRSRV, with some very minor changes to get it workking. [CSRSRV]: Add some more code from Alex's CSRSRV, such as thread dereferencing/deallocation, hacked to work. [CSRSRV]: Make CsrTerminateProcess destroy each CSR thread in that process, otherwise we were always leaking a handle, so processes never died. Because of this, primary tokens would remain "in use", and when umpnpmgr attempted to do a "Create Process as User" for the second+ time, the call would fail since the token from the first process was still around. This fixed that regression from the mailing list. svn path=/trunk/; revision=46051 --- reactos/boot/bootdata/packages/reactos.dff | 1 + .../win32/csrss/{ => csrsrv}/api/handle.c | 2 +- .../win32/csrss/{ => csrsrv}/api/process.c | 74 +++++- .../win32/csrss/{ => csrsrv}/api/user.c | 2 +- .../win32/csrss/{ => csrsrv}/api/wapi.c | 2 +- .../win32/csrss/csrsrv/csrsrv.rbuild | 20 ++ .../subsystems/win32/csrss/csrsrv/csrsrv.rc | 5 + .../subsystems/win32/csrss/csrsrv/csrsrv.spec | 35 +++ .../win32/csrss/{ => csrsrv}/init.c | 229 +++++++++++------- .../win32/csrss/{csrss.h => csrsrv/srv.h} | 12 +- reactos/subsystems/win32/csrss/csrss.c | 108 +++++---- reactos/subsystems/win32/csrss/csrss.rbuild | 15 +- reactos/subsystems/win32/csrss/include/api.h | 10 +- reactos/subsystems/win32/csrss/print.c | 61 ----- reactos/subsystems/win32/csrss/video.c | 111 --------- 15 files changed, 350 insertions(+), 337 deletions(-) rename reactos/subsystems/win32/csrss/{ => csrsrv}/api/handle.c (99%) rename reactos/subsystems/win32/csrss/{ => csrsrv}/api/process.c (94%) rename reactos/subsystems/win32/csrss/{ => csrsrv}/api/user.c (98%) rename reactos/subsystems/win32/csrss/{ => csrsrv}/api/wapi.c (99%) create mode 100644 reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild create mode 100644 reactos/subsystems/win32/csrss/csrsrv/csrsrv.rc create mode 100644 reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec rename reactos/subsystems/win32/csrss/{ => csrsrv}/init.c (82%) rename reactos/subsystems/win32/csrss/{csrss.h => csrsrv/srv.h} (71%) delete mode 100644 reactos/subsystems/win32/csrss/print.c delete mode 100644 reactos/subsystems/win32/csrss/video.c diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index c8be7bd6a18..e5fb874f849 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -670,6 +670,7 @@ boot\bootdata\bootcdregtest\regtest.cmd 7 optional ; Subsystems subsystems\win32\csrss\csrss.exe 1 subsystems\win32\csrss\win32csr\win32csr.dll 1 +subsystems\win32\csrss\csrsrv\csrsrv.dll 1 subsystems\ntvdm\ntvdm.exe 1 subsystems\win32\win32k\win32k.sys 1 diff --git a/reactos/subsystems/win32/csrss/api/handle.c b/reactos/subsystems/win32/csrss/csrsrv/api/handle.c similarity index 99% rename from reactos/subsystems/win32/csrss/api/handle.c rename to reactos/subsystems/win32/csrss/csrsrv/api/handle.c index 391896ed28f..eb6c12c0531 100644 --- a/reactos/subsystems/win32/csrss/api/handle.c +++ b/reactos/subsystems/win32/csrss/csrsrv/api/handle.c @@ -9,7 +9,7 @@ /* INCLUDES ******************************************************************/ -#include +#include #define NDEBUG #include diff --git a/reactos/subsystems/win32/csrss/api/process.c b/reactos/subsystems/win32/csrss/csrsrv/api/process.c similarity index 94% rename from reactos/subsystems/win32/csrss/api/process.c rename to reactos/subsystems/win32/csrss/csrsrv/api/process.c index 9bd3cd6ff26..423424b86e3 100644 --- a/reactos/subsystems/win32/csrss/api/process.c +++ b/reactos/subsystems/win32/csrss/csrsrv/api/process.c @@ -8,7 +8,7 @@ /* INCLUDES ******************************************************************/ -#include +#include #define NDEBUG #include @@ -153,6 +153,65 @@ CsrInsertThread(IN PCSRSS_PROCESS_DATA Process, #define CsrAcquireProcessLock() LOCK #define CsrReleaseProcessLock() UNLOCK +VOID +NTAPI +CsrDeallocateThread(IN PCSR_THREAD CsrThread) +{ + /* Free the process object from the heap */ + RtlFreeHeap(CsrHeap, 0, CsrThread); +} + +VOID +NTAPI +CsrRemoveThread(IN PCSR_THREAD CsrThread) +{ + /* Remove it from the List */ + RemoveEntryList(&CsrThread->Link); + + /* Decreate the thread count of the process */ + CsrThread->Process->ThreadCount--; + + /* Remove it from the Hash List as well */ + if (CsrThread->HashLinks.Flink) RemoveEntryList(&CsrThread->HashLinks); + + /* Check if this is the last Thread */ + if (!CsrThread->Process->ThreadCount) + { + /* Check if it's not already been marked for deletion */ + if (!(CsrThread->Process->Flags & CsrProcessLastThreadTerminated)) + { + /* Let everyone know this process is about to lose the thread */ + //CsrThread->Process->Flags |= CsrProcessLastThreadTerminated; + + /* Reference the Process */ + //CsrLockedDereferenceProcess(CsrThread->Process); + } + } + + /* Mark the thread for deletion */ + CsrThread->Flags |= CsrThreadInTermination; +} + +VOID +NTAPI +CsrThreadRefcountZero(IN PCSR_THREAD CsrThread) +{ + /* Remove this thread */ + CsrRemoveThread(CsrThread); + + /* Release the Process Lock */ + //CsrReleaseProcessLock(); + + /* Close the NT Thread Handle */ + if (CsrThread->ThreadHandle) NtClose(CsrThread->ThreadHandle); + + /* De-allocate the CSR Thread Object */ + CsrDeallocateThread(CsrThread); + + /* Remove a reference from the process */ + //CsrDereferenceProcess(CsrProcess); +} + NTSTATUS NTAPI CsrCreateThreadData(IN PCSRSS_PROCESS_DATA CsrProcess, @@ -933,8 +992,21 @@ CSR_API(CsrCreateThread) CSR_API(CsrTerminateProcess) { + PLIST_ENTRY NextEntry; + PCSR_THREAD Thread; Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + NextEntry = ProcessData->ThreadList.Flink; + while (NextEntry != &ProcessData->ThreadList) + { + Thread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link); + NextEntry = NextEntry->Flink; + + CsrThreadRefcountZero(Thread); + + } + ProcessData->Terminated = TRUE; return STATUS_SUCCESS; diff --git a/reactos/subsystems/win32/csrss/api/user.c b/reactos/subsystems/win32/csrss/csrsrv/api/user.c similarity index 98% rename from reactos/subsystems/win32/csrss/api/user.c rename to reactos/subsystems/win32/csrss/csrsrv/api/user.c index d89e463cecc..de4e49f66e1 100644 --- a/reactos/subsystems/win32/csrss/api/user.c +++ b/reactos/subsystems/win32/csrss/csrsrv/api/user.c @@ -11,7 +11,7 @@ /* INCLUDES ******************************************************************/ -#include +#include #define NDEBUG #include diff --git a/reactos/subsystems/win32/csrss/api/wapi.c b/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c similarity index 99% rename from reactos/subsystems/win32/csrss/api/wapi.c rename to reactos/subsystems/win32/csrss/csrsrv/api/wapi.c index a37e601ee8a..88005c6fe7b 100644 --- a/reactos/subsystems/win32/csrss/api/wapi.c +++ b/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c @@ -10,7 +10,7 @@ /* INCLUDES ******************************************************************/ -#include +#include #define NDEBUG diff --git a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild new file mode 100644 index 00000000000..5cd35e28f40 --- /dev/null +++ b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild @@ -0,0 +1,20 @@ + + + + + . + . + include + include/reactos/subsys + ntdll + pseh + smdll + + handle.c + process.c + user.c + wapi.c + + init.c + srv.h + diff --git a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rc b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rc new file mode 100644 index 00000000000..658072d09b8 --- /dev/null +++ b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS CSR Core Server\0" +#define REACTOS_STR_INTERNAL_NAME "csrsrv\0" +#define REACTOS_STR_ORIGINAL_FILENAME "csrsrv.dll\0" +#include diff --git a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec new file mode 100644 index 00000000000..c394d83df49 --- /dev/null +++ b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec @@ -0,0 +1,35 @@ +;@ stdcall CsrAddStaticServerThread(ptr ptr long) +;@ stdcall CsrCallServerFromServer(ptr ptr) +;@ stdcall CsrConnectToUser() +;@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr) +;@ stdcall CsrCreateRemoteThread(ptr ptr) +;@ stdcall CsrCreateThread(ptr ptr ptr) +;@ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr) +;@ stdcall CsrDebugProcess(ptr) +;@ stdcall CsrDebugProcessStop(ptr) +;@ stdcall CsrDereferenceProcess(ptr) +;@ stdcall CsrDereferenceThread(ptr) +;@ stdcall CsrDereferenceWait(ptr) +;@ stdcall CsrDestroyProcess(ptr long) +;@ stdcall CsrDestroyThread(ptr) +;@ stdcall CsrExecServerThread(ptr long) +;@ stdcall CsrGetProcessLuid(ptr ptr) +;@ stdcall CsrImpersonateClient(ptr) +;@ stdcall CsrLockProcessByClientId(ptr ptr) +;@ stdcall CsrLockThreadByClientId(ptr ptr) +;@ stdcall CsrMoveSatisfiedWait(ptr ptr) +;@ stdcall CsrNotifyWait(ptr long ptr ptr) +;@ stdcall CsrPopulateDosDevices() +;@ stdcall CsrQueryApiPort() +;@ stdcall CsrReferenceThread(ptr) +;@ stdcall CsrRevertToSelf() +@ stdcall CsrServerInitialization(long ptr) +;@ stdcall CsrSetBackgroundPriority(ptr) +;@ stdcall CsrSetCallingSpooler(long) +;@ stdcall CsrSetForegroundPriority(ptr) +;@ stdcall CsrShutdownProcesses(ptr long) +;@ stdcall CsrUnhandledExceptionFilter(ptr) +;@ stdcall CsrUnlockProcess(ptr) +;@ stdcall CsrUnlockThread(ptr) +;@ stdcall CsrValidateMessageBuffer(ptr ptr long long) +;@ stdcall CsrValidateMessageString(ptr ptr) diff --git a/reactos/subsystems/win32/csrss/init.c b/reactos/subsystems/win32/csrss/csrsrv/init.c similarity index 82% rename from reactos/subsystems/win32/csrss/init.c rename to reactos/subsystems/win32/csrss/csrsrv/init.c index 2314ab4b8a8..59b69c54e37 100644 --- a/reactos/subsystems/win32/csrss/init.c +++ b/reactos/subsystems/win32/csrss/csrsrv/init.c @@ -1,47 +1,128 @@ -/* $Id$ - * - * reactos/subsys/csrss/init.c - * - * Initialize the CSRSS subsystem server process. - * - * ReactOS Operating System - * +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS CSR Sub System + * FILE: subsys/csr/csrsrv/init.c + * PURPOSE: CSR Server DLL Initialization + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES ******************************************************************/ - -#include +/* INCLUDES *******************************************************************/ +#include "srv.h" #define NDEBUG #include -/* GLOBALS ******************************************************************/ +/* DATA ***********************************************************************/ HANDLE CsrHeap = (HANDLE) 0; - HANDLE CsrObjectDirectory = (HANDLE) 0; - UNICODE_STRING CsrDirectoryName; - extern HANDLE CsrssApiHeap; - static unsigned InitCompleteProcCount; static CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProcs = NULL; - static unsigned HardErrorProcCount; static CSRPLUGIN_HARDERROR_PROC *HardErrorProcs = NULL; - HANDLE hSbApiPort = (HANDLE) 0; - HANDLE hBootstrapOk = (HANDLE) 0; - HANDLE hSmApiPort = (HANDLE) 0; - HANDLE hApiPort = (HANDLE) 0; -/********************************************************************** - * CsrpAddInitCompleteProc/1 - */ +/* PRIVATE FUNCTIONS **********************************************************/ + +ULONG +InitializeVideoAddressSpace(VOID) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory"); + NTSTATUS Status; + HANDLE PhysMemHandle; + PVOID BaseAddress; + LARGE_INTEGER Offset; + SIZE_T ViewSize; + CHAR IVTAndBda[1024+256]; + + /* Open the physical memory section */ + InitializeObjectAttributes(&ObjectAttributes, + &PhysMemName, + 0, + NULL, + NULL); + Status = ZwOpenSection(&PhysMemHandle, + SECTION_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Couldn't open \\Device\\PhysicalMemory\n"); + return 0; + } + + /* Map the BIOS and device registers into the address space */ + Offset.QuadPart = 0xa0000; + ViewSize = 0x100000 - 0xa0000; + BaseAddress = (PVOID)0xa0000; + Status = ZwMapViewOfSection(PhysMemHandle, + NtCurrentProcess(), + &BaseAddress, + 0, + ViewSize, + &Offset, + &ViewSize, + ViewUnmap, + 0, + PAGE_EXECUTE_READWRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Couldn't map physical memory (%x)\n", Status); + ZwClose(PhysMemHandle); + return 0; + } + + /* Close physical memory section handle */ + ZwClose(PhysMemHandle); + + if (BaseAddress != (PVOID)0xa0000) + { + DPRINT1("Couldn't map physical memory at the right address (was %x)\n", + BaseAddress); + return 0; + } + + /* Allocate some low memory to use for the non-BIOS + * parts of the v86 mode address space + */ + BaseAddress = (PVOID)0x1; + ViewSize = 0xa0000 - 0x1000; + Status = ZwAllocateVirtualMemory(NtCurrentProcess(), + &BaseAddress, + 0, + &ViewSize, + MEM_COMMIT, + PAGE_EXECUTE_READWRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status); + return 0; + } + if (BaseAddress != (PVOID)0x0) + { + DPRINT1("Failed to allocate virtual memory at right address (was %x)\n", + BaseAddress); + return 0; + } + + /* Get the real mode IVT and BDA from the kernel */ + Status = NtVdmControl(VdmInitialize, IVTAndBda); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtVdmControl failed (status %x)\n", Status); + return 0; + } + + /* Return success */ + return 1; +} + + static NTSTATUS FASTCALL CsrpAddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc) { @@ -513,48 +594,6 @@ CsrpRegisterSubsystem (int argc, char ** argv, char ** envp) return Status; } -/********************************************************************** - * EnvpToUnicodeString/2 - */ -static ULONG FASTCALL -EnvpToUnicodeString (char ** envp, PUNICODE_STRING UnicodeEnv) -{ - ULONG CharCount = 0; - ULONG Index = 0; - ANSI_STRING AnsiEnv; - - UnicodeEnv->Buffer = NULL; - - for (Index=0; NULL != envp[Index]; Index++) - { - CharCount += strlen (envp[Index]); - ++ CharCount; - } - ++ CharCount; - - AnsiEnv.Buffer = RtlAllocateHeap (RtlGetProcessHeap(), 0, CharCount); - if (NULL != AnsiEnv.Buffer) - { - - PCHAR WritePos = AnsiEnv.Buffer; - - for (Index=0; NULL != envp[Index]; Index++) - { - strcpy (WritePos, envp[Index]); - WritePos += strlen (envp[Index]) + 1; - } - - /* FIXME: the last (double) nullterm should perhaps not be included in Length - * but only in MaximumLength. -Gunnar */ - AnsiEnv.Buffer [CharCount-1] = '\0'; - AnsiEnv.Length = CharCount; - AnsiEnv.MaximumLength = CharCount; - - RtlAnsiStringToUnicodeString (UnicodeEnv, & AnsiEnv, TRUE); - RtlFreeHeap (RtlGetProcessHeap(), 0, AnsiEnv.Buffer); - } - return CharCount; -} /********************************************************************** * CsrpLoadKernelModeDriver/3 */ @@ -565,26 +604,26 @@ CsrpLoadKernelModeDriver (int argc, char ** argv, char ** envp) WCHAR Data [MAX_PATH + 1]; ULONG DataLength = sizeof Data; ULONG DataType = 0; - UNICODE_STRING Environment; + //UNICODE_STRING Environment; - DPRINT("SM: %s called\n", __FUNCTION__); + DPRINT1("SM: %s called\n", __FUNCTION__); - EnvpToUnicodeString (envp, & Environment); + //EnvpToUnicodeString (envp, & Environment); Status = SmLookupSubsystem (L"Kmode", Data, & DataLength, & DataType, - Environment.Buffer); - RtlFreeUnicodeString (& Environment); + NULL); + //RtlFreeUnicodeString (& Environment); if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0])) { WCHAR ImagePath [MAX_PATH + 1] = {0}; UNICODE_STRING ModuleName; - wcscpy (ImagePath, L"\\??\\"); - wcscat (ImagePath, Data); + wcscpy (ImagePath, L"\\??\\c:\\reactos\\system32\\win32k.sys"); +// wcscat (ImagePath, Data); RtlInitUnicodeString (& ModuleName, ImagePath); Status = NtSetSystemInformation(/* FIXME: SystemLoadAndCallImage */ SystemExtendServiceTableInformation, @@ -592,7 +631,7 @@ CsrpLoadKernelModeDriver (int argc, char ** argv, char ** envp) sizeof ModuleName); if(!NT_SUCCESS(Status)) { - DPRINT("WIN: %s: loading Kmode failed (Status=0x%08lx)\n", + DPRINT1("WIN: %s: loading Kmode failed (Status=0x%08lx)\n", __FUNCTION__, Status); } } @@ -718,22 +757,12 @@ struct { {TRUE, CsrpRunWinlogon, "run WinLogon"}, }; -/********************************************************************** - * NAME - * CsrServerInitialization - * - * DESCRIPTION - * Initialize the Win32 environment subsystem server. - * - * RETURN VALUE - * TRUE: Initialization OK; otherwise FALSE. - */ -BOOL WINAPI -CsrServerInitialization ( - int argc, - char ** argv, - char ** envp - ) +/* PUBLIC FUNCTIONS ***********************************************************/ + +NTSTATUS +NTAPI +CsrServerInitialization(ULONG ArgumentCount, + PCHAR Arguments[]) { UINT i = 0; NTSTATUS Status = STATUS_SUCCESS; @@ -742,7 +771,7 @@ CsrServerInitialization ( for (i=0; i < (sizeof InitRoutine / sizeof InitRoutine[0]); i++) { - Status = InitRoutine[i].EntryPoint(argc,argv,envp); + Status = InitRoutine[i].EntryPoint(ArgumentCount,Arguments,NULL); if(!NT_SUCCESS(Status)) { DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n", @@ -758,9 +787,23 @@ CsrServerInitialization ( if (CallInitComplete()) { Status = SmCompleteSession (hSmApiPort,hSbApiPort,hApiPort); - return TRUE; + return STATUS_SUCCESS; } - return FALSE; + + return STATUS_UNSUCCESSFUL; +} + +BOOL +NTAPI +DllMainCRTStartup(HANDLE hDll, + DWORD dwReason, + LPVOID lpReserved) +{ + /* We don't do much */ + UNREFERENCED_PARAMETER(hDll); + UNREFERENCED_PARAMETER(dwReason); + UNREFERENCED_PARAMETER(lpReserved); + return TRUE; } /* EOF */ diff --git a/reactos/subsystems/win32/csrss/csrss.h b/reactos/subsystems/win32/csrss/csrsrv/srv.h similarity index 71% rename from reactos/subsystems/win32/csrss/csrss.h rename to reactos/subsystems/win32/csrss/csrsrv/srv.h index 447c2e03521..cc11b70603c 100644 --- a/reactos/subsystems/win32/csrss/csrss.h +++ b/reactos/subsystems/win32/csrss/csrsrv/srv.h @@ -1,14 +1,16 @@ /* PSDK/NDK Headers */ +#define NTOS_MODE_USER #include #define WIN32_NO_STATUS #include -#define NTOS_MODE_USER +#include #include -#include +/* CSR Header */ +//#include -/* Build Number */ -#include +/* PSEH for SEH Support */ +#include /* Subsystem Manager Header */ #include @@ -17,5 +19,3 @@ #include #include #include - -/* EOF */ diff --git a/reactos/subsystems/win32/csrss/csrss.c b/reactos/subsystems/win32/csrss/csrss.c index 07027c75f17..c5f574584fb 100644 --- a/reactos/subsystems/win32/csrss/csrss.c +++ b/reactos/subsystems/win32/csrss/csrss.c @@ -1,62 +1,70 @@ -/* $Id$ - * - * csrss.c - Client/Server Runtime subsystem - * - * ReactOS Operating System - * - * -------------------------------------------------------------------- - * - * 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. - * - * -------------------------------------------------------------------- +/* + * PROJECT: ReactOS Client Server Runtime SubSystem (CSRSS) + * LICENSE: BSD - See COPYING.ARM in root directory + * FILE: subsystems/win32/csrss/csrss.c + * PURPOSE: Main Executable Code + * PROGRAMMERS: Alex Ionescu + * ReactOS Portable Systems Group */ -#include +/* INCLUDES *******************************************************************/ +#define WIN32_NO_STATUS +#include +#include +#include #define NDEBUG #include -int _cdecl _main(int argc, - char *argv[], - char *envp[], - int DebugFlag) +/* FUNCTIONS ******************************************************************/ + +VOID +NTAPI +CsrpSetDefaultProcessHardErrorMode(VOID) { - NTSTATUS Status = STATUS_SUCCESS; + ULONG DefaultHardErrorMode = 0; - //PrintString("ReactOS Client/Server Run-Time (Build %s)\n", - //KERNEL_VERSION_BUILD_STR); + /* Disable hard errors */ + NtSetInformationProcess(NtCurrentProcess(), + ProcessDefaultHardErrorMode, + &DefaultHardErrorMode, + sizeof(DefaultHardErrorMode)); +} - /*================================================================== - * Initialize the Win32 environment subsystem server. - *================================================================*/ - if (CsrServerInitialization (argc, argv, envp) == TRUE) - { - /* - * Terminate the current thread only. - */ - Status = NtTerminateThread (NtCurrentThread(), 0); - } - else - { - DisplayString (L"CSR: CsrServerInitialization failed.\n"); - /* - * Tell the SM we failed. - */ - Status = NtTerminateProcess (NtCurrentProcess(), 0); - } - return (int) Status; +int +_cdecl +_main(int argc, + char *argv[], + char *envp[], + int DebugFlag) +{ + KPRIORITY BasePriority = (8 + 1) + 4; + NTSTATUS Status; + + /* Set the Priority */ + NtSetInformationProcess(NtCurrentProcess(), + ProcessBasePriority, + &BasePriority, + sizeof(KPRIORITY)); + + /* Initialize CSR through CSRSRV */ + Status = CsrServerInitialization(argc, argv); + if (!NT_SUCCESS(Status)) + { + /* Kill us */ + DPRINT1("CSRSS: CsrServerInitialization failed:% lx\n", Status); + NtTerminateProcess(NtCurrentProcess(), Status); + } + + /* Disable errors */ + CsrpSetDefaultProcessHardErrorMode(); + + /* If this is Session 0, make sure killing us bugchecks the system */ + if (!NtCurrentPeb()->SessionId) RtlSetProcessIsCritical(TRUE, NULL, FALSE); + + /* Kill this thread. CSRSRV keeps us going */ + NtTerminateThread (NtCurrentThread(), Status); + return 0; } /* EOF */ diff --git a/reactos/subsystems/win32/csrss/csrss.rbuild b/reactos/subsystems/win32/csrss/csrss.rbuild index f3c9df8c87d..438b2e6574a 100644 --- a/reactos/subsystems/win32/csrss/csrss.rbuild +++ b/reactos/subsystems/win32/csrss/csrss.rbuild @@ -9,21 +9,14 @@ -fms-extensions nt ntdll - smdll - - handle.c - process.c - user.c - wapi.c - - csrss.h + csrsrv csrss.c - init.c - print.c - video.c csrss.rc + + + diff --git a/reactos/subsystems/win32/csrss/include/api.h b/reactos/subsystems/win32/csrss/include/api.h index 4a17341f37f..463ee50c002 100644 --- a/reactos/subsystems/win32/csrss/include/api.h +++ b/reactos/subsystems/win32/csrss/include/api.h @@ -13,6 +13,14 @@ #include +typedef enum _CSR_THREAD_FLAGS +{ + CsrThreadAltertable = 0x1, + CsrThreadInTermination = 0x2, + CsrThreadTerminated = 0x4, + CsrThreadIsServerThread = 0x10 +} CSR_THREAD_FLAGS, *PCSR_THREAD_FLAGS; + typedef enum _SHUTDOWN_RESULT { CsrShutdownCsrProcess = 1, @@ -179,7 +187,7 @@ NTSTATUS FASTCALL CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefin NTSTATUS WINAPI CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object, DWORD Access, BOOL Inheritable ); NTSTATUS WINAPI CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData, PCSRSS_PROCESS_DATA TargetProcessData); NTSTATUS WINAPI CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object, DWORD Access ); -BOOL WINAPI CsrServerInitialization (int,char**,char**); +NTSTATUS NTAPI CsrServerInitialization(ULONG ArgumentCount, PCHAR Arguments[]); NTSTATUS WINAPI CsrReleaseObjectByPointer(Object_t *Object); NTSTATUS WINAPI CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); NTSTATUS WINAPI CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); diff --git a/reactos/subsystems/win32/csrss/print.c b/reactos/subsystems/win32/csrss/print.c deleted file mode 100644 index 3e5949d073a..00000000000 --- a/reactos/subsystems/win32/csrss/print.c +++ /dev/null @@ -1,61 +0,0 @@ -/* $Id$ - * - * smss.c - Session Manager - * - * ReactOS Operating System - * - * -------------------------------------------------------------------- - * - * 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. - * - * -------------------------------------------------------------------- - * - * 19990529 (Emanuele Aliberti) - * Compiled successfully with egcs 1.1.2 - */ - -#include - -#define NDEBUG -#include - -VOID WINAPI DisplayString(LPCWSTR lpwString) -{ - UNICODE_STRING us; - - RtlInitUnicodeString (&us, lpwString); - ZwDisplayString (&us); -} - -VOID WINAPI PrintString (char* fmt, ...) -{ - char buffer[512]; - va_list ap; - UNICODE_STRING UnicodeString; - ANSI_STRING AnsiString; - - va_start(ap, fmt); - vsprintf(buffer, fmt, ap); - va_end(ap); - - RtlInitAnsiString (&AnsiString, buffer); - RtlAnsiStringToUnicodeString (&UnicodeString, - &AnsiString, - TRUE); - NtDisplayString(&UnicodeString); - RtlFreeUnicodeString (&UnicodeString); -} - -/* EOF */ diff --git a/reactos/subsystems/win32/csrss/video.c b/reactos/subsystems/win32/csrss/video.c deleted file mode 100644 index 8282c15bd7a..00000000000 --- a/reactos/subsystems/win32/csrss/video.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * PROJECT: ReactOS Client/Server Runtime subsystem - * LICENSE: GPL v2 or later - See COPYING in the top level directory - * FILE: subsystems/win32/csrss/video.c - * PURPOSE: Video memory initialization. - * PROGRAMMERS: ReactOS Development Team - */ - -/* INCLUDES ******************************************************************/ - -#include - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -ULONG -InitializeVideoAddressSpace(VOID) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory"); - NTSTATUS Status; - HANDLE PhysMemHandle; - PVOID BaseAddress; - LARGE_INTEGER Offset; - SIZE_T ViewSize; - CHAR IVTAndBda[1024+256]; - - /* Open the physical memory section */ - InitializeObjectAttributes(&ObjectAttributes, - &PhysMemName, - 0, - NULL, - NULL); - Status = ZwOpenSection(&PhysMemHandle, - SECTION_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Couldn't open \\Device\\PhysicalMemory\n"); - return 0; - } - - /* Map the BIOS and device registers into the address space */ - Offset.QuadPart = 0xa0000; - ViewSize = 0x100000 - 0xa0000; - BaseAddress = (PVOID)0xa0000; - Status = ZwMapViewOfSection(PhysMemHandle, - NtCurrentProcess(), - &BaseAddress, - 0, - ViewSize, - &Offset, - &ViewSize, - ViewUnmap, - 0, - PAGE_EXECUTE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Couldn't map physical memory (%x)\n", Status); - ZwClose(PhysMemHandle); - return 0; - } - - /* Close physical memory section handle */ - ZwClose(PhysMemHandle); - - if (BaseAddress != (PVOID)0xa0000) - { - DPRINT1("Couldn't map physical memory at the right address (was %x)\n", - BaseAddress); - return 0; - } - - /* Allocate some low memory to use for the non-BIOS - * parts of the v86 mode address space - */ - BaseAddress = (PVOID)0x1; - ViewSize = 0xa0000 - 0x1000; - Status = ZwAllocateVirtualMemory(NtCurrentProcess(), - &BaseAddress, - 0, - &ViewSize, - MEM_COMMIT, - PAGE_EXECUTE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status); - return 0; - } - if (BaseAddress != (PVOID)0x0) - { - DPRINT1("Failed to allocate virtual memory at right address (was %x)\n", - BaseAddress); - return 0; - } - - /* Get the real mode IVT and BDA from the kernel */ - Status = NtVdmControl(VdmInitialize, IVTAndBda); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtVdmControl failed (status %x)\n", Status); - return 0; - } - - /* Return success */ - return 1; -} - -/* EOF */ From 34fa6fb97b3f5892d0c8b9681b95e4cf06ece3aa Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Wed, 10 Mar 2010 06:49:53 +0000 Subject: [PATCH 17/64] [CSRSRV]: Move the new process/thread management functions into new, dedicated files. Export some of the functions, so that win32csr can use them by linking to csrsrv. Last change needed for barebones user-mode shutdown support. svn path=/trunk/; revision=46052 --- .../win32/csrss/csrsrv/api/process.c | 696 +----------------- .../win32/csrss/csrsrv/csrsrv.rbuild | 2 + .../subsystems/win32/csrss/csrsrv/csrsrv.spec | 14 +- reactos/subsystems/win32/csrss/csrsrv/init.c | 2 +- .../subsystems/win32/csrss/csrsrv/procsup.c | 447 +++++++++++ .../subsystems/win32/csrss/csrsrv/thredsup.c | 306 ++++++++ reactos/subsystems/win32/csrss/include/api.h | 10 +- 7 files changed, 778 insertions(+), 699 deletions(-) create mode 100644 reactos/subsystems/win32/csrss/csrsrv/procsup.c create mode 100644 reactos/subsystems/win32/csrss/csrsrv/thredsup.c diff --git a/reactos/subsystems/win32/csrss/csrsrv/api/process.c b/reactos/subsystems/win32/csrss/csrsrv/api/process.c index 423424b86e3..5fcac045c70 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/api/process.c +++ b/reactos/subsystems/win32/csrss/csrsrv/api/process.c @@ -15,298 +15,19 @@ #define LOCK RtlEnterCriticalSection(&ProcessDataLock) #define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock) +#define CsrAcquireProcessLock() LOCK +#define CsrReleaseProcessLock() UNLOCK /* GLOBALS *******************************************************************/ static ULONG NrProcess; -static PCSRSS_PROCESS_DATA ProcessData[256]; +PCSRSS_PROCESS_DATA ProcessData[256]; RTL_CRITICAL_SECTION ProcessDataLock; +extern PCSRSS_PROCESS_DATA CsrRootProcess; +extern LIST_ENTRY CsrThreadHashTable[256]; /* FUNCTIONS *****************************************************************/ -#define CsrHeap RtlGetProcessHeap() - -#define CsrHashThread(t) \ - (HandleToUlong(t)&(256 - 1)) - -LIST_ENTRY CsrThreadHashTable[256]; -PCSRSS_PROCESS_DATA CsrRootProcess; - -PCSR_THREAD -NTAPI -CsrAllocateThread(IN PCSRSS_PROCESS_DATA CsrProcess) -{ - PCSR_THREAD CsrThread; - - /* Allocate the structure */ - CsrThread = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, sizeof(CSR_THREAD)); - if (!CsrThread) return(NULL); - - /* Reference the Thread and Process */ - CsrThread->ReferenceCount++; - // CsrProcess->ReferenceCount++; - - /* Set the Parent Process */ - CsrThread->Process = CsrProcess; - - /* Return Thread */ - return CsrThread; -} - -PCSR_THREAD -NTAPI -CsrLocateThreadByClientId(OUT PCSRSS_PROCESS_DATA *Process OPTIONAL, - IN PCLIENT_ID ClientId) -{ - ULONG i; - PLIST_ENTRY ListHead, NextEntry; - PCSR_THREAD FoundThread; - - /* Hash the Thread */ - i = CsrHashThread(ClientId->UniqueThread); - - /* Set the list pointers */ - ListHead = &CsrThreadHashTable[i]; - NextEntry = ListHead->Flink; - - /* Star the loop */ - while (NextEntry != ListHead) - { - /* Get the thread */ - FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks); - - /* Compare the CID */ - if (FoundThread->ClientId.UniqueThread == ClientId->UniqueThread) - { - /* Match found, return the process */ - *Process = FoundThread->Process; - - /* Return thread too */ -// DPRINT1("Found: %p %p\n", FoundThread, FoundThread->Process); - return FoundThread; - } - - /* Next */ - NextEntry = NextEntry->Flink; - } - - /* Nothing found */ - return NULL; -} - -PCSR_THREAD -NTAPI -CsrLocateThreadInProcess(IN PCSRSS_PROCESS_DATA CsrProcess OPTIONAL, - IN PCLIENT_ID Cid) -{ - PLIST_ENTRY ListHead, NextEntry; - PCSR_THREAD FoundThread = NULL; - - /* Use the Root Process if none was specified */ - if (!CsrProcess) CsrProcess = CsrRootProcess; - - /* Save the List pointers */ -// DPRINT1("Searching in: %p %d\n", CsrProcess, CsrProcess->ThreadCount); - ListHead = &CsrProcess->ThreadList; - NextEntry = ListHead->Flink; - - /* Start the Loop */ - while (NextEntry != ListHead) - { - /* Get Thread Entry */ - FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link); - - /* Check for TID Match */ - if (FoundThread->ClientId.UniqueThread == Cid->UniqueThread) break; - - /* Next entry */ - NextEntry = NextEntry->Flink; - } - - /* Return what we found */ -// DPRINT1("Found: %p\n", FoundThread); - return FoundThread; -} - -VOID -NTAPI -CsrInsertThread(IN PCSRSS_PROCESS_DATA Process, - IN PCSR_THREAD Thread) -{ - ULONG i; - - /* Insert it into the Regular List */ - InsertTailList(&Process->ThreadList, &Thread->Link); - - /* Increase Thread Count */ - Process->ThreadCount++; - - /* Hash the Thread */ - i = CsrHashThread(Thread->ClientId.UniqueThread); -// DPRINT1("TID %lx HASH: %lx\n", Thread->ClientId.UniqueThread, i); - - /* Insert it there too */ - InsertHeadList(&CsrThreadHashTable[i], &Thread->HashLinks); -} - - -#define CsrAcquireProcessLock() LOCK -#define CsrReleaseProcessLock() UNLOCK - -VOID -NTAPI -CsrDeallocateThread(IN PCSR_THREAD CsrThread) -{ - /* Free the process object from the heap */ - RtlFreeHeap(CsrHeap, 0, CsrThread); -} - -VOID -NTAPI -CsrRemoveThread(IN PCSR_THREAD CsrThread) -{ - /* Remove it from the List */ - RemoveEntryList(&CsrThread->Link); - - /* Decreate the thread count of the process */ - CsrThread->Process->ThreadCount--; - - /* Remove it from the Hash List as well */ - if (CsrThread->HashLinks.Flink) RemoveEntryList(&CsrThread->HashLinks); - - /* Check if this is the last Thread */ - if (!CsrThread->Process->ThreadCount) - { - /* Check if it's not already been marked for deletion */ - if (!(CsrThread->Process->Flags & CsrProcessLastThreadTerminated)) - { - /* Let everyone know this process is about to lose the thread */ - //CsrThread->Process->Flags |= CsrProcessLastThreadTerminated; - - /* Reference the Process */ - //CsrLockedDereferenceProcess(CsrThread->Process); - } - } - - /* Mark the thread for deletion */ - CsrThread->Flags |= CsrThreadInTermination; -} - -VOID -NTAPI -CsrThreadRefcountZero(IN PCSR_THREAD CsrThread) -{ - /* Remove this thread */ - CsrRemoveThread(CsrThread); - - /* Release the Process Lock */ - //CsrReleaseProcessLock(); - - /* Close the NT Thread Handle */ - if (CsrThread->ThreadHandle) NtClose(CsrThread->ThreadHandle); - - /* De-allocate the CSR Thread Object */ - CsrDeallocateThread(CsrThread); - - /* Remove a reference from the process */ - //CsrDereferenceProcess(CsrProcess); -} - -NTSTATUS -NTAPI -CsrCreateThreadData(IN PCSRSS_PROCESS_DATA CsrProcess, - IN HANDLE hThread, - IN PCLIENT_ID ClientId) -{ - NTSTATUS Status; - PCSR_THREAD CsrThread; - //PCSRSS_PROCESS_DATA CurrentProcess; - PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; - CLIENT_ID CurrentCid; - KERNEL_USER_TIMES KernelTimes; - -// DPRINT1("CSRSRV: %s called\n", __FUNCTION__); - - /* Get the current thread and CID */ - CurrentCid = CurrentThread->ClientId; -// DPRINT1("CALLER PID/TID: %lx/%lx\n", CurrentCid.UniqueProcess, CurrentCid.UniqueThread); - - /* Acquire the Process Lock */ - CsrAcquireProcessLock(); -#if 0 - /* Get the current Process and make sure the Thread is valid with this CID */ - CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, - &CurrentCid); - - /* Something is wrong if we get an empty thread back */ - if (!CurrentThread) - { - DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__); - CsrReleaseProcessLock(); - return STATUS_THREAD_IS_TERMINATING; - } -#endif - /* Get the Thread Create Time */ - Status = NtQueryInformationThread(hThread, - ThreadTimes, - (PVOID)&KernelTimes, - sizeof(KernelTimes), - NULL); - - /* Allocate a CSR Thread Structure */ - if (!(CsrThread = CsrAllocateThread(CsrProcess))) - { - DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__); - CsrReleaseProcessLock(); - return STATUS_NO_MEMORY; - } - - /* Save the data we have */ - CsrThread->CreateTime = KernelTimes.CreateTime; - CsrThread->ClientId = *ClientId; - CsrThread->ThreadHandle = hThread; - CsrThread->Flags = 0; - - /* Insert the Thread into the Process */ - CsrInsertThread(CsrProcess, CsrThread); - - /* Release the lock and return */ - CsrReleaseProcessLock(); - return STATUS_SUCCESS; -} - -PCSR_THREAD -NTAPI -CsrAddStaticServerThread(IN HANDLE hThread, - IN PCLIENT_ID ClientId, - IN ULONG ThreadFlags) -{ - PCSR_THREAD CsrThread; - - /* Get the Lock */ - CsrAcquireProcessLock(); - - /* Allocate the Server Thread */ - if ((CsrThread = CsrAllocateThread(CsrRootProcess))) - { - /* Setup the Object */ -// DPRINT1("New CSR thread created: %lx PID/TID: %lx/%lx\n", CsrThread, ClientId->UniqueProcess, ClientId->UniqueThread); - CsrThread->ThreadHandle = hThread; - CsrThread->ClientId = *ClientId; - CsrThread->Flags = ThreadFlags; - - /* Insert it into the Thread List */ - InsertTailList(&CsrRootProcess->ThreadList, &CsrThread->Link); - - /* Increment the thread count */ - CsrRootProcess->ThreadCount++; - } - - /* Release the Process Lock and return */ - CsrReleaseProcessLock(); - return CsrThread; -} - VOID WINAPI CsrInitProcessData(VOID) { ULONG i; @@ -477,409 +198,6 @@ NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid) return STATUS_INVALID_PARAMETER; } -VOID -NTAPI -CsrSetToNormalPriority(VOID) -{ - KPRIORITY BasePriority = (8 + 1) + 4; - - /* Set the Priority */ - NtSetInformationProcess(NtCurrentProcess(), - ProcessBasePriority, - &BasePriority, - sizeof(KPRIORITY)); -} - -VOID -NTAPI -CsrSetToShutdownPriority(VOID) -{ - KPRIORITY SetBasePriority = (8 + 1) + 6; - BOOLEAN Old; - - /* Get the shutdown privilege */ - if (NT_SUCCESS(RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, - TRUE, - FALSE, - &Old))) - { - /* Set the Priority */ - NtSetInformationProcess(NtCurrentProcess(), - ProcessBasePriority, - &SetBasePriority, - sizeof(KPRIORITY)); - } -} - -NTSTATUS -NTAPI -CsrGetProcessLuid(HANDLE hProcess OPTIONAL, - PLUID Luid) -{ - HANDLE hToken = NULL; - NTSTATUS Status; - ULONG Length; - PTOKEN_STATISTICS TokenStats; - - /* Check if we have a handle to a CSR Process */ - if (!hProcess) - { - /* We don't, so try opening the Thread's Token */ - Status = NtOpenThreadToken(NtCurrentThread(), - TOKEN_QUERY, - FALSE, - &hToken); - - /* Check for success */ - if (!NT_SUCCESS(Status)) - { - /* If we got some other failure, then return and quit */ - if (Status != STATUS_NO_TOKEN) return Status; - - /* We don't have a Thread Token, use a Process Token */ - hProcess = NtCurrentProcess(); - hToken = NULL; - } - } - - /* Check if we have a token by now */ - if (!hToken) - { - /* No token yet, so open the Process Token */ - Status = NtOpenProcessToken(hProcess, - TOKEN_QUERY, - &hToken); - if (!NT_SUCCESS(Status)) - { - /* Still no token, return the error */ - return Status; - } - } - - /* Now get the size we'll need for the Token Information */ - Status = NtQueryInformationToken(hToken, - TokenStatistics, - NULL, - 0, - &Length); - - /* Allocate memory for the Token Info */ - if (!(TokenStats = RtlAllocateHeap(CsrHeap, 0, Length))) - { - /* Fail and close the token */ - NtClose(hToken); - return STATUS_NO_MEMORY; - } - - /* Now query the information */ - Status = NtQueryInformationToken(hToken, - TokenStatistics, - TokenStats, - Length, - &Length); - - /* Close the handle */ - NtClose(hToken); - - /* Check for success */ - if (NT_SUCCESS(Status)) - { - /* Return the LUID */ - *Luid = TokenStats->AuthenticationId; - } - - /* Free the query information */ - RtlFreeHeap(CsrHeap, 0, TokenStats); - - /* Return the Status */ - return Status; -} - -SECURITY_QUALITY_OF_SERVICE CsrSecurityQos = -{ - sizeof(SECURITY_QUALITY_OF_SERVICE), - SecurityImpersonation, - SECURITY_STATIC_TRACKING, - FALSE -}; - -BOOLEAN -NTAPI -CsrImpersonateClient(IN PCSR_THREAD CsrThread) -{ - NTSTATUS Status; - PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; - - /* Use the current thread if none given */ - if (!CsrThread) CsrThread = CurrentThread; - - /* Still no thread, something is wrong */ - if (!CsrThread) - { - /* Failure */ - return FALSE; - } - - /* Make the call */ - Status = NtImpersonateThread(NtCurrentThread(), - CsrThread->ThreadHandle, - &CsrSecurityQos); - - if (!NT_SUCCESS(Status)) - { - /* Failure */ - return FALSE; - } - - /* Increase the impersonation count for the current thread */ - if (CurrentThread) ++CurrentThread->ImpersonationCount; - - /* Return Success */ - return TRUE; -} - -BOOLEAN -NTAPI -CsrRevertToSelf(VOID) -{ - NTSTATUS Status; - PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; - HANDLE ImpersonationToken = NULL; - - /* Check if we have a Current Thread */ - if (CurrentThread) - { - /* Make sure impersonation is on */ - if (!CurrentThread->ImpersonationCount) - { - return FALSE; - } - else if (--CurrentThread->ImpersonationCount > 0) - { - /* Success; impersonation count decreased but still not zero */ - return TRUE; - } - } - - /* Impersonation has been totally removed, revert to ourselves */ - Status = NtSetInformationThread(NtCurrentThread(), - ThreadImpersonationToken, - &ImpersonationToken, - sizeof(HANDLE)); - - /* Return TRUE or FALSE */ - return NT_SUCCESS(Status); -} - -PCSRSS_PROCESS_DATA -NTAPI -FindProcessForShutdown(IN PLUID CallerLuid) -{ - ULONG Hash; - PCSRSS_PROCESS_DATA CsrProcess, ReturnCsrProcess = NULL; - NTSTATUS Status; - ULONG Level = 0; - LUID ProcessLuid; - LUID SystemLuid = SYSTEM_LUID; - BOOLEAN IsSystemLuid = FALSE, IsOurLuid = FALSE; - - for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++) - { - /* Get this process hash bucket */ - CsrProcess = ProcessData[Hash]; - while (CsrProcess) - { - /* Skip this process if it's already been processed*/ - if (CsrProcess->Flags & CsrProcessSkipShutdown) goto Next; - - /* Get the LUID of this Process */ - Status = CsrGetProcessLuid(CsrProcess->Process, &ProcessLuid); - - /* Check if we didn't get access to the LUID */ - if (Status == STATUS_ACCESS_DENIED) - { - /* FIXME:Check if we have any threads */ - } - - if (!NT_SUCCESS(Status)) - { - /* We didn't have access, so skip it */ - CsrProcess->Flags |= CsrProcessSkipShutdown; - goto Next; - } - - /* Check if this is the System LUID */ - if ((IsSystemLuid = RtlEqualLuid(&ProcessLuid, &SystemLuid))) - { - /* Mark this process */ - CsrProcess->ShutdownFlags |= CsrShutdownSystem; - } - else if (!(IsOurLuid = RtlEqualLuid(&ProcessLuid, CallerLuid))) - { - /* Our LUID doesn't match with the caller's */ - CsrProcess->ShutdownFlags |= CsrShutdownOther; - } - - /* Check if we're past the previous level */ - if (CsrProcess->ShutdownLevel > Level) - { - /* Update the level */ - Level = CsrProcess->ShutdownLevel; - - /* Set the final process */ - ReturnCsrProcess = CsrProcess; - } -Next: - /* Next process */ - CsrProcess = CsrProcess->next; - } - } - - /* Check if we found a process */ - if (ReturnCsrProcess) - { - /* Skip this one next time */ - ReturnCsrProcess->Flags |= CsrProcessSkipShutdown; - } - - return ReturnCsrProcess; -} - -/* This is really "CsrShutdownProcess", mostly */ -NTSTATUS -WINAPI -CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc, - IN PVOID Context) -{ - PVOID* RealContext = (PVOID*)Context; - PLUID CallerLuid = RealContext[0]; - PCSRSS_PROCESS_DATA CsrProcess = NULL; - NTSTATUS Status = STATUS_UNSUCCESSFUL; - BOOLEAN FirstTry; - ULONG Result = 0; - ULONG Hash; - - /* Acquire process lock */ - CsrAcquireProcessLock(); - - /* Start the loop */ - for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++) - { - /* Get the Process */ - CsrProcess = ProcessData[Hash]; - while (CsrProcess) - { - /* Remove the skip flag, set shutdown flags to 0*/ - CsrProcess->Flags &= ~CsrProcessSkipShutdown; - CsrProcess->ShutdownFlags = 0; - - /* Move to the next */ - CsrProcess = CsrProcess->next; - } - } - - /* Set shudown Priority */ - CsrSetToShutdownPriority(); - - /* Loop all processes */ - DPRINT1("Enumerating for LUID: %lx %lx\n", CallerLuid->HighPart, CallerLuid->LowPart); - - /* Start looping */ - while (TRUE) - { - /* Find the next process to shutdown */ - FirstTry = TRUE; - if (!(CsrProcess = FindProcessForShutdown(CallerLuid))) - { - /* Done, quit */ - CsrReleaseProcessLock(); - Status = STATUS_SUCCESS; - goto Quickie; - } - -LoopAgain: - /* Release the lock, make the callback, and acquire it back */ - DPRINT1("Found process: %lx\n", CsrProcess->ProcessId); - CsrReleaseProcessLock(); - Result = (ULONG)EnumProc(CsrProcess, (PVOID)((ULONG_PTR)Context | FirstTry)); - CsrAcquireProcessLock(); - - /* Check the result */ - DPRINT1("Result: %d\n", Result); - if (Result == CsrShutdownCsrProcess) - { - /* The callback unlocked the process */ - break; - } - else if (Result == CsrShutdownNonCsrProcess) - { - /* A non-CSR process, the callback didn't touch it */ - //continue; - } - else if (Result == CsrShutdownCancelled) - { - /* Shutdown was cancelled, unlock and exit */ - CsrReleaseProcessLock(); - Status = STATUS_CANCELLED; - goto Quickie; - } - - /* No matches during the first try, so loop again */ - if (FirstTry && Result == CsrShutdownNonCsrProcess) - { - FirstTry = FALSE; - goto LoopAgain; - } - } - -Quickie: - /* Return to normal priority */ - CsrSetToNormalPriority(); - return Status; -} - -NTSTATUS -NTAPI -CsrLockProcessByClientId(IN HANDLE Pid, - OUT PCSRSS_PROCESS_DATA *CsrProcess OPTIONAL) -{ - ULONG Hash; - PCSRSS_PROCESS_DATA CurrentProcess = NULL; - NTSTATUS Status = STATUS_UNSUCCESSFUL; - - /* Acquire the lock */ - CsrAcquireProcessLock(); - - /* Start the loop */ - for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++) - { - /* Get the Process */ - CurrentProcess = ProcessData[Hash]; - while (CurrentProcess) - { - /* Check for PID match */ - if (CurrentProcess->ProcessId == Pid) - { - /* Get out of here with success */ -// DPRINT1("Found %p for PID %lx\n", CurrentProcess, Pid); - Status = STATUS_SUCCESS; - goto Found; - } - - /* Move to the next */ - CurrentProcess = CurrentProcess->next; - } - } - - /* Nothing found, release the lock */ -Found: - if (!CurrentProcess) CsrReleaseProcessLock(); - - /* Return the status and process */ - if (CsrProcess) *CsrProcess = CurrentProcess; - return Status; -} - /********************************************************************** * CSRSS API *********************************************************************/ @@ -920,7 +238,7 @@ CSR_API(CsrCreateProcess) return(STATUS_SUCCESS); } -CSR_API(CsrCreateThread) +CSR_API(CsrSrvCreateThread) { PCSR_THREAD CurrentThread; HANDLE ThreadHandle; @@ -979,7 +297,7 @@ CSR_API(CsrCreateThread) Status = STATUS_SUCCESS; // hack if (NT_SUCCESS(Status)) { - Status = CsrCreateThreadData(CsrProcess, + Status = CsrCreateThread(CsrProcess, ThreadHandle, &Request->Data.CreateThreadRequest.ClientId); // DPRINT1("Create status: %lx\n", Status); diff --git a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild index 5cd35e28f40..3f002106bfe 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild +++ b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild @@ -15,6 +15,8 @@ user.c wapi.c + procsup.c + thredsup.c init.c srv.h diff --git a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec index c394d83df49..d3e7b64f40f 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec +++ b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec @@ -1,9 +1,9 @@ -;@ stdcall CsrAddStaticServerThread(ptr ptr long) +@ stdcall CsrAddStaticServerThread(ptr ptr long) ;@ stdcall CsrCallServerFromServer(ptr ptr) ;@ stdcall CsrConnectToUser() ;@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr) ;@ stdcall CsrCreateRemoteThread(ptr ptr) -;@ stdcall CsrCreateThread(ptr ptr ptr) +@ stdcall CsrCreateThread(ptr ptr ptr) ;@ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr) ;@ stdcall CsrDebugProcess(ptr) ;@ stdcall CsrDebugProcessStop(ptr) @@ -13,23 +13,23 @@ ;@ stdcall CsrDestroyProcess(ptr long) ;@ stdcall CsrDestroyThread(ptr) ;@ stdcall CsrExecServerThread(ptr long) -;@ stdcall CsrGetProcessLuid(ptr ptr) -;@ stdcall CsrImpersonateClient(ptr) -;@ stdcall CsrLockProcessByClientId(ptr ptr) +@ stdcall CsrGetProcessLuid(ptr ptr) +@ stdcall CsrImpersonateClient(ptr) +@ stdcall CsrLockProcessByClientId(ptr ptr) ;@ stdcall CsrLockThreadByClientId(ptr ptr) ;@ stdcall CsrMoveSatisfiedWait(ptr ptr) ;@ stdcall CsrNotifyWait(ptr long ptr ptr) ;@ stdcall CsrPopulateDosDevices() ;@ stdcall CsrQueryApiPort() ;@ stdcall CsrReferenceThread(ptr) -;@ stdcall CsrRevertToSelf() +@ stdcall CsrRevertToSelf() @ stdcall CsrServerInitialization(long ptr) ;@ stdcall CsrSetBackgroundPriority(ptr) ;@ stdcall CsrSetCallingSpooler(long) ;@ stdcall CsrSetForegroundPriority(ptr) ;@ stdcall CsrShutdownProcesses(ptr long) ;@ stdcall CsrUnhandledExceptionFilter(ptr) -;@ stdcall CsrUnlockProcess(ptr) +@ stdcall CsrUnlockProcess(ptr) ;@ stdcall CsrUnlockThread(ptr) ;@ stdcall CsrValidateMessageBuffer(ptr ptr long long) ;@ stdcall CsrValidateMessageString(ptr ptr) diff --git a/reactos/subsystems/win32/csrss/csrsrv/init.c b/reactos/subsystems/win32/csrss/csrsrv/init.c index 59b69c54e37..c6fa69b42de 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/init.c +++ b/reactos/subsystems/win32/csrss/csrsrv/init.c @@ -364,7 +364,7 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp) CSRSS_API_DEFINITION NativeDefinitions[] = { CSRSS_DEFINE_API(CREATE_PROCESS, CsrCreateProcess), - CSRSS_DEFINE_API(CREATE_THREAD, CsrCreateThread), + CSRSS_DEFINE_API(CREATE_THREAD, CsrSrvCreateThread), CSRSS_DEFINE_API(TERMINATE_PROCESS, CsrTerminateProcess), CSRSS_DEFINE_API(CONNECT_PROCESS, CsrConnectProcess), CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS, CsrRegisterServicesProcess), diff --git a/reactos/subsystems/win32/csrss/csrsrv/procsup.c b/reactos/subsystems/win32/csrss/csrsrv/procsup.c new file mode 100644 index 00000000000..d139d9701d6 --- /dev/null +++ b/reactos/subsystems/win32/csrss/csrsrv/procsup.c @@ -0,0 +1,447 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS CSR Sub System + * FILE: subsys/csr/csrsrv/procsup.c + * PURPOSE: CSR Process Management + * PROGRAMMERS: ReactOS Portable Systems Group + * Alex Ionescu + */ + +/* INCLUDES *******************************************************************/ + +#include + +#define NDEBUG +#include + +#define LOCK RtlEnterCriticalSection(&ProcessDataLock) +#define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock) +#define CsrHeap RtlGetProcessHeap() + +#define CsrAcquireProcessLock() LOCK +#define CsrReleaseProcessLock() UNLOCK + +/* GLOBALS ********************************************************************/ + +extern RTL_CRITICAL_SECTION ProcessDataLock; +extern PCSRSS_PROCESS_DATA ProcessData[256]; +PCSRSS_PROCESS_DATA CsrRootProcess; +LIST_ENTRY CsrThreadHashTable[256]; +SECURITY_QUALITY_OF_SERVICE CsrSecurityQos = +{ + sizeof(SECURITY_QUALITY_OF_SERVICE), + SecurityImpersonation, + SECURITY_STATIC_TRACKING, + FALSE +}; + +/* FUNCTIONS ******************************************************************/ + +VOID +NTAPI +CsrSetToNormalPriority(VOID) +{ + KPRIORITY BasePriority = (8 + 1) + 4; + + /* Set the Priority */ + NtSetInformationProcess(NtCurrentProcess(), + ProcessBasePriority, + &BasePriority, + sizeof(KPRIORITY)); +} + +VOID +NTAPI +CsrSetToShutdownPriority(VOID) +{ + KPRIORITY SetBasePriority = (8 + 1) + 6; + BOOLEAN Old; + + /* Get the shutdown privilege */ + if (NT_SUCCESS(RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, + TRUE, + FALSE, + &Old))) + { + /* Set the Priority */ + NtSetInformationProcess(NtCurrentProcess(), + ProcessBasePriority, + &SetBasePriority, + sizeof(KPRIORITY)); + } +} + +NTSTATUS +NTAPI +CsrGetProcessLuid(HANDLE hProcess OPTIONAL, + PLUID Luid) +{ + HANDLE hToken = NULL; + NTSTATUS Status; + ULONG Length; + PTOKEN_STATISTICS TokenStats; + + /* Check if we have a handle to a CSR Process */ + if (!hProcess) + { + /* We don't, so try opening the Thread's Token */ + Status = NtOpenThreadToken(NtCurrentThread(), + TOKEN_QUERY, + FALSE, + &hToken); + + /* Check for success */ + if (!NT_SUCCESS(Status)) + { + /* If we got some other failure, then return and quit */ + if (Status != STATUS_NO_TOKEN) return Status; + + /* We don't have a Thread Token, use a Process Token */ + hProcess = NtCurrentProcess(); + hToken = NULL; + } + } + + /* Check if we have a token by now */ + if (!hToken) + { + /* No token yet, so open the Process Token */ + Status = NtOpenProcessToken(hProcess, + TOKEN_QUERY, + &hToken); + if (!NT_SUCCESS(Status)) + { + /* Still no token, return the error */ + return Status; + } + } + + /* Now get the size we'll need for the Token Information */ + Status = NtQueryInformationToken(hToken, + TokenStatistics, + NULL, + 0, + &Length); + + /* Allocate memory for the Token Info */ + if (!(TokenStats = RtlAllocateHeap(CsrHeap, 0, Length))) + { + /* Fail and close the token */ + NtClose(hToken); + return STATUS_NO_MEMORY; + } + + /* Now query the information */ + Status = NtQueryInformationToken(hToken, + TokenStatistics, + TokenStats, + Length, + &Length); + + /* Close the handle */ + NtClose(hToken); + + /* Check for success */ + if (NT_SUCCESS(Status)) + { + /* Return the LUID */ + *Luid = TokenStats->AuthenticationId; + } + + /* Free the query information */ + RtlFreeHeap(CsrHeap, 0, TokenStats); + + /* Return the Status */ + return Status; +} + +BOOLEAN +NTAPI +CsrImpersonateClient(IN PCSR_THREAD CsrThread) +{ + NTSTATUS Status; + PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; + + /* Use the current thread if none given */ + if (!CsrThread) CsrThread = CurrentThread; + + /* Still no thread, something is wrong */ + if (!CsrThread) + { + /* Failure */ + return FALSE; + } + + /* Make the call */ + Status = NtImpersonateThread(NtCurrentThread(), + CsrThread->ThreadHandle, + &CsrSecurityQos); + + if (!NT_SUCCESS(Status)) + { + /* Failure */ + return FALSE; + } + + /* Increase the impersonation count for the current thread */ + if (CurrentThread) ++CurrentThread->ImpersonationCount; + + /* Return Success */ + return TRUE; +} + +BOOLEAN +NTAPI +CsrRevertToSelf(VOID) +{ + NTSTATUS Status; + PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; + HANDLE ImpersonationToken = NULL; + + /* Check if we have a Current Thread */ + if (CurrentThread) + { + /* Make sure impersonation is on */ + if (!CurrentThread->ImpersonationCount) + { + return FALSE; + } + else if (--CurrentThread->ImpersonationCount > 0) + { + /* Success; impersonation count decreased but still not zero */ + return TRUE; + } + } + + /* Impersonation has been totally removed, revert to ourselves */ + Status = NtSetInformationThread(NtCurrentThread(), + ThreadImpersonationToken, + &ImpersonationToken, + sizeof(HANDLE)); + + /* Return TRUE or FALSE */ + return NT_SUCCESS(Status); +} + +PCSRSS_PROCESS_DATA +NTAPI +FindProcessForShutdown(IN PLUID CallerLuid) +{ + ULONG Hash; + PCSRSS_PROCESS_DATA CsrProcess, ReturnCsrProcess = NULL; + NTSTATUS Status; + ULONG Level = 0; + LUID ProcessLuid; + LUID SystemLuid = SYSTEM_LUID; + BOOLEAN IsSystemLuid = FALSE, IsOurLuid = FALSE; + + for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++) + { + /* Get this process hash bucket */ + CsrProcess = ProcessData[Hash]; + while (CsrProcess) + { + /* Skip this process if it's already been processed*/ + if (CsrProcess->Flags & CsrProcessSkipShutdown) goto Next; + + /* Get the LUID of this Process */ + Status = CsrGetProcessLuid(CsrProcess->Process, &ProcessLuid); + + /* Check if we didn't get access to the LUID */ + if (Status == STATUS_ACCESS_DENIED) + { + /* FIXME:Check if we have any threads */ + } + + if (!NT_SUCCESS(Status)) + { + /* We didn't have access, so skip it */ + CsrProcess->Flags |= CsrProcessSkipShutdown; + goto Next; + } + + /* Check if this is the System LUID */ + if ((IsSystemLuid = RtlEqualLuid(&ProcessLuid, &SystemLuid))) + { + /* Mark this process */ + CsrProcess->ShutdownFlags |= CsrShutdownSystem; + } + else if (!(IsOurLuid = RtlEqualLuid(&ProcessLuid, CallerLuid))) + { + /* Our LUID doesn't match with the caller's */ + CsrProcess->ShutdownFlags |= CsrShutdownOther; + } + + /* Check if we're past the previous level */ + if (CsrProcess->ShutdownLevel > Level) + { + /* Update the level */ + Level = CsrProcess->ShutdownLevel; + + /* Set the final process */ + ReturnCsrProcess = CsrProcess; + } +Next: + /* Next process */ + CsrProcess = CsrProcess->next; + } + } + + /* Check if we found a process */ + if (ReturnCsrProcess) + { + /* Skip this one next time */ + ReturnCsrProcess->Flags |= CsrProcessSkipShutdown; + } + + return ReturnCsrProcess; +} + +/* This is really "CsrShutdownProcess", mostly */ +NTSTATUS +WINAPI +CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc, + IN PVOID Context) +{ + PVOID* RealContext = (PVOID*)Context; + PLUID CallerLuid = RealContext[0]; + PCSRSS_PROCESS_DATA CsrProcess = NULL; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + BOOLEAN FirstTry; + ULONG Result = 0; + ULONG Hash; + + /* Acquire process lock */ + CsrAcquireProcessLock(); + + /* Start the loop */ + for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++) + { + /* Get the Process */ + CsrProcess = ProcessData[Hash]; + while (CsrProcess) + { + /* Remove the skip flag, set shutdown flags to 0*/ + CsrProcess->Flags &= ~CsrProcessSkipShutdown; + CsrProcess->ShutdownFlags = 0; + + /* Move to the next */ + CsrProcess = CsrProcess->next; + } + } + + /* Set shudown Priority */ + CsrSetToShutdownPriority(); + + /* Loop all processes */ + //DPRINT1("Enumerating for LUID: %lx %lx\n", CallerLuid->HighPart, CallerLuid->LowPart); + + /* Start looping */ + while (TRUE) + { + /* Find the next process to shutdown */ + FirstTry = TRUE; + if (!(CsrProcess = FindProcessForShutdown(CallerLuid))) + { + /* Done, quit */ + CsrReleaseProcessLock(); + Status = STATUS_SUCCESS; + goto Quickie; + } + +LoopAgain: + /* Release the lock, make the callback, and acquire it back */ + //DPRINT1("Found process: %lx\n", CsrProcess->ProcessId); + CsrReleaseProcessLock(); + Result = (ULONG)EnumProc(CsrProcess, (PVOID)((ULONG_PTR)Context | FirstTry)); + CsrAcquireProcessLock(); + + /* Check the result */ + //DPRINT1("Result: %d\n", Result); + if (Result == CsrShutdownCsrProcess) + { + /* The callback unlocked the process */ + break; + } + else if (Result == CsrShutdownNonCsrProcess) + { + /* A non-CSR process, the callback didn't touch it */ + //continue; + } + else if (Result == CsrShutdownCancelled) + { + /* Shutdown was cancelled, unlock and exit */ + CsrReleaseProcessLock(); + Status = STATUS_CANCELLED; + goto Quickie; + } + + /* No matches during the first try, so loop again */ + if (FirstTry && Result == CsrShutdownNonCsrProcess) + { + FirstTry = FALSE; + goto LoopAgain; + } + } + +Quickie: + /* Return to normal priority */ + CsrSetToNormalPriority(); + return Status; +} + +NTSTATUS +NTAPI +CsrLockProcessByClientId(IN HANDLE Pid, + OUT PCSRSS_PROCESS_DATA *CsrProcess OPTIONAL) +{ + ULONG Hash; + PCSRSS_PROCESS_DATA CurrentProcess = NULL; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + /* Acquire the lock */ + CsrAcquireProcessLock(); + + /* Start the loop */ + for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++) + { + /* Get the Process */ + CurrentProcess = ProcessData[Hash]; + while (CurrentProcess) + { + /* Check for PID match */ + if (CurrentProcess->ProcessId == Pid) + { + /* Get out of here with success */ +// DPRINT1("Found %p for PID %lx\n", CurrentProcess, Pid); + Status = STATUS_SUCCESS; + goto Found; + } + + /* Move to the next */ + CurrentProcess = CurrentProcess->next; + } + } + + /* Nothing found, release the lock */ +Found: + if (!CurrentProcess) CsrReleaseProcessLock(); + + /* Return the status and process */ + if (CsrProcess) *CsrProcess = CurrentProcess; + return Status; +} + +NTSTATUS +NTAPI +CsrUnlockProcess(IN PCSRSS_PROCESS_DATA CsrProcess) +{ + /* Dereference the process */ + //CsrLockedDereferenceProcess(CsrProcess); + + /* Release the lock and return */ + CsrReleaseProcessLock(); + return STATUS_SUCCESS; +} + +/* EOF */ diff --git a/reactos/subsystems/win32/csrss/csrsrv/thredsup.c b/reactos/subsystems/win32/csrss/csrsrv/thredsup.c new file mode 100644 index 00000000000..e893888773b --- /dev/null +++ b/reactos/subsystems/win32/csrss/csrsrv/thredsup.c @@ -0,0 +1,306 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS CSR Sub System + * FILE: subsys/csr/csrsrv/procsup.c + * PURPOSE: CSR Process Management + * PROGRAMMERS: ReactOS Portable Systems Group + * Alex Ionescu + */ + +/* INCLUDES *******************************************************************/ + +#include + +#define NDEBUG +#include + +#define LOCK RtlEnterCriticalSection(&ProcessDataLock) +#define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock) +#define CsrHeap RtlGetProcessHeap() +#define CsrHashThread(t) \ + (HandleToUlong(t)&(256 - 1)) + +#define CsrAcquireProcessLock() LOCK +#define CsrReleaseProcessLock() UNLOCK + +/* GLOBALS ********************************************************************/ + +LIST_ENTRY CsrThreadHashTable[256]; +extern PCSRSS_PROCESS_DATA CsrRootProcess; +extern RTL_CRITICAL_SECTION ProcessDataLock; +extern PCSRSS_PROCESS_DATA ProcessData[256]; + +/* FUNCTIONS ******************************************************************/ + +PCSR_THREAD +NTAPI +CsrAllocateThread(IN PCSRSS_PROCESS_DATA CsrProcess) +{ + PCSR_THREAD CsrThread; + + /* Allocate the structure */ + CsrThread = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, sizeof(CSR_THREAD)); + if (!CsrThread) return(NULL); + + /* Reference the Thread and Process */ + CsrThread->ReferenceCount++; + // CsrProcess->ReferenceCount++; + + /* Set the Parent Process */ + CsrThread->Process = CsrProcess; + + /* Return Thread */ + return CsrThread; +} + +PCSR_THREAD +NTAPI +CsrLocateThreadByClientId(OUT PCSRSS_PROCESS_DATA *Process OPTIONAL, + IN PCLIENT_ID ClientId) +{ + ULONG i; + PLIST_ENTRY ListHead, NextEntry; + PCSR_THREAD FoundThread; + + /* Hash the Thread */ + i = CsrHashThread(ClientId->UniqueThread); + + /* Set the list pointers */ + ListHead = &CsrThreadHashTable[i]; + NextEntry = ListHead->Flink; + + /* Star the loop */ + while (NextEntry != ListHead) + { + /* Get the thread */ + FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks); + + /* Compare the CID */ + if (FoundThread->ClientId.UniqueThread == ClientId->UniqueThread) + { + /* Match found, return the process */ + *Process = FoundThread->Process; + + /* Return thread too */ +// DPRINT1("Found: %p %p\n", FoundThread, FoundThread->Process); + return FoundThread; + } + + /* Next */ + NextEntry = NextEntry->Flink; + } + + /* Nothing found */ + return NULL; +} + +PCSR_THREAD +NTAPI +CsrLocateThreadInProcess(IN PCSRSS_PROCESS_DATA CsrProcess OPTIONAL, + IN PCLIENT_ID Cid) +{ + PLIST_ENTRY ListHead, NextEntry; + PCSR_THREAD FoundThread = NULL; + + /* Use the Root Process if none was specified */ + if (!CsrProcess) CsrProcess = CsrRootProcess; + + /* Save the List pointers */ +// DPRINT1("Searching in: %p %d\n", CsrProcess, CsrProcess->ThreadCount); + ListHead = &CsrProcess->ThreadList; + NextEntry = ListHead->Flink; + + /* Start the Loop */ + while (NextEntry != ListHead) + { + /* Get Thread Entry */ + FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link); + + /* Check for TID Match */ + if (FoundThread->ClientId.UniqueThread == Cid->UniqueThread) break; + + /* Next entry */ + NextEntry = NextEntry->Flink; + } + + /* Return what we found */ +// DPRINT1("Found: %p\n", FoundThread); + return FoundThread; +} + +VOID +NTAPI +CsrInsertThread(IN PCSRSS_PROCESS_DATA Process, + IN PCSR_THREAD Thread) +{ + ULONG i; + + /* Insert it into the Regular List */ + InsertTailList(&Process->ThreadList, &Thread->Link); + + /* Increase Thread Count */ + Process->ThreadCount++; + + /* Hash the Thread */ + i = CsrHashThread(Thread->ClientId.UniqueThread); +// DPRINT1("TID %lx HASH: %lx\n", Thread->ClientId.UniqueThread, i); + + /* Insert it there too */ + InsertHeadList(&CsrThreadHashTable[i], &Thread->HashLinks); +} + +VOID +NTAPI +CsrDeallocateThread(IN PCSR_THREAD CsrThread) +{ + /* Free the process object from the heap */ + RtlFreeHeap(CsrHeap, 0, CsrThread); +} + +VOID +NTAPI +CsrRemoveThread(IN PCSR_THREAD CsrThread) +{ + /* Remove it from the List */ + RemoveEntryList(&CsrThread->Link); + + /* Decreate the thread count of the process */ + CsrThread->Process->ThreadCount--; + + /* Remove it from the Hash List as well */ + if (CsrThread->HashLinks.Flink) RemoveEntryList(&CsrThread->HashLinks); + + /* Check if this is the last Thread */ + if (!CsrThread->Process->ThreadCount) + { + /* Check if it's not already been marked for deletion */ + if (!(CsrThread->Process->Flags & CsrProcessLastThreadTerminated)) + { + /* Let everyone know this process is about to lose the thread */ + //CsrThread->Process->Flags |= CsrProcessLastThreadTerminated; + + /* Reference the Process */ + //CsrLockedDereferenceProcess(CsrThread->Process); + } + } + + /* Mark the thread for deletion */ + CsrThread->Flags |= CsrThreadInTermination; +} + +VOID +NTAPI +CsrThreadRefcountZero(IN PCSR_THREAD CsrThread) +{ + /* Remove this thread */ + CsrRemoveThread(CsrThread); + + /* Release the Process Lock */ + //CsrReleaseProcessLock(); + + /* Close the NT Thread Handle */ + if (CsrThread->ThreadHandle) NtClose(CsrThread->ThreadHandle); + + /* De-allocate the CSR Thread Object */ + CsrDeallocateThread(CsrThread); + + /* Remove a reference from the process */ + //CsrDereferenceProcess(CsrProcess); +} + +NTSTATUS +NTAPI +CsrCreateThread(IN PCSRSS_PROCESS_DATA CsrProcess, + IN HANDLE hThread, + IN PCLIENT_ID ClientId) +{ + NTSTATUS Status; + PCSR_THREAD CsrThread; + //PCSRSS_PROCESS_DATA CurrentProcess; + PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; + CLIENT_ID CurrentCid; + KERNEL_USER_TIMES KernelTimes; + +// DPRINT1("CSRSRV: %s called\n", __FUNCTION__); + + /* Get the current thread and CID */ + CurrentCid = CurrentThread->ClientId; +// DPRINT1("CALLER PID/TID: %lx/%lx\n", CurrentCid.UniqueProcess, CurrentCid.UniqueThread); + + /* Acquire the Process Lock */ + CsrAcquireProcessLock(); +#if 0 + /* Get the current Process and make sure the Thread is valid with this CID */ + CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, + &CurrentCid); + + /* Something is wrong if we get an empty thread back */ + if (!CurrentThread) + { + DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__); + CsrReleaseProcessLock(); + return STATUS_THREAD_IS_TERMINATING; + } +#endif + /* Get the Thread Create Time */ + Status = NtQueryInformationThread(hThread, + ThreadTimes, + (PVOID)&KernelTimes, + sizeof(KernelTimes), + NULL); + + /* Allocate a CSR Thread Structure */ + if (!(CsrThread = CsrAllocateThread(CsrProcess))) + { + DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__); + CsrReleaseProcessLock(); + return STATUS_NO_MEMORY; + } + + /* Save the data we have */ + CsrThread->CreateTime = KernelTimes.CreateTime; + CsrThread->ClientId = *ClientId; + CsrThread->ThreadHandle = hThread; + CsrThread->Flags = 0; + + /* Insert the Thread into the Process */ + CsrInsertThread(CsrProcess, CsrThread); + + /* Release the lock and return */ + CsrReleaseProcessLock(); + return STATUS_SUCCESS; +} + +PCSR_THREAD +NTAPI +CsrAddStaticServerThread(IN HANDLE hThread, + IN PCLIENT_ID ClientId, + IN ULONG ThreadFlags) +{ + PCSR_THREAD CsrThread; + + /* Get the Lock */ + CsrAcquireProcessLock(); + + /* Allocate the Server Thread */ + if ((CsrThread = CsrAllocateThread(CsrRootProcess))) + { + /* Setup the Object */ +// DPRINT1("New CSR thread created: %lx PID/TID: %lx/%lx\n", CsrThread, ClientId->UniqueProcess, ClientId->UniqueThread); + CsrThread->ThreadHandle = hThread; + CsrThread->ClientId = *ClientId; + CsrThread->Flags = ThreadFlags; + + /* Insert it into the Thread List */ + InsertTailList(&CsrRootProcess->ThreadList, &CsrThread->Link); + + /* Increment the thread count */ + CsrRootProcess->ThreadCount++; + } + + /* Release the Process Lock and return */ + CsrReleaseProcessLock(); + return CsrThread; +} + +/* EOF */ diff --git a/reactos/subsystems/win32/csrss/include/api.h b/reactos/subsystems/win32/csrss/include/api.h index 463ee50c002..7fbf6db9e58 100644 --- a/reactos/subsystems/win32/csrss/include/api.h +++ b/reactos/subsystems/win32/csrss/include/api.h @@ -148,7 +148,7 @@ extern HANDLE hBootstrapOk; CSR_API(CsrConnectProcess); CSR_API(CsrCreateProcess); CSR_API(CsrTerminateProcess); -CSR_API(CsrCreateThread); +CSR_API(CsrSrvCreateThread); /* print.c */ VOID WINAPI DisplayString(LPCWSTR lpwString); @@ -181,7 +181,10 @@ NTSTATUS WINAPI CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context PCSR_THREAD NTAPI CsrAddStaticServerThread(IN HANDLE hThread, IN PCLIENT_ID ClientId, IN ULONG ThreadFlags); PCSR_THREAD NTAPI CsrLocateThreadInProcess(IN PCSRSS_PROCESS_DATA CsrProcess OPTIONAL, IN PCLIENT_ID Cid); PCSR_THREAD NTAPI CsrLocateThreadByClientId(OUT PCSRSS_PROCESS_DATA *Process OPTIONAL, IN PCLIENT_ID ClientId); - +NTSTATUS NTAPI CsrLockProcessByClientId(IN HANDLE Pid, OUT PCSRSS_PROCESS_DATA *CsrProcess OPTIONAL); +NTSTATUS NTAPI CsrCreateThread(IN PCSRSS_PROCESS_DATA CsrProcess, IN HANDLE hThread, IN PCLIENT_ID ClientId); +NTSTATUS NTAPI CsrUnlockProcess(IN PCSRSS_PROCESS_DATA CsrProcess); + /* api/handle.c */ NTSTATUS FASTCALL CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions); NTSTATUS WINAPI CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object, DWORD Access, BOOL Inheritable ); @@ -192,6 +195,9 @@ NTSTATUS WINAPI CsrReleaseObjectByPointer(Object_t *Object); NTSTATUS WINAPI CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); NTSTATUS WINAPI CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); +//hack +VOID NTAPI CsrThreadRefcountZero(IN PCSR_THREAD CsrThread); + CSR_API(CsrGetInputHandle); CSR_API(CsrGetOutputHandle); CSR_API(CsrCloseHandle); From f94bebf2d03e020929a0d5111acc8af601c233e6 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Wed, 10 Mar 2010 06:50:15 +0000 Subject: [PATCH 18/64] [KERNEL32]: Remove debug output. svn path=/trunk/; revision=46053 --- reactos/dll/win32/kernel32/misc/console.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/console.c b/reactos/dll/win32/kernel32/misc/console.c index e535e77f4d4..5a5871d8939 100644 --- a/reactos/dll/win32/kernel32/misc/console.c +++ b/reactos/dll/win32/kernel32/misc/console.c @@ -39,7 +39,7 @@ BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event) { - DPRINT1("Default handler called: %lx\n", Event); + DPRINT("Default handler called: %lx\n", Event); switch(Event) { case CTRL_C_EVENT: @@ -51,7 +51,7 @@ DefaultConsoleCtrlHandler(DWORD Event) break; case CTRL_SHUTDOWN_EVENT: - DPRINT1("Ctrl Shutdown Event\n"); + DPRINT("Ctrl Shutdown Event\n"); break; case CTRL_CLOSE_EVENT: @@ -59,7 +59,7 @@ DefaultConsoleCtrlHandler(DWORD Event) break; case CTRL_LOGOFF_EVENT: - DPRINT1("Ctrl Logoff Event\n"); + DPRINT("Ctrl Logoff Event\n"); break; } @@ -77,7 +77,7 @@ ConsoleControlDispatcher(DWORD CodeAndFlag) UINT i; EXCEPTION_RECORD erException; - DPRINT1("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode); + DPRINT("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); switch(nCode) @@ -154,7 +154,7 @@ ConsoleControlDispatcher(DWORD CodeAndFlag) (CodeAndFlag & MINLONG) && ((nCode == CTRL_LOGOFF_EVENT) || (nCode == CTRL_SHUTDOWN_EVENT))) { - DPRINT1("Skipping system/service apps\n"); + DPRINT("Skipping system/service apps\n"); break; } From 5d434b2f15780e00193e0eef747c847b56a6ca3c Mon Sep 17 00:00:00 2001 From: James Tabor Date: Wed, 10 Mar 2010 10:19:49 +0000 Subject: [PATCH 19/64] - [User32] Send WM_CANCELMODE in EnableWindow. svn path=/trunk/; revision=46054 --- reactos/dll/win32/user32/windows/input.c | 45 ++++++++++++++---------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/reactos/dll/win32/user32/windows/input.c b/reactos/dll/win32/user32/windows/input.c index 81467263a52..4e97b0d4f12 100644 --- a/reactos/dll/win32/user32/windows/input.c +++ b/reactos/dll/win32/user32/windows/input.c @@ -109,30 +109,39 @@ BOOL WINAPI EnableWindow(HWND hWnd, BOOL bEnable) { + // This will soon be moved to win32k. + BOOL Update; LONG Style = GetWindowLongPtrW(hWnd, GWL_STYLE); /* check if updating is needed */ UINT bIsDisabled = (Style & WS_DISABLED); - if ( (bIsDisabled && bEnable) || (!bIsDisabled && !bEnable) ) - { - if (bEnable) - { - Style &= ~WS_DISABLED; - } - else - { - Style |= WS_DISABLED; - /* Remove keyboard focus from that window if it had focus */ - if (hWnd == GetFocus()) - { - SetFocus(NULL); - } - } - NtUserSetWindowLong(hWnd, GWL_STYLE, Style, FALSE); + Update = bIsDisabled; - SendMessageA(hWnd, WM_ENABLE, (LPARAM) IsWindowEnabled(hWnd), 0); + if (bEnable) + { + Style &= ~WS_DISABLED; + } + else + { + Update = !bIsDisabled; + + SendMessageW( hWnd, WM_CANCELMODE, 0, 0); + + /* Remove keyboard focus from that window if it had focus */ + if (hWnd == GetFocus()) + { + SetFocus(NULL); + } + Style |= WS_DISABLED; + } + + NtUserSetWindowLong(hWnd, GWL_STYLE, Style, FALSE); + + if (Update) + { + SendMessageW(hWnd, WM_ENABLE, (LPARAM)bEnable, 0); } // Return nonzero if it was disabled, or zero if it wasn't: - return IsWindowEnabled(hWnd); + return bIsDisabled; } From f4fa6270ae46ff44b8068d12abc71b250f274434 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 10 Mar 2010 14:28:56 +0000 Subject: [PATCH 20/64] [OLE32] - Sync to Wine-1.1.40. Along with improvements, it provides many memory corruption fixes. svn path=/trunk/; revision=46056 --- reactos/dll/win32/ole32/clipboard.c | 14 +- reactos/dll/win32/ole32/compobj.c | 51 +- reactos/dll/win32/ole32/compobj_private.h | 3 + reactos/dll/win32/ole32/compositemoniker.c | 2 +- reactos/dll/win32/ole32/datacache.c | 6 + reactos/dll/win32/ole32/defaulthandler.c | 96 + reactos/dll/win32/ole32/errorinfo.c | 4 + reactos/dll/win32/ole32/filemoniker.c | 69 +- reactos/dll/win32/ole32/hglobalstream.c | 21 +- reactos/dll/win32/ole32/itemmoniker.c | 361 +- reactos/dll/win32/ole32/marshal.c | 8 +- reactos/dll/win32/ole32/moniker.c | 22 +- reactos/dll/win32/ole32/ole2.c | 7 +- reactos/dll/win32/ole32/ole32.spec | 2 +- reactos/dll/win32/ole32/ole32res.rc | 14 +- reactos/dll/win32/ole32/oleproxy.c | 8 +- reactos/dll/win32/ole32/regsvr.c | 64 +- reactos/dll/win32/ole32/rpc.c | 2 +- reactos/dll/win32/ole32/stg_prop.c | 54 +- reactos/dll/win32/ole32/stg_stream.c | 346 +- reactos/dll/win32/ole32/storage32.c | 3916 +++++++++++--------- reactos/dll/win32/ole32/storage32.h | 239 +- reactos/dll/win32/ole32/stubmanager.c | 8 +- reactos/dll/win32/ole32/usrmarshal.c | 10 +- 24 files changed, 2857 insertions(+), 2470 deletions(-) diff --git a/reactos/dll/win32/ole32/clipboard.c b/reactos/dll/win32/ole32/clipboard.c index 7f19d1638a4..2afc77e35f0 100644 --- a/reactos/dll/win32/ole32/clipboard.c +++ b/reactos/dll/win32/ole32/clipboard.c @@ -1608,6 +1608,8 @@ void OLEClipbrd_UnInitialize(void) } IStream_Release(clipbrd->marshal_data); + if (clipbrd->src_data) IDataObject_Release(clipbrd->src_data); + HeapFree(GetProcessHeap(), 0, clipbrd->cached_enum); HeapFree(GetProcessHeap(), 0, clipbrd); theOleClipboard = NULL; } @@ -1699,7 +1701,11 @@ static HRESULT set_clipboard_formats(ole_clipbrd *clipbrd, IDataObject *data) td_offs_to_ptr(clipbrd->cached_enum, (DWORD_PTR)clipbrd->cached_enum->entries[idx].fmtetc.ptd); GlobalUnlock(priv_data_handle); - SetClipboardData(ole_private_data_clipboard_format, priv_data_handle); + if(!SetClipboardData(ole_private_data_clipboard_format, priv_data_handle)) + { + GlobalFree(priv_data_handle); + return CLIPBRD_E_CANT_SET; + } return S_OK; } @@ -1757,7 +1763,11 @@ static HRESULT expose_marshalled_dataobject(ole_clipbrd *clipbrd, IDataObject *d if(!h) return E_OUTOFMEMORY; - SetClipboardData(wine_marshal_clipboard_format, h); + if(!SetClipboardData(wine_marshal_clipboard_format, h)) + { + GlobalFree(h); + return CLIPBRD_E_CANT_SET; + } return S_OK; } diff --git a/reactos/dll/win32/ole32/compobj.c b/reactos/dll/win32/ole32/compobj.c index b2013cfbfa3..583a9cbcd00 100644 --- a/reactos/dll/win32/ole32/compobj.c +++ b/reactos/dll/win32/ole32/compobj.c @@ -828,6 +828,16 @@ static DWORD COM_RegReadPath(HKEY hkeyroot, const WCHAR *keyname, const WCHAR *v if (keytype == REG_EXPAND_SZ) { if (dstlen <= ExpandEnvironmentStringsW(src, dst, dstlen)) ret = ERROR_MORE_DATA; } else { + const WCHAR *quote_start; + quote_start = strchrW(src, '\"'); + if (quote_start) { + const WCHAR *quote_end = strchrW(quote_start + 1, '\"'); + if (quote_end) { + memmove(src, quote_start + 1, + (quote_end - quote_start - 1) * sizeof(WCHAR)); + src[quote_end - quote_start - 1] = '\0'; + } + } lstrcpynW(dst, src, dstlen); } } @@ -1621,7 +1631,7 @@ INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax) '%','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 }; - if (cmax < CHARS_IN_GUID) return 0; + if (!id || cmax < CHARS_IN_GUID) return 0; sprintfW( str, formatW, id->Data1, id->Data2, id->Data3, id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3], id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] ); @@ -2052,6 +2062,7 @@ HRESULT WINAPI CoRegisterClassObject( DWORD flags, LPDWORD lpdwRegister) { + static LONG next_cookie; RegisteredClass* newClass; LPUNKNOWN foundObject; HRESULT hr; @@ -2105,11 +2116,8 @@ HRESULT WINAPI CoRegisterClassObject( newClass->pMarshaledData = NULL; newClass->RpcRegistration = NULL; - /* - * Use the address of the chain node as the cookie since we are sure it's - * unique. FIXME: not on 64-bit platforms. - */ - newClass->dwCookie = (DWORD)newClass; + if (!(newClass->dwCookie = InterlockedIncrement( &next_cookie ))) + newClass->dwCookie = InterlockedIncrement( &next_cookie ); /* * Since we're making a copy of the object pointer, we have to increase its @@ -2130,7 +2138,7 @@ HRESULT WINAPI CoRegisterClassObject( FIXME("Failed to create stream on hglobal, %x\n", hr); return hr; } - hr = CoMarshalInterface(newClass->pMarshaledData, &IID_IClassFactory, + hr = CoMarshalInterface(newClass->pMarshaledData, &IID_IUnknown, newClass->classObject, MSHCTX_LOCAL, NULL, MSHLFLAGS_TABLESTRONG); if (hr) { @@ -2380,7 +2388,7 @@ HRESULT WINAPI CoGetClassObject( if (CLSCTX_REMOTE_SERVER & dwClsContext) { FIXME ("CLSCTX_REMOTE_SERVER not supported\n"); - hres = E_NOINTERFACE; + hres = REGDB_E_CLASSNOTREG; } if (FAILED(hres)) @@ -4106,6 +4114,33 @@ HRESULT WINAPI CoGetContextToken( ULONG_PTR *token ) return S_OK; } +HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +{ + static const WCHAR wszInprocHandler32[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0}; + HKEY hkey; + HRESULT hres; + + hres = COM_OpenKeyForCLSID(rclsid, wszInprocHandler32, KEY_READ, &hkey); + if (SUCCEEDED(hres)) + { + WCHAR dllpath[MAX_PATH+1]; + + if (COM_RegReadPath(hkey, NULL, NULL, dllpath, ARRAYSIZE(dllpath)) == ERROR_SUCCESS) + { + static const WCHAR wszOle32[] = {'o','l','e','3','2','.','d','l','l',0}; + if (!strcmpiW(dllpath, wszOle32)) + { + RegCloseKey(hkey); + return HandlerCF_Create(rclsid, riid, ppv); + } + } + else + WARN("not creating object for inproc handler path %s\n", debugstr_w(dllpath)); + RegCloseKey(hkey); + } + + return CLASS_E_CLASSNOTAVAILABLE; +} /*********************************************************************** * DllMain (OLE32.@) diff --git a/reactos/dll/win32/ole32/compobj_private.h b/reactos/dll/win32/ole32/compobj_private.h index fb059349f8c..076d845c85a 100644 --- a/reactos/dll/win32/ole32/compobj_private.h +++ b/reactos/dll/win32/ole32/compobj_private.h @@ -313,6 +313,9 @@ extern HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID extern HRESULT WINAPI OLE32_DllRegisterServer(void) DECLSPEC_HIDDEN; extern HRESULT WINAPI OLE32_DllUnregisterServer(void) DECLSPEC_HIDDEN; +extern HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv); +extern HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv); + /* Exported non-interface Data Advise Holder functions */ HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDelegate); void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface); diff --git a/reactos/dll/win32/ole32/compositemoniker.c b/reactos/dll/win32/ole32/compositemoniker.c index 5535a97681b..7402b8edbbf 100644 --- a/reactos/dll/win32/ole32/compositemoniker.c +++ b/reactos/dll/win32/ole32/compositemoniker.c @@ -670,7 +670,7 @@ CompositeMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc, else{ if (pbc==NULL) - return E_POINTER; + return E_INVALIDARG; /* If pmkToLeft and pmkNewlyRunning are both NULL, this method checks the ROT to see whether */ /* the moniker is running. If so, the method returns S_OK; otherwise, it recursively calls */ diff --git a/reactos/dll/win32/ole32/datacache.c b/reactos/dll/win32/ole32/datacache.c index a2589808322..ead53fe83c3 100644 --- a/reactos/dll/win32/ole32/datacache.c +++ b/reactos/dll/win32/ole32/datacache.c @@ -234,6 +234,12 @@ static void DataCache_Destroy( LIST_FOR_EACH_ENTRY_SAFE(cache_entry, next_cache_entry, &ptrToDestroy->cache_list, DataCacheEntry, entry) DataCacheEntry_Destroy(cache_entry); + if (ptrToDestroy->presentationStorage != NULL) + { + IStorage_Release(ptrToDestroy->presentationStorage); + ptrToDestroy->presentationStorage = NULL; + } + /* * Free the datacache pointer. */ diff --git a/reactos/dll/win32/ole32/defaulthandler.c b/reactos/dll/win32/ole32/defaulthandler.c index 4102d50845b..5130513d57f 100644 --- a/reactos/dll/win32/ole32/defaulthandler.c +++ b/reactos/dll/win32/ole32/defaulthandler.c @@ -1960,9 +1960,21 @@ static DefaultHandler* DefaultHandler_Construct( &IID_IUnknown, (void**)&This->dataCache); if(SUCCEEDED(hr)) + { hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg); + /* keeping a reference to This->dataCache_PersistStg causes us to keep a + * reference on the outer object */ + if (SUCCEEDED(hr)) + IUnknown_Release(This->outerUnknown); + else + IUnknown_Release(This->dataCache); + } if(FAILED(hr)) + { ERR("Unexpected error creating data cache\n"); + HeapFree(GetProcessHeap(), 0, This); + return NULL; + } This->clsid = *clsid; This->clientSite = NULL; @@ -2009,6 +2021,13 @@ static DefaultHandler* DefaultHandler_Construct( static void DefaultHandler_Destroy( DefaultHandler* This) { + TRACE("(%p)\n", This); + + /* AddRef/Release may be called on this object during destruction. + * Prevent the object being destroyed recursively by artificially raising + * the reference count. */ + This->ref = 10000; + /* release delegates */ DefaultHandler_Stop(This); release_delegates(This); @@ -2020,6 +2039,9 @@ static void DefaultHandler_Destroy( if (This->dataCache) { + /* to balance out the release of dataCache_PersistStg which will result + * in a reference being released from the outer unknown */ + IUnknown_AddRef(This->outerUnknown); IPersistStorage_Release(This->dataCache_PersistStg); IUnknown_Release(This->dataCache); This->dataCache_PersistStg = NULL; @@ -2122,3 +2144,77 @@ HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter, return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW, NULL, riid, ppvObj); } + +typedef struct HandlerCF +{ + const IClassFactoryVtbl *lpVtbl; + LONG refs; + CLSID clsid; +} HandlerCF; + +static HRESULT WINAPI +HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv) +{ + *ppv = NULL; + if (IsEqualIID(riid,&IID_IUnknown) || + IsEqualIID(riid,&IID_IClassFactory)) + { + *ppv = iface; + IClassFactory_AddRef(iface); + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface) +{ + HandlerCF *This = (HandlerCF *)iface; + return InterlockedIncrement(&This->refs); +} + +static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface) +{ + HandlerCF *This = (HandlerCF *)iface; + ULONG refs = InterlockedDecrement(&This->refs); + if (!refs) + HeapFree(GetProcessHeap(), 0, This); + return refs; +} + +static HRESULT WINAPI +HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk, + REFIID riid, LPVOID *ppv) +{ + HandlerCF *This = (HandlerCF *)iface; + return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv); +} + +static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) +{ + FIXME("(%d), stub!\n",fLock); + return S_OK; +} + +static const IClassFactoryVtbl HandlerClassFactoryVtbl = { + HandlerCF_QueryInterface, + HandlerCF_AddRef, + HandlerCF_Release, + HandlerCF_CreateInstance, + HandlerCF_LockServer +}; + +HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +{ + HRESULT hr; + HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + if (!This) return E_OUTOFMEMORY; + This->lpVtbl = &HandlerClassFactoryVtbl; + This->refs = 0; + This->clsid = *rclsid; + + hr = IUnknown_QueryInterface((IUnknown *)&This->lpVtbl, riid, ppv); + if (FAILED(hr)) + HeapFree(GetProcessHeap(), 0, This); + + return hr; +} diff --git a/reactos/dll/win32/ole32/errorinfo.c b/reactos/dll/win32/ole32/errorinfo.c index f69635bc493..39751ab6551 100644 --- a/reactos/dll/win32/ole32/errorinfo.c +++ b/reactos/dll/win32/ole32/errorinfo.c @@ -237,6 +237,10 @@ static ULONG WINAPI IErrorInfoImpl_Release( if (!ref) { TRACE("-- destroying IErrorInfo(%p)\n",This); + + ERRORINFO_SysFreeString(This->bstrSource); + ERRORINFO_SysFreeString(This->bstrDescription); + ERRORINFO_SysFreeString(This->bstrHelpFile); HeapFree(GetProcessHeap(),0,This); return 0; } diff --git a/reactos/dll/win32/ole32/filemoniker.c b/reactos/dll/win32/ole32/filemoniker.c index e9fd4cacfe9..72f59136f78 100644 --- a/reactos/dll/win32/ole32/filemoniker.c +++ b/reactos/dll/win32/ole32/filemoniker.c @@ -198,9 +198,9 @@ FileMonikerImpl_Load(IMoniker* iface, IStream* pStm) TRACE("(%p,%p)\n",iface,pStm); - /* first WORD must be 0 */ + /* first WORD */ res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread); - if (bread!=sizeof(WORD) || wbuffer!=0) + if (bread!=sizeof(WORD)) { WARN("Couldn't read 0 word\n"); goto fail; @@ -229,18 +229,26 @@ FileMonikerImpl_Load(IMoniker* iface, IStream* pStm) goto fail; } - /* read the first constant */ - IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread); - if (bread != sizeof(DWORD) || dwbuffer != 0xDEADFFFF) + /* read the unknown value */ + IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread); + if (bread != sizeof(WORD)) { - WARN("Couldn't read 0xDEADFFFF constant\n"); + WARN("Couldn't read unknown value\n"); + goto fail; + } + + /* read the DEAD constant */ + IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread); + if (bread != sizeof(WORD)) + { + WARN("Couldn't read DEAD constant\n"); goto fail; } for(i=0;i<5;i++) { res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread); - if (bread!=sizeof(DWORD) || dwbuffer!=0) + if (bread!=sizeof(DWORD)) { WARN("Couldn't read 0 padding\n"); goto fail; @@ -320,18 +328,20 @@ FileMonikerImpl_Load(IMoniker* iface, IStream* pStm) * of Windows have minor variations. * * Data which must be written on stream is: - * 1) WORD constant:zero + * 1) WORD constant: zero (not validated by Windows) * 2) length of the path string ("\0" included) * 3) path string type A - * 4) DWORD constant : 0xDEADFFFF - * 5) five DWORD constant: zero - * 6) If we're only writing the multibyte version, + * 4) Unknown WORD value: Frequently 0xFFFF, but not always. If set very large, + * Windows returns E_OUTOFMEMORY + * 5) WORD Constant: 0xDEAD (not validated by Windows) + * 6) five DWORD constant: zero (not validated by Windows) + * 7) If we're only writing the multibyte version, * write a zero DWORD and finish. * - * 7) DWORD: double-length of the path string type W ("\0" not + * 8) DWORD: double-length of the path string type W ("\0" not * included) - * 8) WORD constant: 0x3 - * 9) filePath unicode string. + * 9) WORD constant: 0x3 + * 10) filePath unicode string. * */ static HRESULT WINAPI @@ -344,7 +354,8 @@ FileMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty) CHAR* filePathA; DWORD bytesA, bytesW, len; - static const DWORD DEADFFFF = 0xDEADFFFF; /* Constants */ + static const WORD FFFF = 0xFFFF; /* Constants */ + static const WORD DEAD = 0xDEAD; static const DWORD ZERO = 0; static const WORD THREE = 0x3; @@ -374,8 +385,12 @@ FileMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty) HeapFree(GetProcessHeap(),0,filePathA); if (FAILED(res)) return res; - /* write a DWORD 0xDEADFFFF */ - res=IStream_Write(pStm,&DEADFFFF,sizeof(DWORD),NULL); + /* write a WORD 0xFFFF */ + res=IStream_Write(pStm,&FFFF,sizeof(WORD),NULL); + if (FAILED(res)) return res; + + /* write a WORD 0xDEAD */ + res=IStream_Write(pStm,&DEAD,sizeof(WORD),NULL); if (FAILED(res)) return res; /* write 5 zero DWORDs */ @@ -945,20 +960,32 @@ FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** p if(mkSys==MKSYS_FILEMONIKER){ HRESULT ret; - CreateBindCtx(0,&pbind); + ret = CreateBindCtx(0,&pbind); + if (FAILED(ret)) + return ret; /* create a string based on common part of the two paths */ - IMoniker_GetDisplayName(iface,pbind,NULL,&pathThis); - IMoniker_GetDisplayName(pmkOther,pbind,NULL,&pathOther); + ret = IMoniker_GetDisplayName(iface,pbind,NULL,&pathThis); + if (FAILED(ret)) + return ret; + ret = IMoniker_GetDisplayName(pmkOther,pbind,NULL,&pathOther); + if (FAILED(ret)) + return ret; nb1=FileMonikerImpl_DecomposePath(pathThis,&stringTable1); + if (FAILED(nb1)) + return nb1; nb2=FileMonikerImpl_DecomposePath(pathOther,&stringTable2); + if (FAILED(nb2)) + return nb2; if (nb1==0 || nb2==0) return MK_E_NOPREFIX; commonPath=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(min(lstrlenW(pathThis),lstrlenW(pathOther))+1)); + if (!commonPath) + return E_OUTOFMEMORY; *commonPath=0; @@ -1021,7 +1048,7 @@ int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable) TRACE("%s, %p\n", debugstr_w(str), *stringTable); - strgtable = CoTaskMemAlloc(len*sizeof(WCHAR)); + strgtable = CoTaskMemAlloc((len + 1)*sizeof(*strgtable)); if (strgtable==NULL) return E_OUTOFMEMORY; diff --git a/reactos/dll/win32/ole32/hglobalstream.c b/reactos/dll/win32/ole32/hglobalstream.c index c43d499bb4e..5742f99619a 100644 --- a/reactos/dll/win32/ole32/hglobalstream.c +++ b/reactos/dll/win32/ole32/hglobalstream.c @@ -365,11 +365,18 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek( { HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface; - ULARGE_INTEGER newPosition; + ULARGE_INTEGER newPosition = This->currentPosition; + HRESULT hr = S_OK; TRACE("(%p, %x%08x, %d, %p)\n", iface, dlibMove.u.HighPart, dlibMove.u.LowPart, dwOrigin, plibNewPosition); + if (dlibMove.u.LowPart >= 0x80000000) + { + hr = STG_E_SEEKERROR; + goto end; + } + /* * The file pointer is moved depending on the given "function" * parameter. @@ -381,13 +388,13 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek( newPosition.u.LowPart = 0; break; case STREAM_SEEK_CUR: - newPosition = This->currentPosition; break; case STREAM_SEEK_END: newPosition = This->streamSize; break; default: - return STG_E_INVALIDFUNCTION; + hr = STG_E_SEEKERROR; + goto end; } /* @@ -395,14 +402,14 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek( * If the file pointer ends-up after the end of the stream, the next Write operation will * make the file larger. This is how it is documented. */ - if (dlibMove.QuadPart < 0 && newPosition.QuadPart < -dlibMove.QuadPart) return STG_E_INVALIDFUNCTION; - - newPosition.QuadPart += dlibMove.QuadPart; + newPosition.u.HighPart = 0; + newPosition.u.LowPart += dlibMove.QuadPart; +end: if (plibNewPosition) *plibNewPosition = newPosition; This->currentPosition = newPosition; - return S_OK; + return hr; } /*** diff --git a/reactos/dll/win32/ole32/itemmoniker.c b/reactos/dll/win32/ole32/itemmoniker.c index 816533d42c0..ff8f9b481e3 100644 --- a/reactos/dll/win32/ole32/itemmoniker.c +++ b/reactos/dll/win32/ole32/itemmoniker.c @@ -62,99 +62,12 @@ static inline IMoniker *impl_from_IROTData( IROTData *iface ) return (IMoniker *)((char*)iface - FIELD_OFFSET(ItemMonikerImpl, lpvtbl2)); } -/********************************************************************************/ -/* ItemMoniker prototype functions : */ - -/* IUnknown prototype functions */ -static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject); -static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface); -static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface); - -/* IPersist prototype functions */ -static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID); - -/* IPersistStream prototype functions */ -static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface); -static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface, IStream* pStm); -static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty); -static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize); - -/* IMoniker prototype functions */ -static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult); -static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult); -static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced); -static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite); -static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker); -static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker); -static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash); -static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning); -static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pItemTime); -static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk); -static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix); -static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath); -static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName); -static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut); -static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys); - -/* Local function used by ItemMoniker implementation */ -static HRESULT ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName); static HRESULT ItemMonikerImpl_Destroy(ItemMonikerImpl* iface); -/********************************************************************************/ -/* IROTData prototype functions */ - -/* IUnknown prototype functions */ -static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject); -static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface); -static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface); - -/* IROTData prototype function */ -static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData); - -/********************************************************************************/ -/* Virtual function table for the ItemMonikerImpl class which include IPersist,*/ -/* IPersistStream and IMoniker functions. */ -static const IMonikerVtbl VT_ItemMonikerImpl = - { - ItemMonikerImpl_QueryInterface, - ItemMonikerImpl_AddRef, - ItemMonikerImpl_Release, - ItemMonikerImpl_GetClassID, - ItemMonikerImpl_IsDirty, - ItemMonikerImpl_Load, - ItemMonikerImpl_Save, - ItemMonikerImpl_GetSizeMax, - ItemMonikerImpl_BindToObject, - ItemMonikerImpl_BindToStorage, - ItemMonikerImpl_Reduce, - ItemMonikerImpl_ComposeWith, - ItemMonikerImpl_Enum, - ItemMonikerImpl_IsEqual, - ItemMonikerImpl_Hash, - ItemMonikerImpl_IsRunning, - ItemMonikerImpl_GetTimeOfLastChange, - ItemMonikerImpl_Inverse, - ItemMonikerImpl_CommonPrefixWith, - ItemMonikerImpl_RelativePathTo, - ItemMonikerImpl_GetDisplayName, - ItemMonikerImpl_ParseDisplayName, - ItemMonikerImpl_IsSystemMoniker -}; - -/********************************************************************************/ -/* Virtual function table for the IROTData class. */ -static const IROTDataVtbl VT_ROTDataImpl = -{ - ItemMonikerROTDataImpl_QueryInterface, - ItemMonikerROTDataImpl_AddRef, - ItemMonikerROTDataImpl_Release, - ItemMonikerROTDataImpl_GetComparisonData -}; - /******************************************************************************* * ItemMoniker_QueryInterface *******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject) +static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject) { ItemMonikerImpl *This = (ItemMonikerImpl *)iface; @@ -192,7 +105,7 @@ HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** return E_NOINTERFACE; /* Query Interface always increases the reference count by one when it is successful */ - ItemMonikerImpl_AddRef(iface); + IMoniker_AddRef(iface); return S_OK; } @@ -200,7 +113,7 @@ HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** /****************************************************************************** * ItemMoniker_AddRef ******************************************************************************/ -ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface) +static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface) { ItemMonikerImpl *This = (ItemMonikerImpl *)iface; @@ -212,7 +125,7 @@ ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface) /****************************************************************************** * ItemMoniker_Release ******************************************************************************/ -ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface) +static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface) { ItemMonikerImpl *This = (ItemMonikerImpl *)iface; ULONG ref; @@ -230,7 +143,7 @@ ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface) /****************************************************************************** * ItemMoniker_GetClassID ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID) +static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID) { TRACE("(%p,%p)\n",iface,pClassID); @@ -245,7 +158,7 @@ HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID) /****************************************************************************** * ItemMoniker_IsDirty ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface) +static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface) { /* Note that the OLE-provided implementations of the IPersistStream::IsDirty method in the OLE-provided moniker interfaces always return S_FALSE because @@ -259,7 +172,7 @@ HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface) /****************************************************************************** * ItemMoniker_Load ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm) +static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm) { ItemMonikerImpl *This = (ItemMonikerImpl *)iface; @@ -328,9 +241,9 @@ HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm) /****************************************************************************** * ItemMoniker_Save ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, - IStream* pStm,/* pointer to the stream where the object is to be saved */ - BOOL fClearDirty)/* Specifies whether to clear the dirty flag */ +static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, + IStream* pStm,/* pointer to the stream where the object is to be saved */ + BOOL fClearDirty)/* Specifies whether to clear the dirty flag */ { ItemMonikerImpl *This = (ItemMonikerImpl *)iface; HRESULT res; @@ -364,8 +277,8 @@ HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, /****************************************************************************** * ItemMoniker_GetSizeMax ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, - ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */ +static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, + ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */ { ItemMonikerImpl *This = (ItemMonikerImpl *)iface; DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1; @@ -388,67 +301,14 @@ HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, return S_OK; } -/****************************************************************************** - * ItemMoniker_Construct (local function) - *******************************************************************************/ -static HRESULT ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem) -{ - - int sizeStr1=lstrlenW(lpszItem), sizeStr2; - static const OLECHAR emptystr[1]; - LPCOLESTR delim; - - TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszDelim),debugstr_w(lpszItem)); - - /* Initialize the virtual function table. */ - This->lpvtbl1 = &VT_ItemMonikerImpl; - This->lpvtbl2 = &VT_ROTDataImpl; - This->ref = 0; - This->pMarshal = NULL; - - This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1)); - if (!This->itemName) - return E_OUTOFMEMORY; - lstrcpyW(This->itemName,lpszItem); - - if (!lpszDelim) - FIXME("lpszDelim is NULL. Using empty string which is possibly wrong.\n"); - - delim = lpszDelim ? lpszDelim : emptystr; - - sizeStr2=lstrlenW(delim); - This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1)); - if (!This->itemDelimiter) { - HeapFree(GetProcessHeap(),0,This->itemName); - return E_OUTOFMEMORY; - } - lstrcpyW(This->itemDelimiter,delim); - return S_OK; -} - -/****************************************************************************** - * ItemMoniker_Destroy (local function) - *******************************************************************************/ -static HRESULT ItemMonikerImpl_Destroy(ItemMonikerImpl* This) -{ - TRACE("(%p)\n",This); - - if (This->pMarshal) IUnknown_Release(This->pMarshal); - HeapFree(GetProcessHeap(),0,This->itemName); - HeapFree(GetProcessHeap(),0,This->itemDelimiter); - HeapFree(GetProcessHeap(),0,This); - - return S_OK; -} - /****************************************************************************** * ItemMoniker_BindToObject ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface, - IBindCtx* pbc, - IMoniker* pmkToLeft, - REFIID riid, - VOID** ppvResult) +static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + REFIID riid, + VOID** ppvResult) { ItemMonikerImpl *This = (ItemMonikerImpl *)iface; @@ -481,11 +341,11 @@ HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface, /****************************************************************************** * ItemMoniker_BindToStorage ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface, - IBindCtx* pbc, - IMoniker* pmkToLeft, - REFIID riid, - VOID** ppvResult) +static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + REFIID riid, + VOID** ppvResult) { ItemMonikerImpl *This = (ItemMonikerImpl *)iface; @@ -514,11 +374,11 @@ HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface, /****************************************************************************** * ItemMoniker_Reduce ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface, - IBindCtx* pbc, - DWORD dwReduceHowFar, - IMoniker** ppmkToLeft, - IMoniker** ppmkReduced) +static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface, + IBindCtx* pbc, + DWORD dwReduceHowFar, + IMoniker** ppmkToLeft, + IMoniker** ppmkReduced) { TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced); @@ -534,10 +394,10 @@ HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface, /****************************************************************************** * ItemMoniker_ComposeWith ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface, - IMoniker* pmkRight, - BOOL fOnlyIfNotGeneric, - IMoniker** ppmkComposite) +static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface, + IMoniker* pmkRight, + BOOL fOnlyIfNotGeneric, + IMoniker** ppmkComposite) { HRESULT res=S_OK; DWORD mkSys,mkSys2; @@ -609,7 +469,7 @@ HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface, /****************************************************************************** * ItemMoniker_Enum ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker) +static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker) { TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker); @@ -624,7 +484,7 @@ HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker* /****************************************************************************** * ItemMoniker_IsEqual ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker) +static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker) { CLSID clsid; @@ -657,7 +517,7 @@ HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker /****************************************************************************** * ItemMoniker_Hash ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash) +static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash) { ItemMonikerImpl *This = (ItemMonikerImpl *)iface; DWORD h = 0; @@ -682,10 +542,10 @@ HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash) /****************************************************************************** * ItemMoniker_IsRunning ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface, - IBindCtx* pbc, - IMoniker* pmkToLeft, - IMoniker* pmkNewlyRunning) +static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + IMoniker* pmkNewlyRunning) { IRunningObjectTable* rot; HRESULT res; @@ -701,7 +561,7 @@ HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface, return S_OK; else { if (pbc==NULL) - return E_POINTER; + return E_INVALIDARG; res=IBindCtx_GetRunningObjectTable(pbc,&rot); @@ -734,10 +594,10 @@ HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface, /****************************************************************************** * ItemMoniker_GetTimeOfLastChange ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, - IBindCtx* pbc, - IMoniker* pmkToLeft, - FILETIME* pItemTime) +static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + FILETIME* pItemTime) { IRunningObjectTable* rot; HRESULT res; @@ -775,7 +635,7 @@ HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, /****************************************************************************** * ItemMoniker_Inverse ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk) +static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk) { TRACE("(%p,%p)\n",iface,ppmk); @@ -788,7 +648,7 @@ HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk) /****************************************************************************** * ItemMoniker_CommonPrefixWith ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) +static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) { DWORD mkSys; @@ -815,7 +675,7 @@ HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOth /****************************************************************************** * ItemMoniker_RelativePathTo ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath) +static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath) { TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath); @@ -830,10 +690,10 @@ HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, /****************************************************************************** * ItemMoniker_GetDisplayName ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface, - IBindCtx* pbc, - IMoniker* pmkToLeft, - LPOLESTR *ppszDisplayName) +static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + LPOLESTR *ppszDisplayName) { ItemMonikerImpl *This = (ItemMonikerImpl *)iface; @@ -862,12 +722,12 @@ HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface, /****************************************************************************** * ItemMoniker_ParseDisplayName ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface, - IBindCtx* pbc, - IMoniker* pmkToLeft, - LPOLESTR pszDisplayName, - ULONG* pchEaten, - IMoniker** ppmkOut) +static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + LPOLESTR pszDisplayName, + ULONG* pchEaten, + IMoniker** ppmkOut) { IOleItemContainer* poic=0; IParseDisplayName* ppdn=0; @@ -906,7 +766,7 @@ HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface, /****************************************************************************** * ItemMoniker_IsSystemMoniker ******************************************************************************/ -HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys) +static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys) { TRACE("(%p,%p)\n",iface,pwdMksys); @@ -921,7 +781,7 @@ HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys) /******************************************************************************* * ItemMonikerIROTData_QueryInterface *******************************************************************************/ -HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject) +static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject) { IMoniker *This = impl_from_IROTData(iface); @@ -934,7 +794,7 @@ HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid /*********************************************************************** * ItemMonikerIROTData_AddRef */ -ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface) +static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface) { IMoniker *This = impl_from_IROTData(iface); @@ -946,7 +806,7 @@ ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface) /*********************************************************************** * ItemMonikerIROTData_Release */ -ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface) +static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface) { IMoniker *This = impl_from_IROTData(iface); @@ -958,10 +818,10 @@ ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface) /****************************************************************************** * ItemMonikerIROTData_GetComparisonData ******************************************************************************/ -HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface, - BYTE* pbData, - ULONG cbMax, - ULONG* pcbData) +static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface, + BYTE* pbData, + ULONG cbMax, + ULONG* pcbData) { IMoniker *This = impl_from_IROTData(iface); ItemMonikerImpl *This1 = (ItemMonikerImpl *)This; @@ -989,6 +849,99 @@ HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface, return S_OK; } +/********************************************************************************/ +/* Virtual function table for the ItemMonikerImpl class which include IPersist,*/ +/* IPersistStream and IMoniker functions. */ +static const IMonikerVtbl VT_ItemMonikerImpl = + { + ItemMonikerImpl_QueryInterface, + ItemMonikerImpl_AddRef, + ItemMonikerImpl_Release, + ItemMonikerImpl_GetClassID, + ItemMonikerImpl_IsDirty, + ItemMonikerImpl_Load, + ItemMonikerImpl_Save, + ItemMonikerImpl_GetSizeMax, + ItemMonikerImpl_BindToObject, + ItemMonikerImpl_BindToStorage, + ItemMonikerImpl_Reduce, + ItemMonikerImpl_ComposeWith, + ItemMonikerImpl_Enum, + ItemMonikerImpl_IsEqual, + ItemMonikerImpl_Hash, + ItemMonikerImpl_IsRunning, + ItemMonikerImpl_GetTimeOfLastChange, + ItemMonikerImpl_Inverse, + ItemMonikerImpl_CommonPrefixWith, + ItemMonikerImpl_RelativePathTo, + ItemMonikerImpl_GetDisplayName, + ItemMonikerImpl_ParseDisplayName, + ItemMonikerImpl_IsSystemMoniker +}; + +/********************************************************************************/ +/* Virtual function table for the IROTData class. */ +static const IROTDataVtbl VT_ROTDataImpl = +{ + ItemMonikerROTDataImpl_QueryInterface, + ItemMonikerROTDataImpl_AddRef, + ItemMonikerROTDataImpl_Release, + ItemMonikerROTDataImpl_GetComparisonData +}; + +/****************************************************************************** + * ItemMoniker_Construct (local function) + *******************************************************************************/ +static HRESULT ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem) +{ + + int sizeStr1=lstrlenW(lpszItem), sizeStr2; + static const OLECHAR emptystr[1]; + LPCOLESTR delim; + + TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszDelim),debugstr_w(lpszItem)); + + /* Initialize the virtual function table. */ + This->lpvtbl1 = &VT_ItemMonikerImpl; + This->lpvtbl2 = &VT_ROTDataImpl; + This->ref = 0; + This->pMarshal = NULL; + + This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1)); + if (!This->itemName) + return E_OUTOFMEMORY; + lstrcpyW(This->itemName,lpszItem); + + if (!lpszDelim) + FIXME("lpszDelim is NULL. Using empty string which is possibly wrong.\n"); + + delim = lpszDelim ? lpszDelim : emptystr; + + sizeStr2=lstrlenW(delim); + This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1)); + if (!This->itemDelimiter) { + HeapFree(GetProcessHeap(),0,This->itemName); + return E_OUTOFMEMORY; + } + lstrcpyW(This->itemDelimiter,delim); + return S_OK; +} + +/****************************************************************************** + * ItemMoniker_Destroy (local function) + *******************************************************************************/ +static HRESULT ItemMonikerImpl_Destroy(ItemMonikerImpl* This) +{ + TRACE("(%p)\n",This); + + if (This->pMarshal) IUnknown_Release(This->pMarshal); + HeapFree(GetProcessHeap(),0,This->itemName); + HeapFree(GetProcessHeap(),0,This->itemDelimiter); + HeapFree(GetProcessHeap(),0,This); + + return S_OK; +} + /****************************************************************************** * CreateItemMoniker [OLE32.@] ******************************************************************************/ diff --git a/reactos/dll/win32/ole32/marshal.c b/reactos/dll/win32/ole32/marshal.c index 3703de9f2b8..54a3a87b2b6 100644 --- a/reactos/dll/win32/ole32/marshal.c +++ b/reactos/dll/win32/ole32/marshal.c @@ -553,9 +553,9 @@ static HRESULT WINAPI ProxyCliSec_SetBlanket(IClientSecurity *iface, void *pAuthInfo, DWORD Capabilities) { - FIXME("(%p, %d, %d, %s, %d, %d, %p, 0x%x): stub\n", pProxy, AuthnSvc, - AuthzSvc, debugstr_w(pServerPrincName), AuthnLevel, ImpLevel, - pAuthInfo, Capabilities); + FIXME("(%p, %d, %d, %s, %d, %d, %p, 0x%x): stub\n", pProxy, AuthnSvc, AuthzSvc, + pServerPrincName == COLE_DEFAULT_PRINCIPAL ? "" : debugstr_w(pServerPrincName), + AuthnLevel, ImpLevel, pAuthInfo, Capabilities); return E_NOTIMPL; } @@ -1336,7 +1336,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v /* unref the ifstub. FIXME: only do this on success? */ if (!stub_manager_is_table_marshaled(stubmgr, &stdobjref.ipid)) - stub_manager_ext_release(stubmgr, stdobjref.cPublicRefs, stdobjref.flags & SORFP_TABLEWEAK, TRUE); + stub_manager_ext_release(stubmgr, stdobjref.cPublicRefs, stdobjref.flags & SORFP_TABLEWEAK, FALSE); stub_manager_int_release(stubmgr); return hres; diff --git a/reactos/dll/win32/ole32/moniker.c b/reactos/dll/win32/ole32/moniker.c index f65fe8fe728..a7c5a11c98b 100644 --- a/reactos/dll/win32/ole32/moniker.c +++ b/reactos/dll/win32/ole32/moniker.c @@ -124,30 +124,18 @@ static BOOL start_rpcss(void) { PROCESS_INFORMATION pi; STARTUPINFOW si; - static WCHAR cmd[6]; - static const WCHAR rpcss[] = {'r','p','c','s','s',0}; + WCHAR cmd[MAX_PATH]; + static const WCHAR rpcss[] = {'\\','r','p','c','s','s','.','e','x','e',0}; BOOL rslt; TRACE("\n"); - ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); ZeroMemory(&si, sizeof(STARTUPINFOA)); si.cb = sizeof(STARTUPINFOA); + GetSystemDirectoryW( cmd, MAX_PATH - sizeof(rpcss)/sizeof(WCHAR) ); + strcatW( cmd, rpcss ); - memcpy(cmd, rpcss, sizeof(rpcss)); - - rslt = CreateProcessW( - NULL, /* executable */ - cmd, /* command line */ - NULL, /* process security attributes */ - NULL, /* primary thread security attributes */ - FALSE, /* inherit handles */ - 0, /* creation flags */ - NULL, /* use parent's environment */ - NULL, /* use parent's current directory */ - &si, /* STARTUPINFO pointer */ - &pi /* PROCESS_INFORMATION */ - ); + rslt = CreateProcessW( cmd, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ); if (rslt) { diff --git a/reactos/dll/win32/ole32/ole2.c b/reactos/dll/win32/ole32/ole2.c index 3b87aacd6a6..6bf79fdb507 100644 --- a/reactos/dll/win32/ole32/ole2.c +++ b/reactos/dll/win32/ole32/ole2.c @@ -190,6 +190,9 @@ HRESULT WINAPI OleInitialize(LPVOID reserved) if (FAILED(hr)) return hr; + if (!COM_CurrentInfo()->ole_inits) + hr = S_OK; + /* * Then, it has to initialize the OLE specific modules. * This includes: @@ -1140,8 +1143,8 @@ HRESULT WINAPI OleLockRunning(LPUNKNOWN pUnknown, BOOL fLock, BOOL fLastUnlockCl return hres; } - else - return E_INVALIDARG; + + return S_OK; } diff --git a/reactos/dll/win32/ole32/ole32.spec b/reactos/dll/win32/ole32/ole32.spec index 79e7686c11d..273ddbaa846 100644 --- a/reactos/dll/win32/ole32/ole32.spec +++ b/reactos/dll/win32/ole32/ole32.spec @@ -70,7 +70,7 @@ @ stdcall CoRevokeClassObject(long) @ stdcall CoRevokeInitializeSpy(double) @ stdcall CoRevokeMallocSpy() -@ stdcall CoSetProxyBlanket(ptr long long wstr long long ptr long) +@ stdcall CoSetProxyBlanket(ptr long long ptr long long ptr long) @ stdcall CoSetState(ptr) @ stdcall CoSuspendClassObjects() @ stdcall CoSwitchCallContext(ptr ptr) diff --git a/reactos/dll/win32/ole32/ole32res.rc b/reactos/dll/win32/ole32/ole32res.rc index 0a649a62819..60887a5ec50 100644 --- a/reactos/dll/win32/ole32/ole32res.rc +++ b/reactos/dll/win32/ole32/ole32res.rc @@ -23,7 +23,10 @@ #include "winuser.h" #include "winnls.h" -#include "version.rc" +#define WINE_OLESELFREGISTER +#define WINE_FILENAME_STR "ole32.dll" + +#include /* * Everything that does not depend on language, @@ -44,12 +47,3 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* @makedep: drag_link.cur */ 3 CURSOR drag_link.cur - - -/* - * Everything specific to any language goes - * in one of the specific files. - * Note that you can and may override resources - * which also have a neutral version. This is to - * get localized bitmaps for example. - */ diff --git a/reactos/dll/win32/ole32/oleproxy.c b/reactos/dll/win32/ole32/oleproxy.c index 11a3ad12d8b..184aca13437 100644 --- a/reactos/dll/win32/ole32/oleproxy.c +++ b/reactos/dll/win32/ole32/oleproxy.c @@ -46,6 +46,8 @@ */ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) { + HRESULT hr; + *ppv = NULL; if (IsEqualIID(rclsid,&CLSID_DfMarshal)&&( IsEqualIID(iid,&IID_IClassFactory) || @@ -70,5 +72,9 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) if (IsEqualGUID(rclsid, &CLSID_StdComponentCategoriesMgr)) return ComCatCF_Create(iid, ppv); - return OLE32_DllGetClassObject(rclsid, iid, ppv); + hr = OLE32_DllGetClassObject(rclsid, iid, ppv); + if (SUCCEEDED(hr)) + return hr; + + return Handler_DllGetClassObject(rclsid, iid, ppv); } diff --git a/reactos/dll/win32/ole32/regsvr.c b/reactos/dll/win32/ole32/regsvr.c index 17e78eff0fe..b124a1686c9 100644 --- a/reactos/dll/win32/ole32/regsvr.c +++ b/reactos/dll/win32/ole32/regsvr.c @@ -408,9 +408,6 @@ static GUID const CLSID_StdOleLink = { static GUID const CLSID_PackagerMoniker = { 0x00000308, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} }; -static GUID const CLSID_PSFactoryBuffer_actxprxy = { - 0xB8DA6310, 0xE19B, 0x11D0, {0x93,0x3C,0x00,0xA0,0xC9,0x0D,0xCA,0xA9} }; - extern GUID const CLSID_Picture_Metafile; extern GUID const CLSID_Picture_Dib; @@ -510,42 +507,35 @@ static struct regsvr_coclass const coclass_list[] = { * interface list */ -#define INTERFACE_ENTRY(interface, base, clsid32) { &IID_##interface, #interface, base, sizeof(interface##Vtbl)/sizeof(void*), NULL, clsid32 } -#define BAS_INTERFACE_ENTRY(interface, base) INTERFACE_ENTRY(interface, &IID_##base, NULL) -#define ACTX_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, &CLSID_PSFactoryBuffer_actxprxy) -#define LCL_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, NULL) +#define INTERFACE_ENTRY(interface, base) { &IID_##interface, #interface, base, sizeof(interface##Vtbl)/sizeof(void*), NULL, NULL } static const struct regsvr_interface interface_list[] = { - LCL_INTERFACE_ENTRY(IUnknown), - LCL_INTERFACE_ENTRY(IMalloc), - LCL_INTERFACE_ENTRY(IMarshal), - BAS_INTERFACE_ENTRY(IMoniker, IPersistStream), - LCL_INTERFACE_ENTRY(IMessageFilter), - LCL_INTERFACE_ENTRY(IStdMarshalInfo), - LCL_INTERFACE_ENTRY(IExternalConnection), - LCL_INTERFACE_ENTRY(IMallocSpy), - LCL_INTERFACE_ENTRY(IMultiQI), - BAS_INTERFACE_ENTRY(IPersistStream, IPersist), - BAS_INTERFACE_ENTRY(IPersistStorage, IPersist), - BAS_INTERFACE_ENTRY(IPersistFile, IPersist), - LCL_INTERFACE_ENTRY(IDataAdviseHolder), - LCL_INTERFACE_ENTRY(IOleAdviseHolder), - BAS_INTERFACE_ENTRY(IOleInPlaceObject, IOleWindow), - BAS_INTERFACE_ENTRY(IOleInPlaceUIWindow, IOleWindow), - BAS_INTERFACE_ENTRY(IOleInPlaceActiveObject, IOleWindow), - BAS_INTERFACE_ENTRY(IOleInPlaceSite, IOleWindow), - BAS_INTERFACE_ENTRY(IOleContainer, IParseDisplayName), - BAS_INTERFACE_ENTRY(IOleItemContainer, IOleContainer), - LCL_INTERFACE_ENTRY(IDropSource), - BAS_INTERFACE_ENTRY(IAdviseSink2, IAdviseSink), - BAS_INTERFACE_ENTRY(IViewObject2, IViewObject), - BAS_INTERFACE_ENTRY(IOleCache2, IOleCache), - LCL_INTERFACE_ENTRY(IClientSecurity), - LCL_INTERFACE_ENTRY(IServerSecurity), - ACTX_INTERFACE_ENTRY(IEnumGUID), - ACTX_INTERFACE_ENTRY(IEnumCATEGORYINFO), - ACTX_INTERFACE_ENTRY(ICatRegister), - ACTX_INTERFACE_ENTRY(ICatInformation), + INTERFACE_ENTRY( IUnknown, NULL ), + INTERFACE_ENTRY( IMalloc, NULL ), + INTERFACE_ENTRY( IMarshal, NULL ), + INTERFACE_ENTRY( IMoniker, &IID_IPersistStream ), + INTERFACE_ENTRY( IMessageFilter, NULL ), + INTERFACE_ENTRY( IStdMarshalInfo, NULL ), + INTERFACE_ENTRY( IExternalConnection, NULL ), + INTERFACE_ENTRY( IMallocSpy, NULL ), + INTERFACE_ENTRY( IMultiQI, NULL ), + INTERFACE_ENTRY( IPersistStream, &IID_IPersist ), + INTERFACE_ENTRY( IPersistStorage, &IID_IPersist ), + INTERFACE_ENTRY( IPersistFile, &IID_IPersist ), + INTERFACE_ENTRY( IDataAdviseHolder, NULL ), + INTERFACE_ENTRY( IOleAdviseHolder, NULL ), + INTERFACE_ENTRY( IOleInPlaceObject, &IID_IOleWindow ), + INTERFACE_ENTRY( IOleInPlaceUIWindow, &IID_IOleWindow ), + INTERFACE_ENTRY( IOleInPlaceActiveObject, &IID_IOleWindow ), + INTERFACE_ENTRY( IOleInPlaceSite, &IID_IOleWindow ), + INTERFACE_ENTRY( IOleContainer, &IID_IParseDisplayName ), + INTERFACE_ENTRY( IOleItemContainer, &IID_IOleContainer ), + INTERFACE_ENTRY( IDropSource, NULL ), + INTERFACE_ENTRY( IAdviseSink2, &IID_IAdviseSink ), + INTERFACE_ENTRY( IViewObject2, &IID_IViewObject ), + INTERFACE_ENTRY( IOleCache2, &IID_IOleCache ), + INTERFACE_ENTRY( IClientSecurity, NULL ), + INTERFACE_ENTRY( IServerSecurity, NULL ), { NULL } /* list terminator */ }; diff --git a/reactos/dll/win32/ole32/rpc.c b/reactos/dll/win32/ole32/rpc.c index 9a344653248..0daa4ab815d 100644 --- a/reactos/dll/win32/ole32/rpc.c +++ b/reactos/dll/win32/ole32/rpc.c @@ -1358,7 +1358,7 @@ void RPC_ExecuteCall(struct dispatch_params *params) handlecall = IMessageFilter_HandleInComingCall(COM_CurrentApt()->filter, calltype, - (HTASK)GetCurrentProcessId(), + UlongToHandle(GetCurrentProcessId()), 0 /* FIXME */, &interface_info); TRACE("IMessageFilter_HandleInComingCall returned %d\n", handlecall); diff --git a/reactos/dll/win32/ole32/stg_prop.c b/reactos/dll/win32/ole32/stg_prop.c index 1c77c9e2d3c..52153a20d44 100644 --- a/reactos/dll/win32/ole32/stg_prop.c +++ b/reactos/dll/win32/ole32/stg_prop.c @@ -236,7 +236,7 @@ static PROPVARIANT *PropertyStorage_FindProperty(PropertyStorage_impl *This, { PROPVARIANT *ret = NULL; - dictionary_find(This->propid_to_prop, (void *)propid, (void **)&ret); + dictionary_find(This->propid_to_prop, UlongToPtr(propid), (void **)&ret); TRACE("returning %p\n", ret); return ret; } @@ -246,14 +246,14 @@ static PROPVARIANT *PropertyStorage_FindPropertyByName( PropertyStorage_impl *This, LPCWSTR name) { PROPVARIANT *ret = NULL; - PROPID propid; + void *propid; if (!name) return NULL; if (This->codePage == CP_UNICODE) { - if (dictionary_find(This->name_to_propid, name, (void **)&propid)) - ret = PropertyStorage_FindProperty(This, propid); + if (dictionary_find(This->name_to_propid, name, &propid)) + ret = PropertyStorage_FindProperty(This, PtrToUlong(propid)); } else { @@ -263,9 +263,8 @@ static PROPVARIANT *PropertyStorage_FindPropertyByName( if (SUCCEEDED(hr)) { - if (dictionary_find(This->name_to_propid, ansiName, - (void **)&propid)) - ret = PropertyStorage_FindProperty(This, propid); + if (dictionary_find(This->name_to_propid, ansiName, &propid)) + ret = PropertyStorage_FindProperty(This, PtrToUlong(propid)); CoTaskMemFree(ansiName); } } @@ -278,7 +277,7 @@ static LPWSTR PropertyStorage_FindPropertyNameById(PropertyStorage_impl *This, { LPWSTR ret = NULL; - dictionary_find(This->propid_to_name, (void *)propid, (void **)&ret); + dictionary_find(This->propid_to_name, UlongToPtr(propid), (void **)&ret); TRACE("returning %p\n", ret); return ret; } @@ -490,7 +489,7 @@ static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This, lcid); if (SUCCEEDED(hr)) { - dictionary_insert(This->propid_to_prop, (void *)propid, prop); + dictionary_insert(This->propid_to_prop, UlongToPtr(propid), prop); if (propid > This->highestProp) This->highestProp = propid; } @@ -534,8 +533,8 @@ static HRESULT PropertyStorage_StoreNameWithId(PropertyStorage_impl *This, TRACE("Adding prop name %s, propid %d\n", This->codePage == CP_UNICODE ? debugstr_w((LPCWSTR)name) : debugstr_a(name), id); - dictionary_insert(This->name_to_propid, name, (void *)id); - dictionary_insert(This->propid_to_name, (void *)id, name); + dictionary_insert(This->name_to_propid, name, UlongToPtr(id)); + dictionary_insert(This->propid_to_name, UlongToPtr(id), name); } return hr; } @@ -666,18 +665,16 @@ static HRESULT WINAPI IPropertyStorage_fnDeleteMultiple( { if (rgpspec[i].ulKind == PRSPEC_LPWSTR) { - PROPID propid; + void *propid; - if (dictionary_find(This->name_to_propid, - (void *)rgpspec[i].u.lpwstr, (void **)&propid)) - dictionary_remove(This->propid_to_prop, (void *)propid); + if (dictionary_find(This->name_to_propid, rgpspec[i].u.lpwstr, &propid)) + dictionary_remove(This->propid_to_prop, propid); } else { if (rgpspec[i].u.propid >= PID_FIRST_USABLE && rgpspec[i].u.propid < PID_MIN_READONLY) - dictionary_remove(This->propid_to_prop, - (void *)rgpspec[i].u.propid); + dictionary_remove(This->propid_to_prop, UlongToPtr(rgpspec[i].u.propid)); else hr = STG_E_INVALIDPARAMETER; } @@ -787,10 +784,9 @@ static HRESULT WINAPI IPropertyStorage_fnDeletePropertyNames( { LPWSTR name = NULL; - if (dictionary_find(This->propid_to_name, (void *)rgpropid[i], - (void **)&name)) + if (dictionary_find(This->propid_to_name, UlongToPtr(rgpropid[i]), (void **)&name)) { - dictionary_remove(This->propid_to_name, (void *)rgpropid[i]); + dictionary_remove(This->propid_to_name, UlongToPtr(rgpropid[i])); dictionary_remove(This->name_to_propid, name); } } @@ -955,8 +951,8 @@ static void PropertyStorage_PropNameDestroy(void *k, void *d, void *extra) static int PropertyStorage_PropCompare(const void *a, const void *b, void *extra) { - TRACE("(%d, %d)\n", (PROPID)a, (PROPID)b); - return (PROPID)a - (PROPID)b; + TRACE("(%d, %d)\n", PtrToUlong(a), PtrToUlong(b)); + return PtrToUlong(a) - PtrToUlong(b); } static void PropertyStorage_PropertyDestroy(void *k, void *d, void *extra) @@ -1143,8 +1139,8 @@ static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This, prop->u.pclipdata = CoTaskMemAlloc(sizeof (CLIPDATA)); prop->u.pclipdata->cbSize = len; prop->u.pclipdata->ulClipFmt = tag; - prop->u.pclipdata->pClipData = CoTaskMemAlloc(len); - memcpy(prop->u.pclipdata->pClipData, data+8, len); + prop->u.pclipdata->pClipData = CoTaskMemAlloc(len - sizeof(prop->u.pclipdata->ulClipFmt)); + memcpy(prop->u.pclipdata->pClipData, data+8, len - sizeof(prop->u.pclipdata->ulClipFmt)); } else hr = STG_E_INVALIDPARAMETER; @@ -1406,6 +1402,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This) idOffset->propid, &prop, This->codePage); } } + PropVariantClear(&prop); } } } @@ -1512,7 +1509,7 @@ static BOOL PropertyStorage_DictionaryWriter(const void *key, assert(key); assert(closure); - StorageUtl_WriteDWord((LPBYTE)&propid, 0, (DWORD)value); + StorageUtl_WriteDWord((LPBYTE)&propid, 0, PtrToUlong(value)); c->hr = IStream_Write(This->stm, &propid, sizeof(propid), &count); if (FAILED(c->hr)) goto end; @@ -1735,7 +1732,8 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This, hr = IStream_Write(This->stm, cf_hdr, sizeof(cf_hdr), &count); if (FAILED(hr)) goto end; - hr = IStream_Write(This->stm, &var->u.pclipdata->pClipData, len, &count); + hr = IStream_Write(This->stm, var->u.pclipdata->pClipData, + len - sizeof(var->u.pclipdata->ulClipFmt), &count); if (FAILED(hr)) goto end; bytesWritten = count + sizeof cf_hdr; @@ -1779,7 +1777,7 @@ static BOOL PropertyStorage_PropertiesWriter(const void *key, const void *value, assert(extra); assert(closure); c->hr = PropertyStorage_WritePropertyToStream(This, c->propNum++, - (DWORD)key, value, c->sectionOffset); + PtrToUlong(key), value, c->sectionOffset); return SUCCEEDED(c->hr); } @@ -2396,7 +2394,7 @@ static HRESULT WINAPI IEnumSTATPROPSTG_fnClone( static BOOL prop_enum_stat(const void *k, const void *v, void *extra, void *arg) { enumx_impl *enumx = arg; - PROPID propid = (PROPID) k; + PROPID propid = PtrToUlong(k); const PROPVARIANT *prop = v; STATPROPSTG stat; diff --git a/reactos/dll/win32/ole32/stg_stream.c b/reactos/dll/win32/ole32/stg_stream.c index 79492a406c0..bfecbc72bd1 100644 --- a/reactos/dll/win32/ole32/stg_stream.c +++ b/reactos/dll/win32/ole32/stg_stream.c @@ -74,21 +74,6 @@ static void StgStreamImpl_Destroy(StgStreamImpl* This) This->parentStorage = 0; - /* - * Make sure we clean-up the block chain stream objects that we were using. - */ - if (This->bigBlockChain != 0) - { - BlockChainStream_Destroy(This->bigBlockChain); - This->bigBlockChain = 0; - } - - if (This->smallBlockChain != 0) - { - SmallBlockChainStream_Destroy(This->smallBlockChain); - This->smallBlockChain = 0; - } - /* * Finally, free the memory used-up by the class. */ @@ -179,73 +164,6 @@ static ULONG WINAPI StgStreamImpl_Release( return ref; } -/*** - * This method will open the block chain pointed by the property - * that describes the stream. - * If the stream's size is null, no chain is opened. - */ -static void StgStreamImpl_OpenBlockChain( - StgStreamImpl* This) -{ - StgProperty curProperty; - BOOL readSuccessful; - - /* - * Make sure no old object is left over. - */ - if (This->smallBlockChain != 0) - { - SmallBlockChainStream_Destroy(This->smallBlockChain); - This->smallBlockChain = 0; - } - - if (This->bigBlockChain != 0) - { - BlockChainStream_Destroy(This->bigBlockChain); - This->bigBlockChain = 0; - } - - /* - * Read the information from the property. - */ - readSuccessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage, - This->ownerProperty, - &curProperty); - - if (readSuccessful) - { - This->streamSize = curProperty.size; - - /* - * This code supports only streams that are <32 bits in size. - */ - assert(This->streamSize.u.HighPart == 0); - - if(curProperty.startingBlock == BLOCK_END_OF_CHAIN) - { - assert( (This->streamSize.u.HighPart == 0) && (This->streamSize.u.LowPart == 0) ); - } - else - { - if ( (This->streamSize.u.HighPart == 0) && - (This->streamSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) ) - { - This->smallBlockChain = SmallBlockChainStream_Construct( - This->parentStorage->ancestorStorage, - NULL, - This->ownerProperty); - } - else - { - This->bigBlockChain = BlockChainStream_Construct( - This->parentStorage->ancestorStorage, - NULL, - This->ownerProperty); - } - } - } -} - /*** * This method is part of the ISequentialStream interface. * @@ -264,7 +182,6 @@ static HRESULT WINAPI StgStreamImpl_Read( StgStreamImpl* const This=(StgStreamImpl*)iface; ULONG bytesReadBuffer; - ULONG bytesToReadFromBuffer; HRESULT res; TRACE("(%p, %p, %d, %p)\n", @@ -283,60 +200,21 @@ static HRESULT WINAPI StgStreamImpl_Read( if (pcbRead==0) pcbRead = &bytesReadBuffer; - /* - * Using the known size of the stream, calculate the number of bytes - * to read from the block chain - */ - bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb); - - /* - * Depending on the type of chain that was opened when the stream was constructed, - * we delegate the work to the method that reads the block chains. - */ - if (This->smallBlockChain!=0) - { - res = SmallBlockChainStream_ReadAt(This->smallBlockChain, - This->currentPosition, - bytesToReadFromBuffer, - pv, - pcbRead); - - } - else if (This->bigBlockChain!=0) - { - res = BlockChainStream_ReadAt(This->bigBlockChain, - This->currentPosition, - bytesToReadFromBuffer, - pv, - pcbRead); - } - else - { - /* - * Small and big block chains are both NULL. This case will happen - * when a stream starts with BLOCK_END_OF_CHAIN and has size zero. - */ - - *pcbRead = 0; - res = S_OK; - goto end; - } + res = StorageBaseImpl_StreamReadAt(This->parentStorage, + This->dirEntry, + This->currentPosition, + cb, + pv, + pcbRead); if (SUCCEEDED(res)) { - /* - * We should always be able to read the proper amount of data from the - * chain. - */ - assert(bytesToReadFromBuffer == *pcbRead); - - /* - * Advance the pointer for the number of positions read. - */ - This->currentPosition.u.LowPart += *pcbRead; + /* + * Advance the pointer for the number of positions read. + */ + This->currentPosition.u.LowPart += *pcbRead; } -end: TRACE("<-- %08x\n", res); return res; } @@ -359,7 +237,6 @@ static HRESULT WINAPI StgStreamImpl_Write( { StgStreamImpl* const This=(StgStreamImpl*)iface; - ULARGE_INTEGER newSize; ULONG bytesWritten = 0; HRESULT res; @@ -405,51 +282,13 @@ static HRESULT WINAPI StgStreamImpl_Write( TRACE("<-- S_OK, written 0\n"); return S_OK; } - else - { - newSize.u.HighPart = 0; - newSize.u.LowPart = This->currentPosition.u.LowPart + cb; - } - /* - * Verify if we need to grow the stream - */ - if (newSize.u.LowPart > This->streamSize.u.LowPart) - { - /* grow stream */ - res = IStream_SetSize(iface, newSize); - if (FAILED(res)) - return res; - } - - /* - * Depending on the type of chain that was opened when the stream was constructed, - * we delegate the work to the method that readwrites to the block chains. - */ - if (This->smallBlockChain!=0) - { - res = SmallBlockChainStream_WriteAt(This->smallBlockChain, - This->currentPosition, - cb, - pv, - pcbWritten); - - } - else if (This->bigBlockChain!=0) - { - res = BlockChainStream_WriteAt(This->bigBlockChain, - This->currentPosition, - cb, - pv, - pcbWritten); - } - else - { - /* this should never happen because the IStream_SetSize call above will - * make sure a big or small block chain is created */ - assert(FALSE); - res = 0; - } + res = StorageBaseImpl_StreamWriteAt(This->parentStorage, + This->dirEntry, + This->currentPosition, + cb, + pv, + pcbWritten); /* * Advance the position pointer for the number of positions written. @@ -477,6 +316,8 @@ static HRESULT WINAPI StgStreamImpl_Seek( StgStreamImpl* const This=(StgStreamImpl*)iface; ULARGE_INTEGER newPosition; + DirEntry currentEntry; + HRESULT hr; TRACE("(%p, %d, %d, %p)\n", iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition); @@ -515,7 +356,9 @@ static HRESULT WINAPI StgStreamImpl_Seek( *plibNewPosition = This->currentPosition; break; case STREAM_SEEK_END: - *plibNewPosition = This->streamSize; + hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, This->dirEntry, ¤tEntry); + if (FAILED(hr)) return hr; + *plibNewPosition = currentEntry.size; break; default: WARN("invalid dwOrigin %d\n", dwOrigin); @@ -545,8 +388,7 @@ static HRESULT WINAPI StgStreamImpl_SetSize( { StgStreamImpl* const This=(StgStreamImpl*)iface; - StgProperty curProperty; - BOOL Success; + HRESULT hr; TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart); @@ -574,99 +416,8 @@ static HRESULT WINAPI StgStreamImpl_SetSize( return STG_E_ACCESSDENIED; } - /* In simple mode keep the stream size above the small block limit */ - if (This->parentStorage->ancestorStorage->base.openFlags & STGM_SIMPLE) - libNewSize.u.LowPart = max(libNewSize.u.LowPart, LIMIT_TO_USE_SMALL_BLOCK); - - if (This->streamSize.u.LowPart == libNewSize.u.LowPart) - return S_OK; - - /* - * This will happen if we're creating a stream - */ - if ((This->smallBlockChain == 0) && (This->bigBlockChain == 0)) - { - if (libNewSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) - { - This->smallBlockChain = SmallBlockChainStream_Construct( - This->parentStorage->ancestorStorage, - NULL, - This->ownerProperty); - } - else - { - This->bigBlockChain = BlockChainStream_Construct( - This->parentStorage->ancestorStorage, - NULL, - This->ownerProperty); - } - } - - /* - * Read this stream's property to see if it's small blocks or big blocks - */ - Success = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage, - This->ownerProperty, - &curProperty); - /* - * Determine if we have to switch from small to big blocks or vice versa - */ - if ( (This->smallBlockChain!=0) && - (curProperty.size.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) ) - { - if (libNewSize.u.LowPart >= LIMIT_TO_USE_SMALL_BLOCK) - { - /* - * Transform the small block chain into a big block chain - */ - This->bigBlockChain = Storage32Impl_SmallBlocksToBigBlocks( - This->parentStorage->ancestorStorage, - &This->smallBlockChain); - } - } - else if ( (This->bigBlockChain!=0) && - (curProperty.size.u.LowPart >= LIMIT_TO_USE_SMALL_BLOCK) ) - { - if (libNewSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) - { - /* - * Transform the big block chain into a small block chain - */ - This->smallBlockChain = Storage32Impl_BigBlocksToSmallBlocks( - This->parentStorage->ancestorStorage, - &This->bigBlockChain); - } - } - - if (This->smallBlockChain!=0) - { - Success = SmallBlockChainStream_SetSize(This->smallBlockChain, libNewSize); - } - else - { - Success = BlockChainStream_SetSize(This->bigBlockChain, libNewSize); - } - - /* - * Write the new information about this stream to the property - */ - Success = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage, - This->ownerProperty, - &curProperty); - - curProperty.size.u.HighPart = libNewSize.u.HighPart; - curProperty.size.u.LowPart = libNewSize.u.LowPart; - - if (Success) - { - StorageImpl_WriteProperty(This->parentStorage->ancestorStorage, - This->ownerProperty, - &curProperty); - } - - This->streamSize = libNewSize; - - return S_OK; + hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize); + return hr; } /*** @@ -834,8 +585,8 @@ static HRESULT WINAPI StgStreamImpl_Stat( { StgStreamImpl* const This=(StgStreamImpl*)iface; - StgProperty curProperty; - BOOL readSuccessful; + DirEntry currentEntry; + HRESULT hr; TRACE("%p %p %d\n", This, pstatstg, grfStatFlag); @@ -850,31 +601,30 @@ static HRESULT WINAPI StgStreamImpl_Stat( } /* - * Read the information from the property. + * Read the information from the directory entry. */ - readSuccessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage, - This->ownerProperty, - &curProperty); + hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, + This->dirEntry, + ¤tEntry); - if (readSuccessful) + if (SUCCEEDED(hr)) { - StorageImpl *root = This->parentStorage->ancestorStorage; - - StorageUtl_CopyPropertyToSTATSTG(pstatstg, - &curProperty, + StorageUtl_CopyDirEntryToSTATSTG(This->parentStorage, + pstatstg, + ¤tEntry, grfStatFlag); pstatstg->grfMode = This->grfMode; /* In simple create mode cbSize is the current pos */ - if((root->base.openFlags & STGM_SIMPLE) && root->create) + if((This->parentStorage->openFlags & STGM_SIMPLE) && This->parentStorage->create) pstatstg->cbSize = This->currentPosition; return S_OK; } - WARN("failed to read properties\n"); - return E_FAIL; + WARN("failed to read entry\n"); + return hr; } /*** @@ -910,7 +660,7 @@ static HRESULT WINAPI StgStreamImpl_Clone( if ( ppstm == 0 ) return STG_E_INVALIDPOINTER; - new_stream = StgStreamImpl_Construct (This->parentStorage, This->grfMode, This->ownerProperty); + new_stream = StgStreamImpl_Construct (This->parentStorage, This->grfMode, This->dirEntry); if (!new_stream) return STG_E_INSUFFICIENTMEMORY; /* Currently the only reason for new_stream=0 */ @@ -957,12 +707,12 @@ static const IStreamVtbl StgStreamImpl_Vtbl = * * Params: * parentStorage - Pointer to the storage that contains the stream to open - * ownerProperty - Index of the property that points to this stream. + * dirEntry - Index of the directory entry that points to this stream. */ StgStreamImpl* StgStreamImpl_Construct( StorageBaseImpl* parentStorage, DWORD grfMode, - ULONG ownerProperty) + DirRef dirEntry) { StgStreamImpl* newStream; @@ -991,7 +741,7 @@ StgStreamImpl* StgStreamImpl_Construct( */ newStream->grfMode = grfMode; - newStream->ownerProperty = ownerProperty; + newStream->dirEntry = dirEntry; /* * Start the stream at the beginning. @@ -999,20 +749,6 @@ StgStreamImpl* StgStreamImpl_Construct( newStream->currentPosition.u.HighPart = 0; newStream->currentPosition.u.LowPart = 0; - /* - * Initialize the rest of the data. - */ - newStream->streamSize.u.HighPart = 0; - newStream->streamSize.u.LowPart = 0; - newStream->bigBlockChain = 0; - newStream->smallBlockChain = 0; - - /* - * Read the size from the property and determine if the blocks forming - * this stream are large or small. - */ - StgStreamImpl_OpenBlockChain(newStream); - /* add us to the storage's list of active streams */ StorageBaseImpl_AddStream(parentStorage, newStream); } diff --git a/reactos/dll/win32/ole32/storage32.c b/reactos/dll/win32/ole32/storage32.c index 6e3e1e1d978..837365bdb9d 100644 --- a/reactos/dll/win32/ole32/storage32.c +++ b/reactos/dll/win32/ole32/storage32.c @@ -65,7 +65,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(storage); static const BYTE STORAGE_magic[8] ={0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1}; static const BYTE STORAGE_oldmagic[8] ={0xd0,0xcf,0x11,0xe0,0x0e,0x11,0xfc,0x0d}; -static const char rootPropertyName[] = "Root Entry"; +static const char rootEntryName[] = "Root Entry"; /**************************************************************************** * Storage32InternalImpl definitions. @@ -77,16 +77,21 @@ static const char rootPropertyName[] = "Root Entry"; struct StorageInternalImpl { struct StorageBaseImpl base; + /* - * There is no specific data for this class. + * Entry in the parent's stream tracking list */ + struct list ParentListEntry; + + StorageBaseImpl *parentStorage; }; typedef struct StorageInternalImpl StorageInternalImpl; /* Method definitions for the Storage32InternalImpl class. */ -static StorageInternalImpl* StorageInternalImpl_Construct(StorageImpl* ancestorStorage, - DWORD openFlags, ULONG rootTropertyIndex); +static StorageInternalImpl* StorageInternalImpl_Construct(StorageBaseImpl* parentStorage, + DWORD openFlags, DirRef storageDirEntry); static void StorageImpl_Destroy(StorageBaseImpl* iface); +static void StorageImpl_Invalidate(StorageBaseImpl* iface); static BOOL StorageImpl_ReadBigBlock(StorageImpl* This, ULONG blockIndex, void* buffer); static BOOL StorageImpl_WriteBigBlock(StorageImpl* This, ULONG blockIndex, const void* buffer); static void StorageImpl_SetNextBlockInChain(StorageImpl* This, ULONG blockIndex, ULONG nextBlock); @@ -110,6 +115,30 @@ static BOOL StorageImpl_WriteDWordToBigBlock( StorageImpl* This, static BOOL StorageImpl_ReadDWordFromBigBlock( StorageImpl* This, ULONG blockIndex, ULONG offset, DWORD* value); +static BOOL StorageBaseImpl_IsStreamOpen(StorageBaseImpl * stg, DirRef streamEntry); +static BOOL StorageBaseImpl_IsStorageOpen(StorageBaseImpl * stg, DirRef storageEntry); + +/**************************************************************************** + * Transacted storage object that reads/writes a snapshot file. + */ +typedef struct TransactedSnapshotImpl +{ + struct StorageBaseImpl base; + + /* + * Changes are temporarily saved to the snapshot. + */ + StorageBaseImpl *snapshot; + + /* + * Changes are committed to the transacted parent. + */ + StorageBaseImpl *transactedParent; +} TransactedSnapshotImpl; + +/* Generic function to create a transacted wrapper for a direct storage object. */ +static HRESULT Storage_ConstructTransacted(StorageBaseImpl* parent, StorageBaseImpl** result); + /* OLESTREAM memory structure to use for Get and Put Routines */ /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ typedef struct @@ -159,45 +188,47 @@ typedef struct /*********************************************************************** * Forward declaration of internal functions used by the method DestroyElement */ -static HRESULT deleteStorageProperty( - StorageImpl *parentStorage, - ULONG foundPropertyIndexToDelete, - StgProperty propertyToDelete); +static HRESULT deleteStorageContents( + StorageBaseImpl *parentStorage, + DirRef indexToDelete, + DirEntry entryDataToDelete); -static HRESULT deleteStreamProperty( - StorageImpl *parentStorage, - ULONG foundPropertyIndexToDelete, - StgProperty propertyToDelete); +static HRESULT deleteStreamContents( + StorageBaseImpl *parentStorage, + DirRef indexToDelete, + DirEntry entryDataToDelete); -static HRESULT findPlaceholder( - StorageImpl *storage, - ULONG propertyIndexToStore, - ULONG storagePropertyIndex, - INT typeOfRelation); - -static HRESULT adjustPropertyChain( - StorageImpl *This, - StgProperty propertyToDelete, - StgProperty parentProperty, - ULONG parentPropertyId, - INT typeOfRelation); +static HRESULT removeFromTree( + StorageBaseImpl *This, + DirRef parentStorageIndex, + DirRef deletedIndex); /*********************************************************************** - * Declaration of the functions used to manipulate StgProperty + * Declaration of the functions used to manipulate DirEntry */ -static ULONG getFreeProperty( - StorageImpl *storage); +static HRESULT insertIntoTree( + StorageBaseImpl *This, + DirRef parentStorageIndex, + DirRef newEntryIndex); -static void updatePropertyChain( - StorageImpl *storage, - ULONG newPropertyIndex, - StgProperty newProperty); +static LONG entryNameCmp( + const OLECHAR *name1, + const OLECHAR *name2); -static LONG propertyNameCmp( - const OLECHAR *newProperty, - const OLECHAR *currentProperty); +static DirRef findElement( + StorageBaseImpl *storage, + DirRef storageEntry, + const OLECHAR *name, + DirEntry *data); +static HRESULT findTreeParent( + StorageBaseImpl *storage, + DirRef storageEntry, + const OLECHAR *childName, + DirEntry *parentData, + DirRef *parentEntry, + ULONG *relation); /*********************************************************************** * Declaration of miscellaneous functions... @@ -224,30 +255,15 @@ struct IEnumSTATSTGImpl * since we want to cast this in an IEnumSTATSTG pointer */ LONG ref; /* Reference count */ - StorageImpl* parentStorage; /* Reference to the parent storage */ - ULONG firstPropertyNode; /* Index of the root of the storage to enumerate */ + StorageBaseImpl* parentStorage; /* Reference to the parent storage */ + DirRef storageDirEntry; /* Directory entry of the storage to enumerate */ - /* - * The current implementation of the IEnumSTATSTGImpl class uses a stack - * to walk the property sets to get the content of a storage. This stack - * is implemented by the following 3 data members - */ - ULONG stackSize; - ULONG stackMaxSize; - ULONG* stackToVisit; - -#define ENUMSTATSGT_SIZE_INCREMENT 10 + WCHAR name[DIRENTRY_NAME_MAX_LEN]; /* The most recent name visited */ }; -static IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(StorageImpl* This, ULONG firstPropertyNode); +static IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(StorageBaseImpl* This, DirRef storageDirEntry); static void IEnumSTATSTGImpl_Destroy(IEnumSTATSTGImpl* This); -static void IEnumSTATSTGImpl_PushSearchNode(IEnumSTATSTGImpl* This, ULONG nodeToPush); -static ULONG IEnumSTATSTGImpl_PopSearchNode(IEnumSTATSTGImpl* This, BOOL remove); -static ULONG IEnumSTATSTGImpl_FindProperty(IEnumSTATSTGImpl* This, const OLECHAR* lpszPropName, - StgProperty* buffer); -static INT IEnumSTATSTGImpl_FindParentProperty(IEnumSTATSTGImpl *This, ULONG childProperty, - StgProperty *currentProperty, ULONG *propertyId); /************************************************************************ ** Block Functions @@ -298,20 +314,12 @@ static HRESULT WINAPI StorageBaseImpl_QueryInterface( void** ppvObject) { StorageBaseImpl *This = (StorageBaseImpl *)iface; - /* - * Perform a sanity check on the parameters. - */ + if ( (This==0) || (ppvObject==0) ) return E_INVALIDARG; - /* - * Initialize the return parameter. - */ *ppvObject = 0; - /* - * Compare the riid with the interface IDs implemented by this object. - */ if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IStorage, riid)) { @@ -322,16 +330,9 @@ static HRESULT WINAPI StorageBaseImpl_QueryInterface( *ppvObject = &This->pssVtbl; } - /* - * Check that we obtained an interface. - */ if ((*ppvObject)==0) return E_NOINTERFACE; - /* - * Query Interface always increases the reference count by one when it is - * successful - */ IStorage_AddRef(iface); return S_OK; @@ -368,16 +369,11 @@ static ULONG WINAPI StorageBaseImpl_Release( IStorage* iface) { StorageBaseImpl *This = (StorageBaseImpl *)iface; - /* - * Decrease the reference count on this object. - */ + ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ReleaseRef to %d\n", This, ref); - /* - * If the reference count goes down to 0, perform suicide. - */ if (ref == 0) { /* @@ -385,7 +381,7 @@ static ULONG WINAPI StorageBaseImpl_Release( * destructor of the appropriate derived class. To do this, we are * using virtual functions to implement the destructor. */ - This->v_destructor(This); + StorageBaseImpl_Destroy(This); } return ref; @@ -407,32 +403,22 @@ static HRESULT WINAPI StorageBaseImpl_OpenStream( IStream** ppstm) /* [out] */ { StorageBaseImpl *This = (StorageBaseImpl *)iface; - IEnumSTATSTGImpl* propertyEnumeration; StgStreamImpl* newStream; - StgProperty currentProperty; - ULONG foundPropertyIndex; + DirEntry currentEntry; + DirRef streamEntryRef; HRESULT res = STG_E_UNKNOWN; TRACE("(%p, %s, %p, %x, %d, %p)\n", iface, debugstr_w(pwcsName), reserved1, grfMode, reserved2, ppstm); - /* - * Perform a sanity check on the parameters. - */ if ( (pwcsName==NULL) || (ppstm==0) ) { res = E_INVALIDARG; goto end; } - /* - * Initialize the out parameter - */ *ppstm = NULL; - /* - * Validate the STGM flags - */ if ( FAILED( validateSTGM(grfMode) ) || STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE) { @@ -449,55 +435,53 @@ static HRESULT WINAPI StorageBaseImpl_OpenStream( goto end; } + if (This->reverted) + { + res = STG_E_REVERTED; + goto end; + } + /* * Check that we're compatible with the parent's storage mode, but * only if we are not in transacted mode */ - if(!(This->ancestorStorage->base.openFlags & STGM_TRANSACTED)) { + if(!(This->openFlags & STGM_TRANSACTED)) { if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( This->openFlags ) ) { - res = STG_E_ACCESSDENIED; + res = STG_E_INVALIDFLAG; goto end; } } /* - * Create a property enumeration to search the properties + * Search for the element with the given name */ - propertyEnumeration = IEnumSTATSTGImpl_Construct( - This->ancestorStorage, - This->rootPropertySetIndex); - - /* - * Search the enumeration for the property with the given name - */ - foundPropertyIndex = IEnumSTATSTGImpl_FindProperty( - propertyEnumeration, + streamEntryRef = findElement( + This, + This->storageDirEntry, pwcsName, - ¤tProperty); - - /* - * Delete the property enumeration since we don't need it anymore - */ - IEnumSTATSTGImpl_Destroy(propertyEnumeration); + ¤tEntry); /* * If it was found, construct the stream object and return a pointer to it. */ - if ( (foundPropertyIndex!=PROPERTY_NULL) && - (currentProperty.propertyType==PROPTYPE_STREAM) ) + if ( (streamEntryRef!=DIRENTRY_NULL) && + (currentEntry.stgType==STGTY_STREAM) ) { - newStream = StgStreamImpl_Construct(This, grfMode, foundPropertyIndex); + if (StorageBaseImpl_IsStreamOpen(This, streamEntryRef)) + { + /* A single stream cannot be opened a second time. */ + res = STG_E_ACCESSDENIED; + goto end; + } + + newStream = StgStreamImpl_Construct(This, grfMode, streamEntryRef); if (newStream!=0) { newStream->grfMode = grfMode; *ppstm = (IStream*)newStream; - /* - * Since we are returning a pointer to the interface, we have to - * nail down the reference. - */ IStream_AddRef(*ppstm); res = S_OK; @@ -534,25 +518,28 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage( IStorage** ppstg) /* [out] */ { StorageBaseImpl *This = (StorageBaseImpl *)iface; - StorageInternalImpl* newStorage; - IEnumSTATSTGImpl* propertyEnumeration; - StgProperty currentProperty; - ULONG foundPropertyIndex; + StorageInternalImpl* newStorage; + StorageBaseImpl* newTransactedStorage; + DirEntry currentEntry; + DirRef storageEntryRef; HRESULT res = STG_E_UNKNOWN; TRACE("(%p, %s, %p, %x, %p, %d, %p)\n", iface, debugstr_w(pwcsName), pstgPriority, grfMode, snbExclude, reserved, ppstg); - /* - * Perform a sanity check on the parameters. - */ if ( (This==0) || (pwcsName==NULL) || (ppstg==0) ) { res = E_INVALIDARG; goto end; } + if (This->openFlags & STGM_SIMPLE) + { + res = STG_E_INVALIDFUNCTION; + goto end; + } + /* as documented */ if (snbExclude != NULL) { @@ -560,9 +547,6 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage( goto end; } - /* - * Validate the STGM flags - */ if ( FAILED( validateSTGM(grfMode) )) { res = STG_E_INVALIDFLAG; @@ -580,11 +564,14 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage( goto end; } + if (This->reverted) + return STG_E_REVERTED; + /* * Check that we're compatible with the parent's storage mode, * but only if we are not transacted */ - if(!(This->ancestorStorage->base.openFlags & STGM_TRANSACTED)) { + if(!(This->openFlags & STGM_TRANSACTED)) { if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( This->openFlags ) ) { res = STG_E_ACCESSDENIED; @@ -592,54 +579,49 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage( } } - /* - * Initialize the out parameter - */ *ppstg = NULL; - /* - * Create a property enumeration to search the properties - */ - propertyEnumeration = IEnumSTATSTGImpl_Construct( - This->ancestorStorage, - This->rootPropertySetIndex); - - /* - * Search the enumeration for the property with the given name - */ - foundPropertyIndex = IEnumSTATSTGImpl_FindProperty( - propertyEnumeration, + storageEntryRef = findElement( + This, + This->storageDirEntry, pwcsName, - ¤tProperty); + ¤tEntry); - /* - * Delete the property enumeration since we don't need it anymore - */ - IEnumSTATSTGImpl_Destroy(propertyEnumeration); - - /* - * If it was found, construct the stream object and return a pointer to it. - */ - if ( (foundPropertyIndex!=PROPERTY_NULL) && - (currentProperty.propertyType==PROPTYPE_STORAGE) ) + if ( (storageEntryRef!=DIRENTRY_NULL) && + (currentEntry.stgType==STGTY_STORAGE) ) { - /* - * Construct a new Storage object - */ + if (StorageBaseImpl_IsStorageOpen(This, storageEntryRef)) + { + /* A single storage cannot be opened a second time. */ + res = STG_E_ACCESSDENIED; + goto end; + } + newStorage = StorageInternalImpl_Construct( - This->ancestorStorage, + This, grfMode, - foundPropertyIndex); + storageEntryRef); if (newStorage != 0) { - *ppstg = (IStorage*)newStorage; + if (grfMode & STGM_TRANSACTED) + { + res = Storage_ConstructTransacted(&newStorage->base, &newTransactedStorage); - /* - * Since we are returning a pointer to the interface, - * we have to nail down the reference. - */ - StorageBaseImpl_AddRef(*ppstg); + if (FAILED(res)) + { + HeapFree(GetProcessHeap(), 0, newStorage); + goto end; + } + + *ppstg = (IStorage*)newTransactedStorage; + } + else + { + *ppstg = (IStorage*)newStorage; + } + + list_add_tail(&This->storageHead, &newStorage->ParentListEntry); res = S_OK; goto end; @@ -660,7 +642,7 @@ end: * Storage32BaseImpl_EnumElements (IStorage) * * This method will create an enumerator object that can be used to - * retrieve information about all the properties in the storage object. + * retrieve information about all the elements in the storage object. * * See Windows documentation for more details on IStorage methods. */ @@ -677,27 +659,20 @@ static HRESULT WINAPI StorageBaseImpl_EnumElements( TRACE("(%p, %d, %p, %d, %p)\n", iface, reserved1, reserved2, reserved3, ppenum); - /* - * Perform a sanity check on the parameters. - */ if ( (This==0) || (ppenum==0)) return E_INVALIDARG; - /* - * Construct the enumerator. - */ + if (This->reverted) + return STG_E_REVERTED; + newEnum = IEnumSTATSTGImpl_Construct( - This->ancestorStorage, - This->rootPropertySetIndex); + This, + This->storageDirEntry); if (newEnum!=0) { *ppenum = (IEnumSTATSTG*)newEnum; - /* - * Don't forget to nail down a reference to the new object before - * returning it. - */ IEnumSTATSTG_AddRef(*ppenum); return S_OK; @@ -719,46 +694,41 @@ static HRESULT WINAPI StorageBaseImpl_Stat( DWORD grfStatFlag) /* [in] */ { StorageBaseImpl *This = (StorageBaseImpl *)iface; - StgProperty curProperty; - BOOL readSuccessful; + DirEntry currentEntry; HRESULT res = STG_E_UNKNOWN; TRACE("(%p, %p, %x)\n", iface, pstatstg, grfStatFlag); - /* - * Perform a sanity check on the parameters. - */ if ( (This==0) || (pstatstg==0)) { res = E_INVALIDARG; goto end; } - /* - * Read the information from the property. - */ - readSuccessful = StorageImpl_ReadProperty( - This->ancestorStorage, - This->rootPropertySetIndex, - &curProperty); - - if (readSuccessful) + if (This->reverted) { - StorageUtl_CopyPropertyToSTATSTG( + res = STG_E_REVERTED; + goto end; + } + + res = StorageBaseImpl_ReadDirEntry( + This, + This->storageDirEntry, + ¤tEntry); + + if (SUCCEEDED(res)) + { + StorageUtl_CopyDirEntryToSTATSTG( + This, pstatstg, - &curProperty, + ¤tEntry, grfStatFlag); pstatstg->grfMode = This->openFlags; pstatstg->grfStateBits = This->stateBits; - - res = S_OK; - goto end; } - res = E_FAIL; - end: if (res == S_OK) { @@ -774,10 +744,6 @@ end: * This method will rename the specified element. * * See Windows documentation for more details on IStorage methods. - * - * Implementation notes: The method used to rename consists of creating a clone - * of the deleted StgProperty object setting it with the new name and to - * perform a DestroyElement of the old StgProperty. */ static HRESULT WINAPI StorageBaseImpl_RenameElement( IStorage* iface, @@ -785,141 +751,67 @@ static HRESULT WINAPI StorageBaseImpl_RenameElement( const OLECHAR* pwcsNewName) /* [in] */ { StorageBaseImpl *This = (StorageBaseImpl *)iface; - IEnumSTATSTGImpl* propertyEnumeration; - StgProperty currentProperty; - ULONG foundPropertyIndex; + DirEntry currentEntry; + DirRef currentEntryRef; TRACE("(%p, %s, %s)\n", iface, debugstr_w(pwcsOldName), debugstr_w(pwcsNewName)); - /* - * Create a property enumeration to search the properties - */ - propertyEnumeration = IEnumSTATSTGImpl_Construct(This->ancestorStorage, - This->rootPropertySetIndex); + if (This->reverted) + return STG_E_REVERTED; - /* - * Search the enumeration for the new property name - */ - foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, - pwcsNewName, - ¤tProperty); + currentEntryRef = findElement(This, + This->storageDirEntry, + pwcsNewName, + ¤tEntry); - if (foundPropertyIndex != PROPERTY_NULL) + if (currentEntryRef != DIRENTRY_NULL) { /* - * There is already a property with the new name + * There is already an element with the new name */ - IEnumSTATSTGImpl_Destroy(propertyEnumeration); return STG_E_FILEALREADYEXISTS; } - IEnumSTATSTG_Reset((IEnumSTATSTG*)propertyEnumeration); - /* - * Search the enumeration for the old property name + * Search for the old element name */ - foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, - pwcsOldName, - ¤tProperty); + currentEntryRef = findElement(This, + This->storageDirEntry, + pwcsOldName, + ¤tEntry); - /* - * Delete the property enumeration since we don't need it anymore - */ - IEnumSTATSTGImpl_Destroy(propertyEnumeration); - - if (foundPropertyIndex != PROPERTY_NULL) + if (currentEntryRef != DIRENTRY_NULL) { - StgProperty renamedProperty; - ULONG renamedPropertyIndex; + if (StorageBaseImpl_IsStreamOpen(This, currentEntryRef) || + StorageBaseImpl_IsStorageOpen(This, currentEntryRef)) + { + WARN("Element is already open; cannot rename.\n"); + return STG_E_ACCESSDENIED; + } - /* - * Setup a new property for the renamed property - */ - renamedProperty.sizeOfNameString = - ( lstrlenW(pwcsNewName)+1 ) * sizeof(WCHAR); + /* Remove the element from its current position in the tree */ + removeFromTree(This, This->storageDirEntry, + currentEntryRef); - if (renamedProperty.sizeOfNameString > PROPERTY_NAME_BUFFER_LEN) - return STG_E_INVALIDNAME; + /* Change the name of the element */ + strcpyW(currentEntry.name, pwcsNewName); - strcpyW(renamedProperty.name, pwcsNewName); + /* Delete any sibling links */ + currentEntry.leftChild = DIRENTRY_NULL; + currentEntry.rightChild = DIRENTRY_NULL; - renamedProperty.propertyType = currentProperty.propertyType; - renamedProperty.startingBlock = currentProperty.startingBlock; - renamedProperty.size.u.LowPart = currentProperty.size.u.LowPart; - renamedProperty.size.u.HighPart = currentProperty.size.u.HighPart; - - renamedProperty.previousProperty = PROPERTY_NULL; - renamedProperty.nextProperty = PROPERTY_NULL; - - /* - * Bring the dirProperty link in case it is a storage and in which - * case the renamed storage elements don't require to be reorganized. - */ - renamedProperty.dirProperty = currentProperty.dirProperty; - - /* call CoFileTime to get the current time - renamedProperty.timeStampS1 - renamedProperty.timeStampD1 - renamedProperty.timeStampS2 - renamedProperty.timeStampD2 - renamedProperty.propertyUniqueID - */ - - /* - * Obtain a free property in the property chain - */ - renamedPropertyIndex = getFreeProperty(This->ancestorStorage); - - /* - * Save the new property into the new property spot - */ - StorageImpl_WriteProperty( - This->ancestorStorage, - renamedPropertyIndex, - &renamedProperty); - - /* - * Find a spot in the property chain for our newly created property. - */ - updatePropertyChain( - (StorageImpl*)This, - renamedPropertyIndex, - renamedProperty); - - /* - * At this point the renamed property has been inserted in the tree, - * now, before Destroying the old property we must zero its dirProperty - * otherwise the DestroyProperty below will zap it all and we do not want - * this to happen. - * Also, we fake that the old property is a storage so the DestroyProperty - * will not do a SetSize(0) on the stream data. - * - * This means that we need to tweak the StgProperty if it is a stream or a - * non empty storage. - */ - StorageImpl_ReadProperty(This->ancestorStorage, - foundPropertyIndex, - ¤tProperty); - - currentProperty.dirProperty = PROPERTY_NULL; - currentProperty.propertyType = PROPTYPE_STORAGE; - StorageImpl_WriteProperty( - This->ancestorStorage, - foundPropertyIndex, - ¤tProperty); - - /* - * Invoke Destroy to get rid of the ole property and automatically redo - * the linking of its previous and next members... - */ - IStorage_DestroyElement(iface, pwcsOldName); + StorageBaseImpl_WriteDirEntry(This, currentEntryRef, + ¤tEntry); + /* Insert the element in a new position in the tree */ + insertIntoTree(This, This->storageDirEntry, + currentEntryRef); } else { /* - * There is no property with the old name + * There is no element with the old name */ return STG_E_FILENOTFOUND; } @@ -943,18 +835,15 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream( IStream** ppstm) /* [out] */ { StorageBaseImpl *This = (StorageBaseImpl *)iface; - IEnumSTATSTGImpl* propertyEnumeration; StgStreamImpl* newStream; - StgProperty currentProperty, newStreamProperty; - ULONG foundPropertyIndex, newPropertyIndex; + DirEntry currentEntry, newStreamEntry; + DirRef currentEntryRef, newStreamEntryRef; + HRESULT hr; TRACE("(%p, %s, %x, %d, %d, %p)\n", iface, debugstr_w(pwcsName), grfMode, reserved1, reserved2, ppstm); - /* - * Validate parameters - */ if (ppstm == 0) return STG_E_INVALIDPOINTER; @@ -964,15 +853,15 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream( if (reserved1 || reserved2) return STG_E_INVALIDPARAMETER; - /* - * Validate the STGM flags - */ if ( FAILED( validateSTGM(grfMode) )) return STG_E_INVALIDFLAG; if (STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE) return STG_E_INVALIDFLAG; + if (This->reverted) + return STG_E_REVERTED; + /* * As documented. */ @@ -980,133 +869,101 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream( (grfMode & STGM_TRANSACTED)) return STG_E_INVALIDFUNCTION; - /* Can't create a stream on read-only storage */ - if ( STGM_ACCESS_MODE( This->openFlags ) == STGM_READ ) - return STG_E_ACCESSDENIED; - /* - * Check that we're compatible with the parent's storage mode - * if not in transacted mode + * Don't worry about permissions in transacted mode, as we can always write + * changes; we just can't always commit them. */ - if(!(This->ancestorStorage->base.openFlags & STGM_TRANSACTED)) { + if(!(This->openFlags & STGM_TRANSACTED)) { + /* Can't create a stream on read-only storage */ + if ( STGM_ACCESS_MODE( This->openFlags ) == STGM_READ ) + return STG_E_ACCESSDENIED; + + /* Can't create a stream with greater access than the parent. */ if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( This->openFlags ) ) return STG_E_ACCESSDENIED; } - if(This->ancestorStorage->base.openFlags & STGM_SIMPLE) + if(This->openFlags & STGM_SIMPLE) if(grfMode & STGM_CREATE) return STG_E_INVALIDFLAG; - /* - * Initialize the out parameter - */ *ppstm = 0; - /* - * Create a property enumeration to search the properties - */ - propertyEnumeration = IEnumSTATSTGImpl_Construct(This->ancestorStorage, - This->rootPropertySetIndex); + currentEntryRef = findElement(This, + This->storageDirEntry, + pwcsName, + ¤tEntry); - foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, - pwcsName, - ¤tProperty); - - IEnumSTATSTGImpl_Destroy(propertyEnumeration); - - if (foundPropertyIndex != PROPERTY_NULL) + if (currentEntryRef != DIRENTRY_NULL) { /* * An element with this name already exists */ if (STGM_CREATE_MODE(grfMode) == STGM_CREATE) { - StgStreamImpl *strm; - - LIST_FOR_EACH_ENTRY(strm, &This->strmHead, StgStreamImpl, StrmListEntry) - { - if (strm->ownerProperty == foundPropertyIndex) - { - TRACE("Stream deleted %p\n", strm); - strm->parentStorage = NULL; - list_remove(&strm->StrmListEntry); - } - } IStorage_DestroyElement(iface, pwcsName); } else return STG_E_FILEALREADYEXISTS; } - else if (STGM_ACCESS_MODE(This->openFlags) == STGM_READ) - { - WARN("read-only storage\n"); - return STG_E_ACCESSDENIED; - } /* - * memset the empty property + * memset the empty entry */ - memset(&newStreamProperty, 0, sizeof(StgProperty)); + memset(&newStreamEntry, 0, sizeof(DirEntry)); - newStreamProperty.sizeOfNameString = + newStreamEntry.sizeOfNameString = ( lstrlenW(pwcsName)+1 ) * sizeof(WCHAR); - if (newStreamProperty.sizeOfNameString > PROPERTY_NAME_BUFFER_LEN) + if (newStreamEntry.sizeOfNameString > DIRENTRY_NAME_BUFFER_LEN) return STG_E_INVALIDNAME; - strcpyW(newStreamProperty.name, pwcsName); + strcpyW(newStreamEntry.name, pwcsName); - newStreamProperty.propertyType = PROPTYPE_STREAM; - newStreamProperty.startingBlock = BLOCK_END_OF_CHAIN; - newStreamProperty.size.u.LowPart = 0; - newStreamProperty.size.u.HighPart = 0; + newStreamEntry.stgType = STGTY_STREAM; + newStreamEntry.startingBlock = BLOCK_END_OF_CHAIN; + newStreamEntry.size.u.LowPart = 0; + newStreamEntry.size.u.HighPart = 0; - newStreamProperty.previousProperty = PROPERTY_NULL; - newStreamProperty.nextProperty = PROPERTY_NULL; - newStreamProperty.dirProperty = PROPERTY_NULL; + newStreamEntry.leftChild = DIRENTRY_NULL; + newStreamEntry.rightChild = DIRENTRY_NULL; + newStreamEntry.dirRootEntry = DIRENTRY_NULL; /* call CoFileTime to get the current time - newStreamProperty.timeStampS1 - newStreamProperty.timeStampD1 - newStreamProperty.timeStampS2 - newStreamProperty.timeStampD2 + newStreamEntry.ctime + newStreamEntry.mtime */ - /* newStreamProperty.propertyUniqueID */ + /* newStreamEntry.clsid */ /* - * Get a free property or create a new one + * Create an entry with the new data */ - newPropertyIndex = getFreeProperty(This->ancestorStorage); + hr = StorageBaseImpl_CreateDirEntry(This, &newStreamEntry, &newStreamEntryRef); + if (FAILED(hr)) + return hr; /* - * Save the new property into the new property spot + * Insert the new entry in the parent storage's tree. */ - StorageImpl_WriteProperty( - This->ancestorStorage, - newPropertyIndex, - &newStreamProperty); - - /* - * Find a spot in the property chain for our newly created property. - */ - updatePropertyChain( - (StorageImpl*)This, - newPropertyIndex, - newStreamProperty); + hr = insertIntoTree( + This, + This->storageDirEntry, + newStreamEntryRef); + if (FAILED(hr)) + { + StorageBaseImpl_DestroyDirEntry(This, newStreamEntryRef); + return hr; + } /* * Open the stream to return it. */ - newStream = StgStreamImpl_Construct(This, grfMode, newPropertyIndex); + newStream = StgStreamImpl_Construct(This, grfMode, newStreamEntryRef); if (newStream != 0) { *ppstm = (IStream*)newStream; - /* - * Since we are returning a pointer to the interface, we have to nail down - * the reference. - */ IStream_AddRef(*ppstm); } else @@ -1120,7 +977,7 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream( /************************************************************************ * Storage32BaseImpl_SetClass (IStorage) * - * This method will write the specified CLSID in the property of this + * This method will write the specified CLSID in the directory entry of this * storage. * * See Windows documentation for more details on IStorage methods. @@ -1130,24 +987,24 @@ static HRESULT WINAPI StorageBaseImpl_SetClass( REFCLSID clsid) /* [in] */ { StorageBaseImpl *This = (StorageBaseImpl *)iface; - HRESULT hRes = E_FAIL; - StgProperty curProperty; - BOOL success; + HRESULT hRes; + DirEntry currentEntry; TRACE("(%p, %p)\n", iface, clsid); - success = StorageImpl_ReadProperty(This->ancestorStorage, - This->rootPropertySetIndex, - &curProperty); - if (success) - { - curProperty.propertyUniqueID = *clsid; + if (This->reverted) + return STG_E_REVERTED; - success = StorageImpl_WriteProperty(This->ancestorStorage, - This->rootPropertySetIndex, - &curProperty); - if (success) - hRes = S_OK; + hRes = StorageBaseImpl_ReadDirEntry(This, + This->storageDirEntry, + ¤tEntry); + if (SUCCEEDED(hRes)) + { + currentEntry.clsid = *clsid; + + hRes = StorageBaseImpl_WriteDirEntry(This, + This->storageDirEntry, + ¤tEntry); } return hRes; @@ -1158,13 +1015,13 @@ static HRESULT WINAPI StorageBaseImpl_SetClass( */ /************************************************************************ - * Storage32Impl_CreateStorage (IStorage) + * Storage32BaseImpl_CreateStorage (IStorage) * * This method will create the storage object within the provided storage. * * See Windows documentation for more details on IStorage methods. */ -static HRESULT WINAPI StorageImpl_CreateStorage( +static HRESULT WINAPI StorageBaseImpl_CreateStorage( IStorage* iface, const OLECHAR *pwcsName, /* [string][in] */ DWORD grfMode, /* [in] */ @@ -1172,36 +1029,31 @@ static HRESULT WINAPI StorageImpl_CreateStorage( DWORD reserved2, /* [in] */ IStorage **ppstg) /* [out] */ { - StorageImpl* const This=(StorageImpl*)iface; + StorageBaseImpl* const This=(StorageBaseImpl*)iface; - IEnumSTATSTGImpl *propertyEnumeration; - StgProperty currentProperty; - StgProperty newProperty; - ULONG foundPropertyIndex; - ULONG newPropertyIndex; + DirEntry currentEntry; + DirEntry newEntry; + DirRef currentEntryRef; + DirRef newEntryRef; HRESULT hr; TRACE("(%p, %s, %x, %d, %d, %p)\n", iface, debugstr_w(pwcsName), grfMode, reserved1, reserved2, ppstg); - /* - * Validate parameters - */ if (ppstg == 0) return STG_E_INVALIDPOINTER; + if (This->openFlags & STGM_SIMPLE) + { + return STG_E_INVALIDFUNCTION; + } + if (pwcsName == 0) return STG_E_INVALIDNAME; - /* - * Initialize the out parameter - */ *ppstg = NULL; - /* - * Validate the STGM flags - */ if ( FAILED( validateSTGM(grfMode) ) || (grfMode & STGM_DELETEONRELEASE) ) { @@ -1209,33 +1061,32 @@ static HRESULT WINAPI StorageImpl_CreateStorage( return STG_E_INVALIDFLAG; } + if (This->reverted) + return STG_E_REVERTED; + /* * Check that we're compatible with the parent's storage mode */ - if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( This->base.openFlags ) ) + if ( !(This->openFlags & STGM_TRANSACTED) && + STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( This->openFlags ) ) { WARN("access denied\n"); return STG_E_ACCESSDENIED; } - /* - * Create a property enumeration and search the properties - */ - propertyEnumeration = IEnumSTATSTGImpl_Construct( This->base.ancestorStorage, - This->base.rootPropertySetIndex); + currentEntryRef = findElement(This, + This->storageDirEntry, + pwcsName, + ¤tEntry); - foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, - pwcsName, - ¤tProperty); - IEnumSTATSTGImpl_Destroy(propertyEnumeration); - - if (foundPropertyIndex != PROPERTY_NULL) + if (currentEntryRef != DIRENTRY_NULL) { /* * An element with this name already exists */ if (STGM_CREATE_MODE(grfMode) == STGM_CREATE && - STGM_ACCESS_MODE(This->base.openFlags) != STGM_READ) + ((This->openFlags & STGM_TRANSACTED) || + STGM_ACCESS_MODE(This->openFlags) != STGM_READ)) { hr = IStorage_DestroyElement(iface, pwcsName); if (FAILED(hr)) @@ -1247,65 +1098,60 @@ static HRESULT WINAPI StorageImpl_CreateStorage( return STG_E_FILEALREADYEXISTS; } } - else if (STGM_ACCESS_MODE(This->base.openFlags) == STGM_READ) + else if (!(This->openFlags & STGM_TRANSACTED) && + STGM_ACCESS_MODE(This->openFlags) == STGM_READ) { WARN("read-only storage\n"); return STG_E_ACCESSDENIED; } - /* - * memset the empty property - */ - memset(&newProperty, 0, sizeof(StgProperty)); + memset(&newEntry, 0, sizeof(DirEntry)); - newProperty.sizeOfNameString = (lstrlenW(pwcsName)+1)*sizeof(WCHAR); + newEntry.sizeOfNameString = (lstrlenW(pwcsName)+1)*sizeof(WCHAR); - if (newProperty.sizeOfNameString > PROPERTY_NAME_BUFFER_LEN) + if (newEntry.sizeOfNameString > DIRENTRY_NAME_BUFFER_LEN) { FIXME("name too long\n"); return STG_E_INVALIDNAME; } - strcpyW(newProperty.name, pwcsName); + strcpyW(newEntry.name, pwcsName); - newProperty.propertyType = PROPTYPE_STORAGE; - newProperty.startingBlock = BLOCK_END_OF_CHAIN; - newProperty.size.u.LowPart = 0; - newProperty.size.u.HighPart = 0; + newEntry.stgType = STGTY_STORAGE; + newEntry.startingBlock = BLOCK_END_OF_CHAIN; + newEntry.size.u.LowPart = 0; + newEntry.size.u.HighPart = 0; - newProperty.previousProperty = PROPERTY_NULL; - newProperty.nextProperty = PROPERTY_NULL; - newProperty.dirProperty = PROPERTY_NULL; + newEntry.leftChild = DIRENTRY_NULL; + newEntry.rightChild = DIRENTRY_NULL; + newEntry.dirRootEntry = DIRENTRY_NULL; /* call CoFileTime to get the current time - newProperty.timeStampS1 - newProperty.timeStampD1 - newProperty.timeStampS2 - newProperty.timeStampD2 + newEntry.ctime + newEntry.mtime */ - /* newStorageProperty.propertyUniqueID */ + /* newEntry.clsid */ /* - * Obtain a free property in the property chain + * Create a new directory entry for the storage */ - newPropertyIndex = getFreeProperty(This->base.ancestorStorage); + hr = StorageBaseImpl_CreateDirEntry(This, &newEntry, &newEntryRef); + if (FAILED(hr)) + return hr; /* - * Save the new property into the new property spot + * Insert the new directory entry into the parent storage's tree */ - StorageImpl_WriteProperty( - This->base.ancestorStorage, - newPropertyIndex, - &newProperty); - - /* - * Find a spot in the property chain for our newly created property. - */ - updatePropertyChain( + hr = insertIntoTree( This, - newPropertyIndex, - newProperty); + This->storageDirEntry, + newEntryRef); + if (FAILED(hr)) + { + StorageBaseImpl_DestroyDirEntry(This, newEntryRef); + return hr; + } /* * Open it to get a pointer to return. @@ -1326,122 +1172,198 @@ static HRESULT WINAPI StorageImpl_CreateStorage( * * Internal Method * - * Get a free property or create a new one. + * Reserve a directory entry in the file and initialize it. */ -static ULONG getFreeProperty( - StorageImpl *storage) +static HRESULT StorageImpl_CreateDirEntry( + StorageBaseImpl *base, + const DirEntry *newData, + DirRef *index) { - ULONG currentPropertyIndex = 0; - ULONG newPropertyIndex = PROPERTY_NULL; - BOOL readSuccessful = TRUE; - StgProperty currentProperty; + StorageImpl *storage = (StorageImpl*)base; + ULONG currentEntryIndex = 0; + ULONG newEntryIndex = DIRENTRY_NULL; + HRESULT hr = S_OK; + BYTE currentData[RAW_DIRENTRY_SIZE]; + WORD sizeOfNameString; do { - /* - * Start by reading the root property - */ - readSuccessful = StorageImpl_ReadProperty(storage->base.ancestorStorage, - currentPropertyIndex, - ¤tProperty); - if (readSuccessful) + hr = StorageImpl_ReadRawDirEntry(storage, + currentEntryIndex, + currentData); + + if (SUCCEEDED(hr)) { - if (currentProperty.sizeOfNameString == 0) + StorageUtl_ReadWord( + currentData, + OFFSET_PS_NAMELENGTH, + &sizeOfNameString); + + if (sizeOfNameString == 0) { /* - * The property existis and is available, we found it. + * The entry exists and is available, we found it. */ - newPropertyIndex = currentPropertyIndex; + newEntryIndex = currentEntryIndex; } } else { /* - * We exhausted the property list, we will create more space below + * We exhausted the directory entries, we will create more space below */ - newPropertyIndex = currentPropertyIndex; + newEntryIndex = currentEntryIndex; } - currentPropertyIndex++; + currentEntryIndex++; - } while (newPropertyIndex == PROPERTY_NULL); + } while (newEntryIndex == DIRENTRY_NULL); /* - * grow the property chain + * grow the directory stream */ - if (! readSuccessful) + if (FAILED(hr)) { - StgProperty emptyProperty; + BYTE emptyData[RAW_DIRENTRY_SIZE]; ULARGE_INTEGER newSize; - ULONG propertyIndex; - ULONG lastProperty = 0; + ULONG entryIndex; + ULONG lastEntry = 0; ULONG blockCount = 0; /* - * obtain the new count of property blocks + * obtain the new count of blocks in the directory stream */ blockCount = BlockChainStream_GetCount( - storage->base.ancestorStorage->rootBlockChain)+1; + storage->rootBlockChain)+1; /* - * initialize the size used by the property stream + * initialize the size used by the directory stream */ newSize.u.HighPart = 0; newSize.u.LowPart = storage->bigBlockSize * blockCount; /* - * add a property block to the property chain + * add a block to the directory stream */ - BlockChainStream_SetSize(storage->base.ancestorStorage->rootBlockChain, newSize); + BlockChainStream_SetSize(storage->rootBlockChain, newSize); /* - * memset the empty property in order to initialize the unused newly - * created property + * memset the empty entry in order to initialize the unused newly + * created entries */ - memset(&emptyProperty, 0, sizeof(StgProperty)); + memset(&emptyData, 0, RAW_DIRENTRY_SIZE); /* * initialize them */ - lastProperty = storage->bigBlockSize / PROPSET_BLOCK_SIZE * blockCount; + lastEntry = storage->bigBlockSize / RAW_DIRENTRY_SIZE * blockCount; for( - propertyIndex = newPropertyIndex; - propertyIndex < lastProperty; - propertyIndex++) + entryIndex = newEntryIndex + 1; + entryIndex < lastEntry; + entryIndex++) { - StorageImpl_WriteProperty( - storage->base.ancestorStorage, - propertyIndex, - &emptyProperty); + StorageImpl_WriteRawDirEntry( + storage, + entryIndex, + emptyData); } } - return newPropertyIndex; + UpdateRawDirEntry(currentData, newData); + + hr = StorageImpl_WriteRawDirEntry(storage, newEntryIndex, currentData); + + if (SUCCEEDED(hr)) + *index = newEntryIndex; + + return hr; } +/*************************************************************************** + * + * Internal Method + * + * Mark a directory entry in the file as free. + */ +static HRESULT StorageImpl_DestroyDirEntry( + StorageBaseImpl *base, + DirRef index) +{ + HRESULT hr; + BYTE emptyData[RAW_DIRENTRY_SIZE]; + StorageImpl *storage = (StorageImpl*)base; + + memset(&emptyData, 0, RAW_DIRENTRY_SIZE); + + hr = StorageImpl_WriteRawDirEntry(storage, index, emptyData); + + return hr; +} + + +/*************************************************************************** + * + * Internal Method + * + * Destroy an entry, its attached data, and all entries reachable from it. + */ +static HRESULT DestroyReachableEntries( + StorageBaseImpl *base, + DirRef index) +{ + HRESULT hr = S_OK; + DirEntry data; + ULARGE_INTEGER zero; + + zero.QuadPart = 0; + + if (index != DIRENTRY_NULL) + { + hr = StorageBaseImpl_ReadDirEntry(base, index, &data); + + if (SUCCEEDED(hr)) + hr = DestroyReachableEntries(base, data.dirRootEntry); + + if (SUCCEEDED(hr)) + hr = DestroyReachableEntries(base, data.leftChild); + + if (SUCCEEDED(hr)) + hr = DestroyReachableEntries(base, data.rightChild); + + if (SUCCEEDED(hr)) + hr = StorageBaseImpl_StreamSetSize(base, index, zero); + + if (SUCCEEDED(hr)) + hr = StorageBaseImpl_DestroyDirEntry(base, index); + } + + return hr; +} + + /**************************************************************************** * * Internal Method * - * Case insensitive comparison of StgProperty.name by first considering + * Case insensitive comparison of DirEntry.name by first considering * their size. * - * Returns <0 when newProperty < currentProperty - * >0 when newProperty > currentProperty - * 0 when newProperty == currentProperty + * Returns <0 when name1 < name2 + * >0 when name1 > name2 + * 0 when name1 == name2 */ -static LONG propertyNameCmp( - const OLECHAR *newProperty, - const OLECHAR *currentProperty) +static LONG entryNameCmp( + const OLECHAR *name1, + const OLECHAR *name2) { - LONG diff = lstrlenW(newProperty) - lstrlenW(currentProperty); + LONG diff = lstrlenW(name1) - lstrlenW(name2); - if (diff == 0) + while (diff == 0 && *name1 != 0) { /* * We compare the string themselves only when they are of the same length */ - diff = lstrcmpiW( newProperty, currentProperty); + diff = toupperW(*name1++) - toupperW(*name2++); } return diff; @@ -1451,84 +1373,92 @@ static LONG propertyNameCmp( * * Internal Method * - * Properly link this new element in the property chain. + * Add a directory entry to a storage */ -static void updatePropertyChain( - StorageImpl *storage, - ULONG newPropertyIndex, - StgProperty newProperty) +static HRESULT insertIntoTree( + StorageBaseImpl *This, + DirRef parentStorageIndex, + DirRef newEntryIndex) { - StgProperty currentProperty; + DirEntry currentEntry; + DirEntry newEntry; /* - * Read the root property + * Read the inserted entry */ - StorageImpl_ReadProperty(storage->base.ancestorStorage, - storage->base.rootPropertySetIndex, - ¤tProperty); + StorageBaseImpl_ReadDirEntry(This, + newEntryIndex, + &newEntry); - if (currentProperty.dirProperty != PROPERTY_NULL) + /* + * Read the storage entry + */ + StorageBaseImpl_ReadDirEntry(This, + parentStorageIndex, + ¤tEntry); + + if (currentEntry.dirRootEntry != DIRENTRY_NULL) { /* * The root storage contains some element, therefore, start the research * for the appropriate location. */ BOOL found = 0; - ULONG current, next, previous, currentPropertyId; + DirRef current, next, previous, currentEntryId; /* - * Keep the StgProperty sequence number of the storage first property + * Keep a reference to the root of the storage's element tree */ - currentPropertyId = currentProperty.dirProperty; + currentEntryId = currentEntry.dirRootEntry; /* * Read */ - StorageImpl_ReadProperty(storage->base.ancestorStorage, - currentProperty.dirProperty, - ¤tProperty); + StorageBaseImpl_ReadDirEntry(This, + currentEntry.dirRootEntry, + ¤tEntry); - previous = currentProperty.previousProperty; - next = currentProperty.nextProperty; - current = currentPropertyId; + previous = currentEntry.leftChild; + next = currentEntry.rightChild; + current = currentEntryId; while (found == 0) { - LONG diff = propertyNameCmp( newProperty.name, currentProperty.name); + LONG diff = entryNameCmp( newEntry.name, currentEntry.name); if (diff < 0) { - if (previous != PROPERTY_NULL) + if (previous != DIRENTRY_NULL) { - StorageImpl_ReadProperty(storage->base.ancestorStorage, - previous, - ¤tProperty); + StorageBaseImpl_ReadDirEntry(This, + previous, + ¤tEntry); current = previous; } else { - currentProperty.previousProperty = newPropertyIndex; - StorageImpl_WriteProperty(storage->base.ancestorStorage, - current, - ¤tProperty); + currentEntry.leftChild = newEntryIndex; + StorageBaseImpl_WriteDirEntry(This, + current, + ¤tEntry); found = 1; } } else if (diff > 0) { - if (next != PROPERTY_NULL) + if (next != DIRENTRY_NULL) { - StorageImpl_ReadProperty(storage->base.ancestorStorage, - next, - ¤tProperty); + StorageBaseImpl_ReadDirEntry(This, + next, + ¤tEntry); current = next; } else { - currentProperty.nextProperty = newPropertyIndex; - StorageImpl_WriteProperty(storage->base.ancestorStorage, - current, - ¤tProperty); + currentEntry.rightChild = newEntryIndex; + StorageBaseImpl_WriteDirEntry(This, + current, + ¤tEntry); found = 1; } } @@ -1538,30 +1468,131 @@ static void updatePropertyChain( * Trying to insert an item with the same name in the * subtree structure. */ - assert(FALSE); + return STG_E_FILEALREADYEXISTS; } - previous = currentProperty.previousProperty; - next = currentProperty.nextProperty; + previous = currentEntry.leftChild; + next = currentEntry.rightChild; } } else { /* - * The root storage is empty, link the new property to its dir property + * The storage is empty, make the new entry the root of its element tree */ - currentProperty.dirProperty = newPropertyIndex; - StorageImpl_WriteProperty(storage->base.ancestorStorage, - storage->base.rootPropertySetIndex, - ¤tProperty); + currentEntry.dirRootEntry = newEntryIndex; + StorageBaseImpl_WriteDirEntry(This, + parentStorageIndex, + ¤tEntry); } + + return S_OK; +} + +/**************************************************************************** + * + * Internal Method + * + * Find and read the element of a storage with the given name. + */ +static DirRef findElement(StorageBaseImpl *storage, DirRef storageEntry, + const OLECHAR *name, DirEntry *data) +{ + DirRef currentEntry; + + /* Read the storage entry to find the root of the tree. */ + StorageBaseImpl_ReadDirEntry(storage, storageEntry, data); + + currentEntry = data->dirRootEntry; + + while (currentEntry != DIRENTRY_NULL) + { + LONG cmp; + + StorageBaseImpl_ReadDirEntry(storage, currentEntry, data); + + cmp = entryNameCmp(name, data->name); + + if (cmp == 0) + /* found it */ + break; + + else if (cmp < 0) + currentEntry = data->leftChild; + + else if (cmp > 0) + currentEntry = data->rightChild; + } + + return currentEntry; +} + +/**************************************************************************** + * + * Internal Method + * + * Find and read the binary tree parent of the element with the given name. + * + * If there is no such element, find a place where it could be inserted and + * return STG_E_FILENOTFOUND. + */ +static HRESULT findTreeParent(StorageBaseImpl *storage, DirRef storageEntry, + const OLECHAR *childName, DirEntry *parentData, DirRef *parentEntry, + ULONG *relation) +{ + DirRef childEntry; + DirEntry childData; + + /* Read the storage entry to find the root of the tree. */ + StorageBaseImpl_ReadDirEntry(storage, storageEntry, parentData); + + *parentEntry = storageEntry; + *relation = DIRENTRY_RELATION_DIR; + + childEntry = parentData->dirRootEntry; + + while (childEntry != DIRENTRY_NULL) + { + LONG cmp; + + StorageBaseImpl_ReadDirEntry(storage, childEntry, &childData); + + cmp = entryNameCmp(childName, childData.name); + + if (cmp == 0) + /* found it */ + break; + + else if (cmp < 0) + { + *parentData = childData; + *parentEntry = childEntry; + *relation = DIRENTRY_RELATION_PREVIOUS; + + childEntry = parentData->leftChild; + } + + else if (cmp > 0) + { + *parentData = childData; + *parentEntry = childEntry; + *relation = DIRENTRY_RELATION_NEXT; + + childEntry = parentData->rightChild; + } + } + + if (childEntry == DIRENTRY_NULL) + return STG_E_FILENOTFOUND; + else + return S_OK; } /************************************************************************* * CopyTo (IStorage) */ -static HRESULT WINAPI StorageImpl_CopyTo( +static HRESULT WINAPI StorageBaseImpl_CopyTo( IStorage* iface, DWORD ciidExclude, /* [in] */ const IID* rgiidExclude, /* [size_is][unique][in] */ @@ -1573,17 +1604,13 @@ static HRESULT WINAPI StorageImpl_CopyTo( HRESULT hr; IStorage *pstgTmp, *pstgChild; IStream *pstrTmp, *pstrChild; - - if ((ciidExclude != 0) || (rgiidExclude != NULL) || (snbExclude != NULL)) - FIXME("Exclude option not implemented\n"); + BOOL skip = FALSE, skip_storage = FALSE, skip_stream = FALSE; + int i; TRACE("(%p, %d, %p, %p, %p)\n", iface, ciidExclude, rgiidExclude, snbExclude, pstgDest); - /* - * Perform a sanity check - */ if ( pstgDest == 0 ) return STG_E_INVALIDPOINTER; @@ -1601,6 +1628,16 @@ static HRESULT WINAPI StorageImpl_CopyTo( IStorage_Stat( iface, &curElement, STATFLAG_NONAME); IStorage_SetClass( pstgDest, &curElement.clsid ); + for(i = 0; i < ciidExclude; ++i) + { + if(IsEqualGUID(&IID_IStorage, &rgiidExclude[i])) + skip_storage = TRUE; + else if(IsEqualGUID(&IID_IStream, &rgiidExclude[i])) + skip_stream = TRUE; + else + WARN("Unknown excluded GUID: %s\n", debugstr_guid(&rgiidExclude[i])); + } + do { /* @@ -1614,8 +1651,26 @@ static HRESULT WINAPI StorageImpl_CopyTo( break; } + if ( snbExclude ) + { + WCHAR **snb = snbExclude; + skip = FALSE; + while ( *snb != NULL && !skip ) + { + if ( lstrcmpW(curElement.pwcsName, *snb) == 0 ) + skip = TRUE; + ++snb; + } + } + + if ( skip ) + goto cleanup; + if (curElement.type == STGTY_STORAGE) { + if(skip_storage) + goto cleanup; + /* * open child source storage */ @@ -1624,18 +1679,7 @@ static HRESULT WINAPI StorageImpl_CopyTo( NULL, 0, &pstgChild ); if (hr != S_OK) - break; - - /* - * Check if destination storage is not a child of the source - * storage, which will cause an infinite loop - */ - if (pstgChild == pstgDest) - { - IEnumSTATSTG_Release(elements); - - return STG_E_ACCESSDENIED; - } + goto cleanup; /* * create a new storage in destination storage @@ -1654,21 +1698,24 @@ static HRESULT WINAPI StorageImpl_CopyTo( NULL, 0, &pstgTmp ); } - if (hr != S_OK) - break; + if (hr == S_OK) + { + /* + * do the copy recursively + */ + hr = IStorage_CopyTo( pstgChild, ciidExclude, rgiidExclude, + NULL, pstgTmp ); + IStorage_Release( pstgTmp ); + } - /* - * do the copy recursively - */ - hr = IStorage_CopyTo( pstgChild, ciidExclude, rgiidExclude, - snbExclude, pstgTmp ); - - IStorage_Release( pstgTmp ); IStorage_Release( pstgChild ); } else if (curElement.type == STGTY_STREAM) { + if(skip_stream) + goto cleanup; + /* * create a new stream in destination storage. If the stream already * exist, it will be deleted and a new one will be created. @@ -1678,7 +1725,7 @@ static HRESULT WINAPI StorageImpl_CopyTo( 0, 0, &pstrTmp ); if (hr != S_OK) - break; + goto cleanup; /* * open child stream storage @@ -1687,33 +1734,36 @@ static HRESULT WINAPI StorageImpl_CopyTo( STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &pstrChild ); - if (hr != S_OK) - break; + if (hr == S_OK) + { + /* + * Get the size of the source stream + */ + IStream_Stat( pstrChild, &strStat, STATFLAG_NONAME ); - /* - * Get the size of the source stream - */ - IStream_Stat( pstrChild, &strStat, STATFLAG_NONAME ); + /* + * Set the size of the destination stream. + */ + IStream_SetSize(pstrTmp, strStat.cbSize); - /* - * Set the size of the destination stream. - */ - IStream_SetSize(pstrTmp, strStat.cbSize); + /* + * do the copy + */ + hr = IStream_CopyTo( pstrChild, pstrTmp, strStat.cbSize, + NULL, NULL ); - /* - * do the copy - */ - hr = IStream_CopyTo( pstrChild, pstrTmp, strStat.cbSize, - NULL, NULL ); + IStream_Release( pstrChild ); + } IStream_Release( pstrTmp ); - IStream_Release( pstrChild ); } else { WARN("unknown element type: %d\n", curElement.type); } +cleanup: + CoTaskMemFree(curElement.pwcsName); } while (hr == S_OK); /* @@ -1727,7 +1777,7 @@ static HRESULT WINAPI StorageImpl_CopyTo( /************************************************************************* * MoveElementTo (IStorage) */ -static HRESULT WINAPI StorageImpl_MoveElementTo( +static HRESULT WINAPI StorageBaseImpl_MoveElementTo( IStorage* iface, const OLECHAR *pwcsName, /* [string][in] */ IStorage *pstgDest, /* [unique][in] */ @@ -1766,8 +1816,8 @@ static HRESULT WINAPI StorageImpl_Commit( static HRESULT WINAPI StorageImpl_Revert( IStorage* iface) { - FIXME("(%p): stub\n", iface); - return E_NOTIMPL; + TRACE("(%p)\n", iface); + return S_OK; } /************************************************************************* @@ -1781,157 +1831,76 @@ static HRESULT WINAPI StorageImpl_Revert( * enumeration strategy that would give all the leaves of a storage * first. (postfix order) */ -static HRESULT WINAPI StorageImpl_DestroyElement( +static HRESULT WINAPI StorageBaseImpl_DestroyElement( IStorage* iface, const OLECHAR *pwcsName)/* [string][in] */ { - StorageImpl* const This=(StorageImpl*)iface; + StorageBaseImpl* const This=(StorageBaseImpl*)iface; - IEnumSTATSTGImpl* propertyEnumeration; HRESULT hr = S_OK; - BOOL res; - StgProperty propertyToDelete; - StgProperty parentProperty; - ULONG foundPropertyIndexToDelete; - ULONG typeOfRelation; - ULONG parentPropertyId = 0; + DirEntry entryToDelete; + DirRef entryToDeleteRef; TRACE("(%p, %s)\n", iface, debugstr_w(pwcsName)); - /* - * Perform a sanity check on the parameters. - */ if (pwcsName==NULL) return STG_E_INVALIDPOINTER; - if ( STGM_ACCESS_MODE( This->base.openFlags ) == STGM_READ ) + if (This->reverted) + return STG_E_REVERTED; + + if ( !(This->openFlags & STGM_TRANSACTED) && + STGM_ACCESS_MODE( This->openFlags ) == STGM_READ ) return STG_E_ACCESSDENIED; - /* - * Create a property enumeration to search the property with the given name - */ - propertyEnumeration = IEnumSTATSTGImpl_Construct( - This->base.ancestorStorage, - This->base.rootPropertySetIndex); - - foundPropertyIndexToDelete = IEnumSTATSTGImpl_FindProperty( - propertyEnumeration, + entryToDeleteRef = findElement( + This, + This->storageDirEntry, pwcsName, - &propertyToDelete); + &entryToDelete); - IEnumSTATSTGImpl_Destroy(propertyEnumeration); - - if ( foundPropertyIndexToDelete == PROPERTY_NULL ) + if ( entryToDeleteRef == DIRENTRY_NULL ) { return STG_E_FILENOTFOUND; } - /* - * Find the parent property of the property to delete (the one that - * link to it). If This->dirProperty == foundPropertyIndexToDelete, - * the parent is This. Otherwise, the parent is one of its sibling... - */ - - /* - * First, read This's StgProperty.. - */ - res = StorageImpl_ReadProperty( - This->base.ancestorStorage, - This->base.rootPropertySetIndex, - &parentProperty); - - assert(res); - - /* - * Second, check to see if by any chance the actual storage (This) is not - * the parent of the property to delete... We never know... - */ - if ( parentProperty.dirProperty == foundPropertyIndexToDelete ) + if ( entryToDelete.stgType == STGTY_STORAGE ) { - /* - * Set data as it would have been done in the else part... - */ - typeOfRelation = PROPERTY_RELATION_DIR; - parentPropertyId = This->base.rootPropertySetIndex; - } - else - { - /* - * Create a property enumeration to search the parent properties, and - * delete it once done. - */ - IEnumSTATSTGImpl* propertyEnumeration2; - - propertyEnumeration2 = IEnumSTATSTGImpl_Construct( - This->base.ancestorStorage, - This->base.rootPropertySetIndex); - - typeOfRelation = IEnumSTATSTGImpl_FindParentProperty( - propertyEnumeration2, - foundPropertyIndexToDelete, - &parentProperty, - &parentPropertyId); - - IEnumSTATSTGImpl_Destroy(propertyEnumeration2); - } - - if ( propertyToDelete.propertyType == PROPTYPE_STORAGE ) - { - hr = deleteStorageProperty( + hr = deleteStorageContents( This, - foundPropertyIndexToDelete, - propertyToDelete); + entryToDeleteRef, + entryToDelete); } - else if ( propertyToDelete.propertyType == PROPTYPE_STREAM ) + else if ( entryToDelete.stgType == STGTY_STREAM ) { - hr = deleteStreamProperty( + hr = deleteStreamContents( This, - foundPropertyIndexToDelete, - propertyToDelete); + entryToDeleteRef, + entryToDelete); } if (hr!=S_OK) return hr; /* - * Adjust the property chain + * Remove the entry from its parent storage */ - hr = adjustPropertyChain( + hr = removeFromTree( This, - propertyToDelete, - parentProperty, - parentPropertyId, - typeOfRelation); + This->storageDirEntry, + entryToDeleteRef); + + /* + * Invalidate the entry + */ + if (SUCCEEDED(hr)) + StorageBaseImpl_DestroyDirEntry(This, entryToDeleteRef); return hr; } -/************************************************************************ - * StorageImpl_Stat (IStorage) - * - * This method will retrieve information about this storage object. - * - * See Windows documentation for more details on IStorage methods. - */ -static HRESULT WINAPI StorageImpl_Stat( IStorage* iface, - STATSTG* pstatstg, /* [out] */ - DWORD grfStatFlag) /* [in] */ -{ - StorageImpl* const This = (StorageImpl*)iface; - HRESULT result = StorageBaseImpl_Stat( iface, pstatstg, grfStatFlag ); - - if ( SUCCEEDED(result) && ((grfStatFlag & STATFLAG_NONAME) == 0) && This->pwcsName ) - { - CoTaskMemFree(pstatstg->pwcsName); - pstatstg->pwcsName = CoTaskMemAlloc((lstrlenW(This->pwcsName)+1)*sizeof(WCHAR)); - strcpyW(pstatstg->pwcsName, This->pwcsName); - } - - return result; -} - /****************************************************************************** * Internal stream list handlers */ @@ -1948,17 +1917,60 @@ void StorageBaseImpl_RemoveStream(StorageBaseImpl * stg, StgStreamImpl * strm) list_remove(&(strm->StrmListEntry)); } +static BOOL StorageBaseImpl_IsStreamOpen(StorageBaseImpl * stg, DirRef streamEntry) +{ + StgStreamImpl *strm; + + LIST_FOR_EACH_ENTRY(strm, &stg->strmHead, StgStreamImpl, StrmListEntry) + { + if (strm->dirEntry == streamEntry) + { + return TRUE; + } + } + + return FALSE; +} + +static BOOL StorageBaseImpl_IsStorageOpen(StorageBaseImpl * stg, DirRef storageEntry) +{ + StorageInternalImpl *childstg; + + LIST_FOR_EACH_ENTRY(childstg, &stg->storageHead, StorageInternalImpl, ParentListEntry) + { + if (childstg->base.storageDirEntry == storageEntry) + { + return TRUE; + } + } + + return FALSE; +} + static void StorageBaseImpl_DeleteAll(StorageBaseImpl * stg) { struct list *cur, *cur2; StgStreamImpl *strm=NULL; + StorageInternalImpl *childstg=NULL; LIST_FOR_EACH_SAFE(cur, cur2, &stg->strmHead) { strm = LIST_ENTRY(cur,StgStreamImpl,StrmListEntry); - TRACE("Streams deleted (stg=%p strm=%p next=%p prev=%p)\n", stg,strm,cur->next,cur->prev); + TRACE("Streams invalidated (stg=%p strm=%p next=%p prev=%p)\n", stg,strm,cur->next,cur->prev); strm->parentStorage = NULL; list_remove(cur); } + + LIST_FOR_EACH_SAFE(cur, cur2, &stg->storageHead) { + childstg = LIST_ENTRY(cur,StorageInternalImpl,ParentListEntry); + StorageBaseImpl_Invalidate( &childstg->base ); + } + + if (stg->transactedChild) + { + StorageBaseImpl_Invalidate(stg->transactedChild); + + stg->transactedChild = NULL; + } } @@ -1966,26 +1978,36 @@ static void StorageBaseImpl_DeleteAll(StorageBaseImpl * stg) * * Internal Method * - * Perform the deletion of a complete storage node + * Delete the contents of a storage entry. * */ -static HRESULT deleteStorageProperty( - StorageImpl *parentStorage, - ULONG indexOfPropertyToDelete, - StgProperty propertyToDelete) +static HRESULT deleteStorageContents( + StorageBaseImpl *parentStorage, + DirRef indexToDelete, + DirEntry entryDataToDelete) { IEnumSTATSTG *elements = 0; IStorage *childStorage = 0; STATSTG currentElement; HRESULT hr; HRESULT destroyHr = S_OK; + StorageInternalImpl *stg, *stg2; + + /* Invalidate any open storage objects. */ + LIST_FOR_EACH_ENTRY_SAFE(stg, stg2, &parentStorage->storageHead, StorageInternalImpl, ParentListEntry) + { + if (stg->base.storageDirEntry == indexToDelete) + { + StorageBaseImpl_Invalidate(&stg->base); + } + } /* * Open the storage and enumerate it */ hr = StorageBaseImpl_OpenStorage( (IStorage*)parentStorage, - propertyToDelete.name, + entryDataToDelete.name, 0, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, @@ -2010,7 +2032,7 @@ static HRESULT deleteStorageProperty( hr = IEnumSTATSTG_Next(elements, 1, ¤tElement, NULL); if (hr==S_OK) { - destroyHr = StorageImpl_DestroyElement(childStorage, currentElement.pwcsName); + destroyHr = IStorage_DestroyElement(childStorage, currentElement.pwcsName); CoTaskMemFree(currentElement.pwcsName); } @@ -2023,15 +2045,6 @@ static HRESULT deleteStorageProperty( } while ((hr == S_OK) && (destroyHr == S_OK)); - /* - * Invalidate the property by zeroing its name member. - */ - propertyToDelete.sizeOfNameString = 0; - - StorageImpl_WriteProperty(parentStorage->base.ancestorStorage, - indexOfPropertyToDelete, - &propertyToDelete); - IStorage_Release(childStorage); IEnumSTATSTG_Release(elements); @@ -2042,23 +2055,35 @@ static HRESULT deleteStorageProperty( * * Internal Method * - * Perform the deletion of a stream node + * Perform the deletion of a stream's data * */ -static HRESULT deleteStreamProperty( - StorageImpl *parentStorage, - ULONG indexOfPropertyToDelete, - StgProperty propertyToDelete) +static HRESULT deleteStreamContents( + StorageBaseImpl *parentStorage, + DirRef indexToDelete, + DirEntry entryDataToDelete) { IStream *pis; HRESULT hr; ULARGE_INTEGER size; + StgStreamImpl *strm, *strm2; + + /* Invalidate any open stream objects. */ + LIST_FOR_EACH_ENTRY_SAFE(strm, strm2, &parentStorage->strmHead, StgStreamImpl, StrmListEntry) + { + if (strm->dirEntry == indexToDelete) + { + TRACE("Stream deleted %p\n", strm); + strm->parentStorage = NULL; + list_remove(&strm->StrmListEntry); + } + } size.u.HighPart = 0; size.u.LowPart = 0; hr = StorageBaseImpl_OpenStream((IStorage*)parentStorage, - propertyToDelete.name, NULL, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, &pis); + entryDataToDelete.name, NULL, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, &pis); if (hr!=S_OK) { @@ -2080,260 +2105,127 @@ static HRESULT deleteStreamProperty( */ IStream_Release(pis); - /* - * Invalidate the property by zeroing its name member. - */ - propertyToDelete.sizeOfNameString = 0; - - /* - * Here we should re-read the property so we get the updated pointer - * but since we are here to zap it, I don't do it... - */ - StorageImpl_WriteProperty( - parentStorage->base.ancestorStorage, - indexOfPropertyToDelete, - &propertyToDelete); - return S_OK; } -/********************************************************************* - * - * Internal Method - * - * Finds a placeholder for the StgProperty within the Storage - * - */ -static HRESULT findPlaceholder( - StorageImpl *storage, - ULONG propertyIndexToStore, - ULONG storePropertyIndex, - INT typeOfRelation) +static void setEntryLink(DirEntry *entry, ULONG relation, DirRef new_target) { - StgProperty storeProperty; - BOOL res = TRUE; - - /* - * Read the storage property - */ - res = StorageImpl_ReadProperty( - storage->base.ancestorStorage, - storePropertyIndex, - &storeProperty); - - if(! res) + switch (relation) { - return E_FAIL; + case DIRENTRY_RELATION_PREVIOUS: + entry->leftChild = new_target; + break; + case DIRENTRY_RELATION_NEXT: + entry->rightChild = new_target; + break; + case DIRENTRY_RELATION_DIR: + entry->dirRootEntry = new_target; + break; + default: + assert(0); } - - if (typeOfRelation == PROPERTY_RELATION_PREVIOUS) - { - if (storeProperty.previousProperty != PROPERTY_NULL) - { - return findPlaceholder( - storage, - propertyIndexToStore, - storeProperty.previousProperty, - typeOfRelation); - } - else - { - storeProperty.previousProperty = propertyIndexToStore; - } - } - else if (typeOfRelation == PROPERTY_RELATION_NEXT) - { - if (storeProperty.nextProperty != PROPERTY_NULL) - { - return findPlaceholder( - storage, - propertyIndexToStore, - storeProperty.nextProperty, - typeOfRelation); - } - else - { - storeProperty.nextProperty = propertyIndexToStore; - } - } - else if (typeOfRelation == PROPERTY_RELATION_DIR) - { - if (storeProperty.dirProperty != PROPERTY_NULL) - { - return findPlaceholder( - storage, - propertyIndexToStore, - storeProperty.dirProperty, - typeOfRelation); - } - else - { - storeProperty.dirProperty = propertyIndexToStore; - } - } - - res = StorageImpl_WriteProperty( - storage->base.ancestorStorage, - storePropertyIndex, - &storeProperty); - - if(!res) - { - return E_FAIL; - } - - return S_OK; } /************************************************************************* * * Internal Method * - * This method takes the previous and the next property link of a property - * to be deleted and find them a place in the Storage. + * This method removes a directory entry from its parent storage tree without + * freeing any resources attached to it. */ -static HRESULT adjustPropertyChain( - StorageImpl *This, - StgProperty propertyToDelete, - StgProperty parentProperty, - ULONG parentPropertyId, - INT typeOfRelation) +static HRESULT removeFromTree( + StorageBaseImpl *This, + DirRef parentStorageIndex, + DirRef deletedIndex) { - ULONG newLinkProperty = PROPERTY_NULL; - BOOL needToFindAPlaceholder = FALSE; - ULONG storeNode = PROPERTY_NULL; - ULONG toStoreNode = PROPERTY_NULL; - INT relationType = 0; HRESULT hr = S_OK; - BOOL res = TRUE; + DirEntry entryToDelete; + DirEntry parentEntry; + DirRef parentEntryRef; + ULONG typeOfRelation; - if (typeOfRelation == PROPERTY_RELATION_PREVIOUS) - { - if (propertyToDelete.previousProperty != PROPERTY_NULL) - { - /* - * Set the parent previous to the property to delete previous - */ - newLinkProperty = propertyToDelete.previousProperty; + hr = StorageBaseImpl_ReadDirEntry(This, deletedIndex, &entryToDelete); - if (propertyToDelete.nextProperty != PROPERTY_NULL) - { - /* - * We also need to find a storage for the other link, setup variables - * to do this at the end... - */ - needToFindAPlaceholder = TRUE; - storeNode = propertyToDelete.previousProperty; - toStoreNode = propertyToDelete.nextProperty; - relationType = PROPERTY_RELATION_NEXT; - } - } - else if (propertyToDelete.nextProperty != PROPERTY_NULL) - { - /* - * Set the parent previous to the property to delete next - */ - newLinkProperty = propertyToDelete.nextProperty; - } - - /* - * Link it for real... - */ - parentProperty.previousProperty = newLinkProperty; - - } - else if (typeOfRelation == PROPERTY_RELATION_NEXT) - { - if (propertyToDelete.previousProperty != PROPERTY_NULL) - { - /* - * Set the parent next to the property to delete next previous - */ - newLinkProperty = propertyToDelete.previousProperty; - - if (propertyToDelete.nextProperty != PROPERTY_NULL) - { - /* - * We also need to find a storage for the other link, setup variables - * to do this at the end... - */ - needToFindAPlaceholder = TRUE; - storeNode = propertyToDelete.previousProperty; - toStoreNode = propertyToDelete.nextProperty; - relationType = PROPERTY_RELATION_NEXT; - } - } - else if (propertyToDelete.nextProperty != PROPERTY_NULL) - { - /* - * Set the parent next to the property to delete next - */ - newLinkProperty = propertyToDelete.nextProperty; - } - - /* - * Link it for real... - */ - parentProperty.nextProperty = newLinkProperty; - } - else /* (typeOfRelation == PROPERTY_RELATION_DIR) */ - { - if (propertyToDelete.previousProperty != PROPERTY_NULL) - { - /* - * Set the parent dir to the property to delete previous - */ - newLinkProperty = propertyToDelete.previousProperty; - - if (propertyToDelete.nextProperty != PROPERTY_NULL) - { - /* - * We also need to find a storage for the other link, setup variables - * to do this at the end... - */ - needToFindAPlaceholder = TRUE; - storeNode = propertyToDelete.previousProperty; - toStoreNode = propertyToDelete.nextProperty; - relationType = PROPERTY_RELATION_NEXT; - } - } - else if (propertyToDelete.nextProperty != PROPERTY_NULL) - { - /* - * Set the parent dir to the property to delete next - */ - newLinkProperty = propertyToDelete.nextProperty; - } - - /* - * Link it for real... - */ - parentProperty.dirProperty = newLinkProperty; - } + if (hr != S_OK) + return hr; /* - * Write back the parent property + * Find the element that links to the one we want to delete. */ - res = StorageImpl_WriteProperty( - This->base.ancestorStorage, - parentPropertyId, - &parentProperty); - if(! res) - { - return E_FAIL; - } + hr = findTreeParent(This, parentStorageIndex, entryToDelete.name, + &parentEntry, &parentEntryRef, &typeOfRelation); - /* - * If a placeholder is required for the other link, then, find one and - * get out of here... - */ - if (needToFindAPlaceholder) + if (hr != S_OK) + return hr; + + if (entryToDelete.leftChild != DIRENTRY_NULL) { - hr = findPlaceholder( - This, - toStoreNode, - storeNode, - relationType); + /* + * Replace the deleted entry with its left child + */ + setEntryLink(&parentEntry, typeOfRelation, entryToDelete.leftChild); + + hr = StorageBaseImpl_WriteDirEntry( + This, + parentEntryRef, + &parentEntry); + if(FAILED(hr)) + { + return hr; + } + + if (entryToDelete.rightChild != DIRENTRY_NULL) + { + /* + * We need to reinsert the right child somewhere. We already know it and + * its children are greater than everything in the left tree, so we + * insert it at the rightmost point in the left tree. + */ + DirRef newRightChildParent = entryToDelete.leftChild; + DirEntry newRightChildParentEntry; + + do + { + hr = StorageBaseImpl_ReadDirEntry( + This, + newRightChildParent, + &newRightChildParentEntry); + if (FAILED(hr)) + { + return hr; + } + + if (newRightChildParentEntry.rightChild != DIRENTRY_NULL) + newRightChildParent = newRightChildParentEntry.rightChild; + } while (newRightChildParentEntry.rightChild != DIRENTRY_NULL); + + newRightChildParentEntry.rightChild = entryToDelete.rightChild; + + hr = StorageBaseImpl_WriteDirEntry( + This, + newRightChildParent, + &newRightChildParentEntry); + if (FAILED(hr)) + { + return hr; + } + } + } + else + { + /* + * Replace the deleted entry with its right child + */ + setEntryLink(&parentEntry, typeOfRelation, entryToDelete.rightChild); + + hr = StorageBaseImpl_WriteDirEntry( + This, + parentEntryRef, + &parentEntry); + if(FAILED(hr)) + { + return hr; + } } return hr; @@ -2343,7 +2235,7 @@ static HRESULT adjustPropertyChain( /****************************************************************************** * SetElementTimes (IStorage) */ -static HRESULT WINAPI StorageImpl_SetElementTimes( +static HRESULT WINAPI StorageBaseImpl_SetElementTimes( IStorage* iface, const OLECHAR *pwcsName,/* [string][in] */ const FILETIME *pctime, /* [in] */ @@ -2357,16 +2249,282 @@ static HRESULT WINAPI StorageImpl_SetElementTimes( /****************************************************************************** * SetStateBits (IStorage) */ -static HRESULT WINAPI StorageImpl_SetStateBits( +static HRESULT WINAPI StorageBaseImpl_SetStateBits( IStorage* iface, DWORD grfStateBits,/* [in] */ DWORD grfMask) /* [in] */ { - StorageImpl* const This = (StorageImpl*)iface; - This->base.stateBits = (This->base.stateBits & ~grfMask) | (grfStateBits & grfMask); + StorageBaseImpl* const This = (StorageBaseImpl*)iface; + + if (This->reverted) + return STG_E_REVERTED; + + This->stateBits = (This->stateBits & ~grfMask) | (grfStateBits & grfMask); return S_OK; } +static HRESULT StorageImpl_BaseWriteDirEntry(StorageBaseImpl *base, + DirRef index, const DirEntry *data) +{ + StorageImpl *This = (StorageImpl*)base; + return StorageImpl_WriteDirEntry(This, index, data); +} + +static HRESULT StorageImpl_BaseReadDirEntry(StorageBaseImpl *base, + DirRef index, DirEntry *data) +{ + StorageImpl *This = (StorageImpl*)base; + return StorageImpl_ReadDirEntry(This, index, data); +} + +static BlockChainStream **StorageImpl_GetFreeBlockChainCacheEntry(StorageImpl* This) +{ + int i; + + for (i=0; iblockChainCache[i]) + { + return &This->blockChainCache[i]; + } + } + + i = This->blockChainToEvict; + + BlockChainStream_Destroy(This->blockChainCache[i]); + This->blockChainCache[i] = NULL; + + This->blockChainToEvict++; + if (This->blockChainToEvict == BLOCKCHAIN_CACHE_SIZE) + This->blockChainToEvict = 0; + + return &This->blockChainCache[i]; +} + +static BlockChainStream **StorageImpl_GetCachedBlockChainStream(StorageImpl *This, + DirRef index) +{ + int i, free_index=-1; + + for (i=0; iblockChainCache[i]) + { + if (free_index == -1) free_index = i; + } + else if (This->blockChainCache[i]->ownerDirEntry == index) + { + return &This->blockChainCache[i]; + } + } + + if (free_index == -1) + { + free_index = This->blockChainToEvict; + + BlockChainStream_Destroy(This->blockChainCache[free_index]); + This->blockChainCache[free_index] = NULL; + + This->blockChainToEvict++; + if (This->blockChainToEvict == BLOCKCHAIN_CACHE_SIZE) + This->blockChainToEvict = 0; + } + + This->blockChainCache[free_index] = BlockChainStream_Construct(This, NULL, index); + return &This->blockChainCache[free_index]; +} + +static HRESULT StorageImpl_StreamReadAt(StorageBaseImpl *base, DirRef index, + ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) +{ + StorageImpl *This = (StorageImpl*)base; + DirEntry data; + HRESULT hr; + ULONG bytesToRead; + + hr = StorageImpl_ReadDirEntry(This, index, &data); + if (FAILED(hr)) return hr; + + if (data.size.QuadPart == 0) + { + *bytesRead = 0; + return S_OK; + } + + if (offset.QuadPart + size > data.size.QuadPart) + { + bytesToRead = data.size.QuadPart - offset.QuadPart; + } + else + { + bytesToRead = size; + } + + if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + SmallBlockChainStream *stream; + + stream = SmallBlockChainStream_Construct(This, NULL, index); + if (!stream) return E_OUTOFMEMORY; + + hr = SmallBlockChainStream_ReadAt(stream, offset, bytesToRead, buffer, bytesRead); + + SmallBlockChainStream_Destroy(stream); + + return hr; + } + else + { + BlockChainStream *stream = NULL; + + stream = *StorageImpl_GetCachedBlockChainStream(This, index); + if (!stream) return E_OUTOFMEMORY; + + hr = BlockChainStream_ReadAt(stream, offset, bytesToRead, buffer, bytesRead); + + return hr; + } +} + +static HRESULT StorageImpl_StreamSetSize(StorageBaseImpl *base, DirRef index, + ULARGE_INTEGER newsize) +{ + StorageImpl *This = (StorageImpl*)base; + DirEntry data; + HRESULT hr; + SmallBlockChainStream *smallblock=NULL; + BlockChainStream **pbigblock=NULL, *bigblock=NULL; + + hr = StorageImpl_ReadDirEntry(This, index, &data); + if (FAILED(hr)) return hr; + + /* In simple mode keep the stream size above the small block limit */ + if (This->base.openFlags & STGM_SIMPLE) + newsize.QuadPart = max(newsize.QuadPart, LIMIT_TO_USE_SMALL_BLOCK); + + if (data.size.QuadPart == newsize.QuadPart) + return S_OK; + + /* Create a block chain object of the appropriate type */ + if (data.size.QuadPart == 0) + { + if (newsize.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + smallblock = SmallBlockChainStream_Construct(This, NULL, index); + if (!smallblock) return E_OUTOFMEMORY; + } + else + { + pbigblock = StorageImpl_GetCachedBlockChainStream(This, index); + bigblock = *pbigblock; + if (!bigblock) return E_OUTOFMEMORY; + } + } + else if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + smallblock = SmallBlockChainStream_Construct(This, NULL, index); + if (!smallblock) return E_OUTOFMEMORY; + } + else + { + pbigblock = StorageImpl_GetCachedBlockChainStream(This, index); + bigblock = *pbigblock; + if (!bigblock) return E_OUTOFMEMORY; + } + + /* Change the block chain type if necessary. */ + if (smallblock && newsize.QuadPart >= LIMIT_TO_USE_SMALL_BLOCK) + { + bigblock = Storage32Impl_SmallBlocksToBigBlocks(This, &smallblock); + if (!bigblock) + { + SmallBlockChainStream_Destroy(smallblock); + return E_FAIL; + } + + pbigblock = StorageImpl_GetFreeBlockChainCacheEntry(This); + *pbigblock = bigblock; + } + else if (bigblock && newsize.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + smallblock = Storage32Impl_BigBlocksToSmallBlocks(This, pbigblock); + if (!smallblock) + return E_FAIL; + } + + /* Set the size of the block chain. */ + if (smallblock) + { + SmallBlockChainStream_SetSize(smallblock, newsize); + SmallBlockChainStream_Destroy(smallblock); + } + else + { + BlockChainStream_SetSize(bigblock, newsize); + } + + /* Set the size in the directory entry. */ + hr = StorageImpl_ReadDirEntry(This, index, &data); + if (SUCCEEDED(hr)) + { + data.size = newsize; + + hr = StorageImpl_WriteDirEntry(This, index, &data); + } + return hr; +} + +static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index, + ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) +{ + StorageImpl *This = (StorageImpl*)base; + DirEntry data; + HRESULT hr; + ULARGE_INTEGER newSize; + + hr = StorageImpl_ReadDirEntry(This, index, &data); + if (FAILED(hr)) return hr; + + /* Grow the stream if necessary */ + newSize.QuadPart = 0; + newSize.QuadPart = offset.QuadPart + size; + + if (newSize.QuadPart > data.size.QuadPart) + { + hr = StorageImpl_StreamSetSize(base, index, newSize); + if (FAILED(hr)) + return hr; + + hr = StorageImpl_ReadDirEntry(This, index, &data); + if (FAILED(hr)) return hr; + } + + if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + SmallBlockChainStream *stream; + + stream = SmallBlockChainStream_Construct(This, NULL, index); + if (!stream) return E_OUTOFMEMORY; + + hr = SmallBlockChainStream_WriteAt(stream, offset, size, buffer, bytesWritten); + + SmallBlockChainStream_Destroy(stream); + + return hr; + } + else + { + BlockChainStream *stream; + + stream = *StorageImpl_GetCachedBlockChainStream(This, index); + if (!stream) return E_OUTOFMEMORY; + + hr = BlockChainStream_WriteAt(stream, offset, size, buffer, bytesWritten); + + return hr; + } +} + /* * Virtual function table for the IStorage32Impl class. */ @@ -2377,62 +2535,87 @@ static const IStorageVtbl Storage32Impl_Vtbl = StorageBaseImpl_Release, StorageBaseImpl_CreateStream, StorageBaseImpl_OpenStream, - StorageImpl_CreateStorage, + StorageBaseImpl_CreateStorage, StorageBaseImpl_OpenStorage, - StorageImpl_CopyTo, - StorageImpl_MoveElementTo, + StorageBaseImpl_CopyTo, + StorageBaseImpl_MoveElementTo, StorageImpl_Commit, StorageImpl_Revert, StorageBaseImpl_EnumElements, - StorageImpl_DestroyElement, + StorageBaseImpl_DestroyElement, StorageBaseImpl_RenameElement, - StorageImpl_SetElementTimes, + StorageBaseImpl_SetElementTimes, StorageBaseImpl_SetClass, - StorageImpl_SetStateBits, - StorageImpl_Stat + StorageBaseImpl_SetStateBits, + StorageBaseImpl_Stat +}; + +static const StorageBaseImplVtbl StorageImpl_BaseVtbl = +{ + StorageImpl_Destroy, + StorageImpl_Invalidate, + StorageImpl_CreateDirEntry, + StorageImpl_BaseWriteDirEntry, + StorageImpl_BaseReadDirEntry, + StorageImpl_DestroyDirEntry, + StorageImpl_StreamReadAt, + StorageImpl_StreamWriteAt, + StorageImpl_StreamSetSize }; static HRESULT StorageImpl_Construct( - StorageImpl* This, HANDLE hFile, LPCOLESTR pwcsName, ILockBytes* pLkbyt, DWORD openFlags, BOOL fileBased, - BOOL create) + BOOL create, + StorageImpl** result) { + StorageImpl* This; HRESULT hr = S_OK; - StgProperty currentProperty; - BOOL readSuccessful; - ULONG currentPropertyIndex; + DirEntry currentEntry; + DirRef currentEntryRef; + WCHAR fullpath[MAX_PATH]; if ( FAILED( validateSTGM(openFlags) )) return STG_E_INVALIDFLAG; + This = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl)); + if (!This) + return E_OUTOFMEMORY; + memset(This, 0, sizeof(StorageImpl)); list_init(&This->base.strmHead); + list_init(&This->base.storageHead); + This->base.lpVtbl = &Storage32Impl_Vtbl; This->base.pssVtbl = &IPropertySetStorage_Vtbl; - This->base.v_destructor = StorageImpl_Destroy; + This->base.baseVtbl = &StorageImpl_BaseVtbl; This->base.openFlags = (openFlags & ~STGM_CREATE); - This->create = create; + This->base.ref = 1; + This->base.create = create; - /* - * This is the top-level storage so initialize the ancestor pointer - * to this. - */ - This->base.ancestorStorage = This; + This->base.reverted = 0; This->hFile = hFile; if(pwcsName) { + if (!GetFullPathNameW(pwcsName, MAX_PATH, fullpath, NULL)) + { + lstrcpynW(fullpath, pwcsName, MAX_PATH); + } This->pwcsName = HeapAlloc(GetProcessHeap(), 0, - (lstrlenW(pwcsName)+1)*sizeof(WCHAR)); + (lstrlenW(fullpath)+1)*sizeof(WCHAR)); if (!This->pwcsName) - return STG_E_INSUFFICIENTMEMORY; - strcpyW(This->pwcsName, pwcsName); + { + hr = STG_E_INSUFFICIENTMEMORY; + goto end; + } + strcpyW(This->pwcsName, fullpath); + This->base.filename = This->pwcsName; } /* @@ -2447,7 +2630,10 @@ static HRESULT StorageImpl_Construct( fileBased); if (This->bigBlockFile == 0) - return E_FAIL; + { + hr = E_FAIL; + goto end; + } if (create) { @@ -2457,7 +2643,7 @@ static HRESULT StorageImpl_Construct( /* * Initialize all header variables: * - The big block depot consists of one block and it is at block 0 - * - The properties start at block 1 + * - The directory table starts at block 1 * - There is no small block depot */ memset( This->bigBlockDepotStart, @@ -2476,7 +2662,7 @@ static HRESULT StorageImpl_Construct( StorageImpl_SaveFileHeader(This); /* - * Add one block for the big block depot and one block for the properties + * Add one block for the big block depot and one block for the directory table */ size.u.HighPart = 0; size.u.LowPart = This->bigBlockSize * 3; @@ -2499,9 +2685,7 @@ static HRESULT StorageImpl_Construct( if (FAILED(hr)) { - BIGBLOCKFILE_Destructor(This->bigBlockFile); - - return hr; + goto end; } } @@ -2519,85 +2703,112 @@ static HRESULT StorageImpl_Construct( * Create the block chain abstractions. */ if(!(This->rootBlockChain = - BlockChainStream_Construct(This, &This->rootStartBlock, PROPERTY_NULL))) - return STG_E_READFAULT; + BlockChainStream_Construct(This, &This->rootStartBlock, DIRENTRY_NULL))) + { + hr = STG_E_READFAULT; + goto end; + } if(!(This->smallBlockDepotChain = BlockChainStream_Construct(This, &This->smallBlockDepotStart, - PROPERTY_NULL))) - return STG_E_READFAULT; - - /* - * Write the root property (memory only) - */ - if (create) + DIRENTRY_NULL))) { - StgProperty rootProp; - /* - * Initialize the property chain - */ - memset(&rootProp, 0, sizeof(rootProp)); - MultiByteToWideChar( CP_ACP, 0, rootPropertyName, -1, rootProp.name, - sizeof(rootProp.name)/sizeof(WCHAR) ); - rootProp.sizeOfNameString = (strlenW(rootProp.name)+1) * sizeof(WCHAR); - rootProp.propertyType = PROPTYPE_ROOT; - rootProp.previousProperty = PROPERTY_NULL; - rootProp.nextProperty = PROPERTY_NULL; - rootProp.dirProperty = PROPERTY_NULL; - rootProp.startingBlock = BLOCK_END_OF_CHAIN; - rootProp.size.u.HighPart = 0; - rootProp.size.u.LowPart = 0; - - StorageImpl_WriteProperty(This, 0, &rootProp); + hr = STG_E_READFAULT; + goto end; } /* - * Find the ID of the root in the property sets. + * Write the root storage entry (memory only) */ - currentPropertyIndex = 0; + if (create) + { + DirEntry rootEntry; + /* + * Initialize the directory table + */ + memset(&rootEntry, 0, sizeof(rootEntry)); + MultiByteToWideChar( CP_ACP, 0, rootEntryName, -1, rootEntry.name, + sizeof(rootEntry.name)/sizeof(WCHAR) ); + rootEntry.sizeOfNameString = (strlenW(rootEntry.name)+1) * sizeof(WCHAR); + rootEntry.stgType = STGTY_ROOT; + rootEntry.leftChild = DIRENTRY_NULL; + rootEntry.rightChild = DIRENTRY_NULL; + rootEntry.dirRootEntry = DIRENTRY_NULL; + rootEntry.startingBlock = BLOCK_END_OF_CHAIN; + rootEntry.size.u.HighPart = 0; + rootEntry.size.u.LowPart = 0; + + StorageImpl_WriteDirEntry(This, 0, &rootEntry); + } + + /* + * Find the ID of the root storage. + */ + currentEntryRef = 0; do { - readSuccessful = StorageImpl_ReadProperty( + hr = StorageImpl_ReadDirEntry( This, - currentPropertyIndex, - ¤tProperty); + currentEntryRef, + ¤tEntry); - if (readSuccessful) + if (SUCCEEDED(hr)) { - if ( (currentProperty.sizeOfNameString != 0 ) && - (currentProperty.propertyType == PROPTYPE_ROOT) ) + if ( (currentEntry.sizeOfNameString != 0 ) && + (currentEntry.stgType == STGTY_ROOT) ) { - This->base.rootPropertySetIndex = currentPropertyIndex; + This->base.storageDirEntry = currentEntryRef; } } - currentPropertyIndex++; + currentEntryRef++; - } while (readSuccessful && (This->base.rootPropertySetIndex == PROPERTY_NULL) ); + } while (SUCCEEDED(hr) && (This->base.storageDirEntry == DIRENTRY_NULL) ); - if (!readSuccessful) + if (FAILED(hr)) { - /* TODO CLEANUP */ - return STG_E_READFAULT; + hr = STG_E_READFAULT; + goto end; } /* * Create the block chain abstraction for the small block root chain. */ if(!(This->smallBlockRootChain = - BlockChainStream_Construct(This, NULL, This->base.rootPropertySetIndex))) - return STG_E_READFAULT; + BlockChainStream_Construct(This, NULL, This->base.storageDirEntry))) + { + hr = STG_E_READFAULT; + } + +end: + if (FAILED(hr)) + { + IStorage_Release((IStorage*)This); + *result = NULL; + } + else + *result = This; return hr; } +static void StorageImpl_Invalidate(StorageBaseImpl* iface) +{ + StorageImpl *This = (StorageImpl*) iface; + + StorageBaseImpl_DeleteAll(&This->base); + + This->base.reverted = 1; +} + static void StorageImpl_Destroy(StorageBaseImpl* iface) { StorageImpl *This = (StorageImpl*) iface; + int i; TRACE("(%p)\n", This); - StorageBaseImpl_DeleteAll(&This->base); + StorageImpl_Invalidate(iface); HeapFree(GetProcessHeap(), 0, This->pwcsName); @@ -2605,7 +2816,11 @@ static void StorageImpl_Destroy(StorageBaseImpl* iface) BlockChainStream_Destroy(This->rootBlockChain); BlockChainStream_Destroy(This->smallBlockDepotChain); - BIGBLOCKFILE_Destructor(This->bigBlockFile); + for (i=0; iblockChainCache[i]); + + if (This->bigBlockFile) + BIGBLOCKFILE_Destructor(This->bigBlockFile); HeapFree(GetProcessHeap(), 0, This); } @@ -3258,192 +3473,233 @@ static void StorageImpl_SaveFileHeader( } /****************************************************************************** - * Storage32Impl_ReadProperty + * StorageImpl_ReadRawDirEntry * - * This method will read the specified property from the property chain. + * This method will read the raw data from a directory entry in the file. + * + * buffer must be RAW_DIRENTRY_SIZE bytes long. */ -BOOL StorageImpl_ReadProperty( - StorageImpl* This, - ULONG index, - StgProperty* buffer) +HRESULT StorageImpl_ReadRawDirEntry(StorageImpl *This, ULONG index, BYTE *buffer) { - BYTE currentProperty[PROPSET_BLOCK_SIZE]; - ULARGE_INTEGER offsetInPropSet; - HRESULT readRes; - ULONG bytesRead; + ULARGE_INTEGER offset; + HRESULT hr; + ULONG bytesRead; - offsetInPropSet.u.HighPart = 0; - offsetInPropSet.u.LowPart = index * PROPSET_BLOCK_SIZE; + offset.u.HighPart = 0; + offset.u.LowPart = index * RAW_DIRENTRY_SIZE; - readRes = BlockChainStream_ReadAt( + hr = BlockChainStream_ReadAt( This->rootBlockChain, - offsetInPropSet, - PROPSET_BLOCK_SIZE, - currentProperty, + offset, + RAW_DIRENTRY_SIZE, + buffer, &bytesRead); + return hr; +} + +/****************************************************************************** + * StorageImpl_WriteRawDirEntry + * + * This method will write the raw data from a directory entry in the file. + * + * buffer must be RAW_DIRENTRY_SIZE bytes long. + */ +HRESULT StorageImpl_WriteRawDirEntry(StorageImpl *This, ULONG index, const BYTE *buffer) +{ + ULARGE_INTEGER offset; + HRESULT hr; + ULONG bytesRead; + + offset.u.HighPart = 0; + offset.u.LowPart = index * RAW_DIRENTRY_SIZE; + + hr = BlockChainStream_WriteAt( + This->rootBlockChain, + offset, + RAW_DIRENTRY_SIZE, + buffer, + &bytesRead); + + return hr; +} + +/****************************************************************************** + * UpdateRawDirEntry + * + * Update raw directory entry data from the fields in newData. + * + * buffer must be RAW_DIRENTRY_SIZE bytes long. + */ +void UpdateRawDirEntry(BYTE *buffer, const DirEntry *newData) +{ + memset(buffer, 0, RAW_DIRENTRY_SIZE); + + memcpy( + buffer + OFFSET_PS_NAME, + newData->name, + DIRENTRY_NAME_BUFFER_LEN ); + + memcpy(buffer + OFFSET_PS_STGTYPE, &newData->stgType, 1); + + StorageUtl_WriteWord( + buffer, + OFFSET_PS_NAMELENGTH, + newData->sizeOfNameString); + + StorageUtl_WriteDWord( + buffer, + OFFSET_PS_LEFTCHILD, + newData->leftChild); + + StorageUtl_WriteDWord( + buffer, + OFFSET_PS_RIGHTCHILD, + newData->rightChild); + + StorageUtl_WriteDWord( + buffer, + OFFSET_PS_DIRROOT, + newData->dirRootEntry); + + StorageUtl_WriteGUID( + buffer, + OFFSET_PS_GUID, + &newData->clsid); + + StorageUtl_WriteDWord( + buffer, + OFFSET_PS_CTIMELOW, + newData->ctime.dwLowDateTime); + + StorageUtl_WriteDWord( + buffer, + OFFSET_PS_CTIMEHIGH, + newData->ctime.dwHighDateTime); + + StorageUtl_WriteDWord( + buffer, + OFFSET_PS_MTIMELOW, + newData->mtime.dwLowDateTime); + + StorageUtl_WriteDWord( + buffer, + OFFSET_PS_MTIMEHIGH, + newData->ctime.dwHighDateTime); + + StorageUtl_WriteDWord( + buffer, + OFFSET_PS_STARTBLOCK, + newData->startingBlock); + + StorageUtl_WriteDWord( + buffer, + OFFSET_PS_SIZE, + newData->size.u.LowPart); +} + +/****************************************************************************** + * Storage32Impl_ReadDirEntry + * + * This method will read the specified directory entry. + */ +HRESULT StorageImpl_ReadDirEntry( + StorageImpl* This, + DirRef index, + DirEntry* buffer) +{ + BYTE currentEntry[RAW_DIRENTRY_SIZE]; + HRESULT readRes; + + readRes = StorageImpl_ReadRawDirEntry(This, index, currentEntry); + if (SUCCEEDED(readRes)) { - /* replace the name of root entry (often "Root Entry") by the file name */ - WCHAR *propName = (index == This->base.rootPropertySetIndex) ? - This->filename : (WCHAR *)currentProperty+OFFSET_PS_NAME; - memset(buffer->name, 0, sizeof(buffer->name)); memcpy( buffer->name, - propName, - PROPERTY_NAME_BUFFER_LEN ); + (WCHAR *)currentEntry+OFFSET_PS_NAME, + DIRENTRY_NAME_BUFFER_LEN ); TRACE("storage name: %s\n", debugstr_w(buffer->name)); - memcpy(&buffer->propertyType, currentProperty + OFFSET_PS_PROPERTYTYPE, 1); + memcpy(&buffer->stgType, currentEntry + OFFSET_PS_STGTYPE, 1); StorageUtl_ReadWord( - currentProperty, + currentEntry, OFFSET_PS_NAMELENGTH, &buffer->sizeOfNameString); StorageUtl_ReadDWord( - currentProperty, - OFFSET_PS_PREVIOUSPROP, - &buffer->previousProperty); + currentEntry, + OFFSET_PS_LEFTCHILD, + &buffer->leftChild); StorageUtl_ReadDWord( - currentProperty, - OFFSET_PS_NEXTPROP, - &buffer->nextProperty); + currentEntry, + OFFSET_PS_RIGHTCHILD, + &buffer->rightChild); StorageUtl_ReadDWord( - currentProperty, - OFFSET_PS_DIRPROP, - &buffer->dirProperty); + currentEntry, + OFFSET_PS_DIRROOT, + &buffer->dirRootEntry); StorageUtl_ReadGUID( - currentProperty, + currentEntry, OFFSET_PS_GUID, - &buffer->propertyUniqueID); + &buffer->clsid); StorageUtl_ReadDWord( - currentProperty, - OFFSET_PS_TSS1, - &buffer->timeStampS1); + currentEntry, + OFFSET_PS_CTIMELOW, + &buffer->ctime.dwLowDateTime); StorageUtl_ReadDWord( - currentProperty, - OFFSET_PS_TSD1, - &buffer->timeStampD1); + currentEntry, + OFFSET_PS_CTIMEHIGH, + &buffer->ctime.dwHighDateTime); StorageUtl_ReadDWord( - currentProperty, - OFFSET_PS_TSS2, - &buffer->timeStampS2); + currentEntry, + OFFSET_PS_MTIMELOW, + &buffer->mtime.dwLowDateTime); StorageUtl_ReadDWord( - currentProperty, - OFFSET_PS_TSD2, - &buffer->timeStampD2); + currentEntry, + OFFSET_PS_MTIMEHIGH, + &buffer->mtime.dwHighDateTime); StorageUtl_ReadDWord( - currentProperty, + currentEntry, OFFSET_PS_STARTBLOCK, &buffer->startingBlock); StorageUtl_ReadDWord( - currentProperty, + currentEntry, OFFSET_PS_SIZE, &buffer->size.u.LowPart); buffer->size.u.HighPart = 0; } - return SUCCEEDED(readRes) ? TRUE : FALSE; + return readRes; } /********************************************************************* - * Write the specified property into the property chain + * Write the specified directory entry to the file */ -BOOL StorageImpl_WriteProperty( +HRESULT StorageImpl_WriteDirEntry( StorageImpl* This, - ULONG index, - const StgProperty* buffer) + DirRef index, + const DirEntry* buffer) { - BYTE currentProperty[PROPSET_BLOCK_SIZE]; - ULARGE_INTEGER offsetInPropSet; + BYTE currentEntry[RAW_DIRENTRY_SIZE]; HRESULT writeRes; - ULONG bytesWritten; - offsetInPropSet.u.HighPart = 0; - offsetInPropSet.u.LowPart = index * PROPSET_BLOCK_SIZE; + UpdateRawDirEntry(currentEntry, buffer); - memset(currentProperty, 0, PROPSET_BLOCK_SIZE); - - memcpy( - currentProperty + OFFSET_PS_NAME, - buffer->name, - PROPERTY_NAME_BUFFER_LEN ); - - memcpy(currentProperty + OFFSET_PS_PROPERTYTYPE, &buffer->propertyType, 1); - - StorageUtl_WriteWord( - currentProperty, - OFFSET_PS_NAMELENGTH, - buffer->sizeOfNameString); - - StorageUtl_WriteDWord( - currentProperty, - OFFSET_PS_PREVIOUSPROP, - buffer->previousProperty); - - StorageUtl_WriteDWord( - currentProperty, - OFFSET_PS_NEXTPROP, - buffer->nextProperty); - - StorageUtl_WriteDWord( - currentProperty, - OFFSET_PS_DIRPROP, - buffer->dirProperty); - - StorageUtl_WriteGUID( - currentProperty, - OFFSET_PS_GUID, - &buffer->propertyUniqueID); - - StorageUtl_WriteDWord( - currentProperty, - OFFSET_PS_TSS1, - buffer->timeStampS1); - - StorageUtl_WriteDWord( - currentProperty, - OFFSET_PS_TSD1, - buffer->timeStampD1); - - StorageUtl_WriteDWord( - currentProperty, - OFFSET_PS_TSS2, - buffer->timeStampS2); - - StorageUtl_WriteDWord( - currentProperty, - OFFSET_PS_TSD2, - buffer->timeStampD2); - - StorageUtl_WriteDWord( - currentProperty, - OFFSET_PS_STARTBLOCK, - buffer->startingBlock); - - StorageUtl_WriteDWord( - currentProperty, - OFFSET_PS_SIZE, - buffer->size.u.LowPart); - - writeRes = BlockChainStream_WriteAt(This->rootBlockChain, - offsetInPropSet, - PROPSET_BLOCK_SIZE, - currentProperty, - &bytesWritten); - return SUCCEEDED(writeRes) ? TRUE : FALSE; + writeRes = StorageImpl_WriteRawDirEntry(This, index, currentEntry); + return writeRes; } static BOOL StorageImpl_ReadBigBlock( @@ -3527,22 +3783,22 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks( ULARGE_INTEGER size, offset; ULONG cbRead, cbWritten; ULARGE_INTEGER cbTotalRead; - ULONG propertyIndex; + DirRef streamEntryRef; HRESULT resWrite = S_OK; HRESULT resRead; - StgProperty chainProperty; + DirEntry streamEntry; BYTE *buffer; BlockChainStream *bbTempChain = NULL; BlockChainStream *bigBlockChain = NULL; /* * Create a temporary big block chain that doesn't have - * an associated property. This temporary chain will be + * an associated directory entry. This temporary chain will be * used to copy data from small blocks to big blocks. */ bbTempChain = BlockChainStream_Construct(This, &bbHeadOfChain, - PROPERTY_NULL); + DIRENTRY_NULL); if(!bbTempChain) return NULL; /* * Grow the big block chain. @@ -3601,29 +3857,29 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks( /* * Destroy the small block chain. */ - propertyIndex = (*ppsbChain)->ownerPropertyIndex; + streamEntryRef = (*ppsbChain)->ownerDirEntry; SmallBlockChainStream_SetSize(*ppsbChain, size); SmallBlockChainStream_Destroy(*ppsbChain); *ppsbChain = 0; /* - * Change the property information. This chain is now a big block chain + * Change the directory entry. This chain is now a big block chain * and it doesn't reside in the small blocks chain anymore. */ - StorageImpl_ReadProperty(This, propertyIndex, &chainProperty); + StorageImpl_ReadDirEntry(This, streamEntryRef, &streamEntry); - chainProperty.startingBlock = bbHeadOfChain; + streamEntry.startingBlock = bbHeadOfChain; - StorageImpl_WriteProperty(This, propertyIndex, &chainProperty); + StorageImpl_WriteDirEntry(This, streamEntryRef, &streamEntry); /* - * Destroy the temporary propertyless big block chain. - * Create a new big block chain associated with this property. + * Destroy the temporary entryless big block chain. + * Create a new big block chain associated with this entry. */ BlockChainStream_Destroy(bbTempChain); bigBlockChain = BlockChainStream_Construct(This, NULL, - propertyIndex); + streamEntryRef); return bigBlockChain; } @@ -3639,16 +3895,17 @@ SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks( BlockChainStream** ppbbChain) { ULARGE_INTEGER size, offset, cbTotalRead; - ULONG cbRead, cbWritten, propertyIndex, sbHeadOfChain = BLOCK_END_OF_CHAIN; + ULONG cbRead, cbWritten, sbHeadOfChain = BLOCK_END_OF_CHAIN; + DirRef streamEntryRef; HRESULT resWrite = S_OK, resRead; - StgProperty chainProperty; + DirEntry streamEntry; BYTE* buffer; SmallBlockChainStream* sbTempChain; TRACE("%p %p\n", This, ppbbChain); sbTempChain = SmallBlockChainStream_Construct(This, &sbHeadOfChain, - PROPERTY_NULL); + DIRENTRY_NULL); if(!sbTempChain) return NULL; @@ -3696,38 +3953,491 @@ SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks( } /* destroy the original big block chain */ - propertyIndex = (*ppbbChain)->ownerPropertyIndex; + streamEntryRef = (*ppbbChain)->ownerDirEntry; BlockChainStream_SetSize(*ppbbChain, size); BlockChainStream_Destroy(*ppbbChain); *ppbbChain = NULL; - StorageImpl_ReadProperty(This, propertyIndex, &chainProperty); - chainProperty.startingBlock = sbHeadOfChain; - StorageImpl_WriteProperty(This, propertyIndex, &chainProperty); + StorageImpl_ReadDirEntry(This, streamEntryRef, &streamEntry); + streamEntry.startingBlock = sbHeadOfChain; + StorageImpl_WriteDirEntry(This, streamEntryRef, &streamEntry); SmallBlockChainStream_Destroy(sbTempChain); - return SmallBlockChainStream_Construct(This, NULL, propertyIndex); + return SmallBlockChainStream_Construct(This, NULL, streamEntryRef); +} + +static HRESULT CreateSnapshotFile(StorageBaseImpl* original, StorageBaseImpl **snapshot) +{ + HRESULT hr; + DirEntry parentData, snapshotData; + + hr = StgCreateDocfile(NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_DELETEONRELEASE, + 0, (IStorage**)snapshot); + + if (SUCCEEDED(hr)) + { + hr = StorageBaseImpl_ReadDirEntry(original, + original->storageDirEntry, &parentData); + + if (SUCCEEDED(hr)) + hr = StorageBaseImpl_ReadDirEntry((*snapshot), + (*snapshot)->storageDirEntry, &snapshotData); + + if (SUCCEEDED(hr)) + { + memcpy(snapshotData.name, parentData.name, sizeof(snapshotData.name)); + snapshotData.sizeOfNameString = parentData.sizeOfNameString; + snapshotData.stgType = parentData.stgType; + snapshotData.clsid = parentData.clsid; + snapshotData.ctime = parentData.ctime; + snapshotData.mtime = parentData.mtime; + hr = StorageBaseImpl_WriteDirEntry((*snapshot), + (*snapshot)->storageDirEntry, &snapshotData); + } + + if (SUCCEEDED(hr)) + hr = IStorage_CopyTo((IStorage*)original, 0, NULL, NULL, + (IStorage*)(*snapshot)); + + if (FAILED(hr)) IStorage_Release((IStorage*)(*snapshot)); + } + + return hr; +} + +static HRESULT WINAPI TransactedSnapshotImpl_Commit( + IStorage* iface, + DWORD grfCommitFlags) /* [in] */ +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) iface; + HRESULT hr; + DirEntry data, tempStorageData, snapshotRootData; + DirRef tempStorageEntry, oldDirRoot; + StorageInternalImpl *tempStorage; + + TRACE("(%p,%x)\n", iface, grfCommitFlags); + + /* Cannot commit a read-only transacted storage */ + if ( STGM_ACCESS_MODE( This->base.openFlags ) == STGM_READ ) + return STG_E_ACCESSDENIED; + + /* To prevent data loss, we create the new structure in the file before we + * delete the old one, so that in case of errors the old data is intact. We + * shouldn't do this if STGC_OVERWRITE is set, but that flag should only be + * needed in the rare situation where we have just enough free disk space to + * overwrite the existing data. */ + + /* Create an orphaned storage in the parent for the new directory structure. */ + memset(&data, 0, sizeof(data)); + data.name[0] = 'D'; + data.sizeOfNameString = 1; + data.stgType = STGTY_STORAGE; + data.leftChild = DIRENTRY_NULL; + data.rightChild = DIRENTRY_NULL; + data.dirRootEntry = DIRENTRY_NULL; + hr = StorageBaseImpl_CreateDirEntry(This->transactedParent, &data, &tempStorageEntry); + + if (FAILED(hr)) return hr; + + tempStorage = StorageInternalImpl_Construct(This->transactedParent, + STGM_READWRITE|STGM_SHARE_EXCLUSIVE, tempStorageEntry); + if (tempStorage) + { + hr = IStorage_CopyTo((IStorage*)This->snapshot, 0, NULL, NULL, + (IStorage*)tempStorage); + + list_init(&tempStorage->ParentListEntry); + + IStorage_Release((IStorage*) tempStorage); + } + else + hr = E_OUTOFMEMORY; + + if (FAILED(hr)) + { + DestroyReachableEntries(This->transactedParent, tempStorageEntry); + return hr; + } + + /* Update the storage to use the new data in one step. */ + hr = StorageBaseImpl_ReadDirEntry(This->transactedParent, + This->transactedParent->storageDirEntry, &data); + + if (SUCCEEDED(hr)) + { + hr = StorageBaseImpl_ReadDirEntry(This->transactedParent, + tempStorageEntry, &tempStorageData); + } + + if (SUCCEEDED(hr)) + { + hr = StorageBaseImpl_ReadDirEntry(This->snapshot, + This->snapshot->storageDirEntry, &snapshotRootData); + } + + if (SUCCEEDED(hr)) + { + oldDirRoot = data.dirRootEntry; + data.dirRootEntry = tempStorageData.dirRootEntry; + data.clsid = snapshotRootData.clsid; + data.ctime = snapshotRootData.ctime; + data.mtime = snapshotRootData.mtime; + + hr = StorageBaseImpl_WriteDirEntry(This->transactedParent, + This->transactedParent->storageDirEntry, &data); + } + + if (SUCCEEDED(hr)) + { + /* Destroy the old now-orphaned data. */ + DestroyReachableEntries(This->transactedParent, oldDirRoot); + StorageBaseImpl_DestroyDirEntry(This->transactedParent, tempStorageEntry); + } + else + { + DestroyReachableEntries(This->transactedParent, tempStorageEntry); + } + + return hr; +} + +static HRESULT WINAPI TransactedSnapshotImpl_Revert( + IStorage* iface) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) iface; + StorageBaseImpl *newSnapshot; + HRESULT hr; + + TRACE("(%p)\n", iface); + + /* Create a new copy of the parent data. */ + hr = CreateSnapshotFile(This->transactedParent, &newSnapshot); + if (FAILED(hr)) return hr; + + /* Destroy the open objects. */ + StorageBaseImpl_DeleteAll(&This->base); + + /* Replace our current snapshot. */ + IStorage_Release((IStorage*)This->snapshot); + This->snapshot = newSnapshot; + + return S_OK; +} + +static void TransactedSnapshotImpl_Invalidate(StorageBaseImpl* This) +{ + if (!This->reverted) + { + TRACE("Storage invalidated (stg=%p)\n", This); + + This->reverted = 1; + + StorageBaseImpl_DeleteAll(This); + } +} + +static void TransactedSnapshotImpl_Destroy( StorageBaseImpl *iface) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) iface; + + TransactedSnapshotImpl_Invalidate(iface); + + IStorage_Release((IStorage*)This->transactedParent); + + IStorage_Release((IStorage*)This->snapshot); + + HeapFree(GetProcessHeap(), 0, This); +} + +static HRESULT TransactedSnapshotImpl_CreateDirEntry(StorageBaseImpl *base, + const DirEntry *newData, DirRef *index) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_CreateDirEntry(This->snapshot, + newData, index); +} + +static HRESULT TransactedSnapshotImpl_WriteDirEntry(StorageBaseImpl *base, + DirRef index, const DirEntry *data) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_WriteDirEntry(This->snapshot, + index, data); +} + +static HRESULT TransactedSnapshotImpl_ReadDirEntry(StorageBaseImpl *base, + DirRef index, DirEntry *data) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_ReadDirEntry(This->snapshot, + index, data); +} + +static HRESULT TransactedSnapshotImpl_DestroyDirEntry(StorageBaseImpl *base, + DirRef index) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_DestroyDirEntry(This->snapshot, + index); +} + +static HRESULT TransactedSnapshotImpl_StreamReadAt(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_StreamReadAt(This->snapshot, + index, offset, size, buffer, bytesRead); +} + +static HRESULT TransactedSnapshotImpl_StreamWriteAt(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_StreamWriteAt(This->snapshot, + index, offset, size, buffer, bytesWritten); +} + +static HRESULT TransactedSnapshotImpl_StreamSetSize(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER newsize) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_StreamSetSize(This->snapshot, + index, newsize); +} + +static const IStorageVtbl TransactedSnapshotImpl_Vtbl = +{ + StorageBaseImpl_QueryInterface, + StorageBaseImpl_AddRef, + StorageBaseImpl_Release, + StorageBaseImpl_CreateStream, + StorageBaseImpl_OpenStream, + StorageBaseImpl_CreateStorage, + StorageBaseImpl_OpenStorage, + StorageBaseImpl_CopyTo, + StorageBaseImpl_MoveElementTo, + TransactedSnapshotImpl_Commit, + TransactedSnapshotImpl_Revert, + StorageBaseImpl_EnumElements, + StorageBaseImpl_DestroyElement, + StorageBaseImpl_RenameElement, + StorageBaseImpl_SetElementTimes, + StorageBaseImpl_SetClass, + StorageBaseImpl_SetStateBits, + StorageBaseImpl_Stat +}; + +static const StorageBaseImplVtbl TransactedSnapshotImpl_BaseVtbl = +{ + TransactedSnapshotImpl_Destroy, + TransactedSnapshotImpl_Invalidate, + TransactedSnapshotImpl_CreateDirEntry, + TransactedSnapshotImpl_WriteDirEntry, + TransactedSnapshotImpl_ReadDirEntry, + TransactedSnapshotImpl_DestroyDirEntry, + TransactedSnapshotImpl_StreamReadAt, + TransactedSnapshotImpl_StreamWriteAt, + TransactedSnapshotImpl_StreamSetSize +}; + +static HRESULT TransactedSnapshotImpl_Construct(StorageBaseImpl *parentStorage, + TransactedSnapshotImpl** result) +{ + HRESULT hr; + + *result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TransactedSnapshotImpl)); + if (*result) + { + (*result)->base.lpVtbl = &TransactedSnapshotImpl_Vtbl; + + /* This is OK because the property set storage functions use the IStorage functions. */ + (*result)->base.pssVtbl = parentStorage->pssVtbl; + + (*result)->base.baseVtbl = &TransactedSnapshotImpl_BaseVtbl; + + list_init(&(*result)->base.strmHead); + + list_init(&(*result)->base.storageHead); + + (*result)->base.ref = 1; + + (*result)->base.openFlags = parentStorage->openFlags; + + (*result)->base.filename = parentStorage->filename; + + /* Create a new temporary storage to act as the snapshot */ + hr = CreateSnapshotFile(parentStorage, &(*result)->snapshot); + + if (SUCCEEDED(hr)) + { + (*result)->base.storageDirEntry = (*result)->snapshot->storageDirEntry; + + /* parentStorage already has 1 reference, which we take over here. */ + (*result)->transactedParent = parentStorage; + + parentStorage->transactedChild = (StorageBaseImpl*)*result; + } + + if (FAILED(hr)) HeapFree(GetProcessHeap(), 0, (*result)); + + return hr; + } + else + return E_OUTOFMEMORY; +} + +static HRESULT Storage_ConstructTransacted(StorageBaseImpl *parentStorage, + StorageBaseImpl** result) +{ + static int fixme=0; + + if (parentStorage->openFlags & (STGM_NOSCRATCH|STGM_NOSNAPSHOT) && !fixme++) + { + FIXME("Unimplemented flags %x\n", parentStorage->openFlags); + } + + return TransactedSnapshotImpl_Construct(parentStorage, + (TransactedSnapshotImpl**)result); +} + +static HRESULT Storage_Construct( + HANDLE hFile, + LPCOLESTR pwcsName, + ILockBytes* pLkbyt, + DWORD openFlags, + BOOL fileBased, + BOOL create, + StorageBaseImpl** result) +{ + StorageImpl *newStorage; + StorageBaseImpl *newTransactedStorage; + HRESULT hr; + + hr = StorageImpl_Construct(hFile, pwcsName, pLkbyt, openFlags, fileBased, create, &newStorage); + if (FAILED(hr)) goto end; + + if (openFlags & STGM_TRANSACTED) + { + hr = Storage_ConstructTransacted(&newStorage->base, &newTransactedStorage); + if (FAILED(hr)) + IStorage_Release((IStorage*)newStorage); + else + *result = newTransactedStorage; + } + else + *result = &newStorage->base; + +end: + return hr; +} + +static void StorageInternalImpl_Invalidate( StorageBaseImpl *base ) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + if (!This->base.reverted) + { + TRACE("Storage invalidated (stg=%p)\n", This); + + This->base.reverted = 1; + + This->parentStorage = NULL; + + StorageBaseImpl_DeleteAll(&This->base); + + list_remove(&This->ParentListEntry); + } } static void StorageInternalImpl_Destroy( StorageBaseImpl *iface) { StorageInternalImpl* This = (StorageInternalImpl*) iface; - StorageBaseImpl_Release((IStorage*)This->base.ancestorStorage); + StorageInternalImpl_Invalidate(&This->base); + HeapFree(GetProcessHeap(), 0, This); } +static HRESULT StorageInternalImpl_CreateDirEntry(StorageBaseImpl *base, + const DirEntry *newData, DirRef *index) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_CreateDirEntry(This->parentStorage, + newData, index); +} + +static HRESULT StorageInternalImpl_WriteDirEntry(StorageBaseImpl *base, + DirRef index, const DirEntry *data) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_WriteDirEntry(This->parentStorage, + index, data); +} + +static HRESULT StorageInternalImpl_ReadDirEntry(StorageBaseImpl *base, + DirRef index, DirEntry *data) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_ReadDirEntry(This->parentStorage, + index, data); +} + +static HRESULT StorageInternalImpl_DestroyDirEntry(StorageBaseImpl *base, + DirRef index) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_DestroyDirEntry(This->parentStorage, + index); +} + +static HRESULT StorageInternalImpl_StreamReadAt(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_StreamReadAt(This->parentStorage, + index, offset, size, buffer, bytesRead); +} + +static HRESULT StorageInternalImpl_StreamWriteAt(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_StreamWriteAt(This->parentStorage, + index, offset, size, buffer, bytesWritten); +} + +static HRESULT StorageInternalImpl_StreamSetSize(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER newsize) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_StreamSetSize(This->parentStorage, + index, newsize); +} + /****************************************************************************** ** ** Storage32InternalImpl_Commit ** -** The non-root storages cannot be opened in transacted mode thus this function -** does nothing. */ static HRESULT WINAPI StorageInternalImpl_Commit( IStorage* iface, DWORD grfCommitFlags) /* [in] */ { + FIXME("(%p,%x): stub\n", iface, grfCommitFlags); return S_OK; } @@ -3735,19 +4445,17 @@ static HRESULT WINAPI StorageInternalImpl_Commit( ** ** Storage32InternalImpl_Revert ** -** The non-root storages cannot be opened in transacted mode thus this function -** does nothing. */ static HRESULT WINAPI StorageInternalImpl_Revert( IStorage* iface) { + FIXME("(%p): stub\n", iface); return S_OK; } static void IEnumSTATSTGImpl_Destroy(IEnumSTATSTGImpl* This) { IStorage_Release((IStorage*)This->parentStorage); - HeapFree(GetProcessHeap(), 0, This->stackToVisit); HeapFree(GetProcessHeap(), 0, This); } @@ -3758,20 +4466,11 @@ static HRESULT WINAPI IEnumSTATSTGImpl_QueryInterface( { IEnumSTATSTGImpl* const This=(IEnumSTATSTGImpl*)iface; - /* - * Perform a sanity check on the parameters. - */ if (ppvObject==0) return E_INVALIDARG; - /* - * Initialize the return parameter. - */ *ppvObject = 0; - /* - * Compare the riid with the interface IDs implemented by this object. - */ if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IEnumSTATSTG, riid)) { @@ -3799,9 +4498,6 @@ static ULONG WINAPI IEnumSTATSTGImpl_Release( newRef = InterlockedDecrement(&This->ref); - /* - * If the reference count goes down to 0, perform suicide. - */ if (newRef==0) { IEnumSTATSTGImpl_Destroy(This); @@ -3810,6 +4506,51 @@ static ULONG WINAPI IEnumSTATSTGImpl_Release( return newRef; } +static HRESULT IEnumSTATSTGImpl_GetNextRef( + IEnumSTATSTGImpl* This, + DirRef *ref) +{ + DirRef result = DIRENTRY_NULL; + DirRef searchNode; + DirEntry entry; + HRESULT hr; + WCHAR result_name[DIRENTRY_NAME_MAX_LEN]; + + hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, + This->parentStorage->storageDirEntry, &entry); + searchNode = entry.dirRootEntry; + + while (SUCCEEDED(hr) && searchNode != DIRENTRY_NULL) + { + hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, searchNode, &entry); + + if (SUCCEEDED(hr)) + { + LONG diff = entryNameCmp( entry.name, This->name); + + if (diff <= 0) + { + searchNode = entry.rightChild; + } + else + { + result = searchNode; + memcpy(result_name, entry.name, sizeof(result_name)); + searchNode = entry.leftChild; + } + } + } + + if (SUCCEEDED(hr)) + { + *ref = result; + if (result != DIRENTRY_NULL) + memcpy(This->name, result_name, sizeof(result_name)); + } + + return hr; +} + static HRESULT WINAPI IEnumSTATSTGImpl_Next( IEnumSTATSTG* iface, ULONG celt, @@ -3818,17 +4559,18 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Next( { IEnumSTATSTGImpl* const This=(IEnumSTATSTGImpl*)iface; - StgProperty currentProperty; + DirEntry currentEntry; STATSTG* currentReturnStruct = rgelt; ULONG objectFetched = 0; - ULONG currentSearchNode; + DirRef currentSearchNode; + HRESULT hr=S_OK; - /* - * Perform a sanity check on the parameters. - */ if ( (rgelt==0) || ( (celt!=1) && (pceltFetched==0) ) ) return E_INVALIDARG; + if (This->parentStorage->reverted) + return STG_E_REVERTED; + /* * To avoid the special case, get another pointer to a ULONG value if * the caller didn't supply one. @@ -3842,31 +4584,26 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Next( */ *pceltFetched = 0; - /* - * Start with the node at the top of the stack. - */ - currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); - - while ( ( *pceltFetched < celt) && - ( currentSearchNode!=PROPERTY_NULL) ) + while ( *pceltFetched < celt ) { - /* - * Remove the top node from the stack - */ - IEnumSTATSTGImpl_PopSearchNode(This, TRUE); + hr = IEnumSTATSTGImpl_GetNextRef(This, ¤tSearchNode); + + if (FAILED(hr) || currentSearchNode == DIRENTRY_NULL) + break; /* - * Read the property from the storage. + * Read the entry from the storage. */ - StorageImpl_ReadProperty(This->parentStorage, + StorageBaseImpl_ReadDirEntry(This->parentStorage, currentSearchNode, - ¤tProperty); + ¤tEntry); /* * Copy the information to the return buffer. */ - StorageUtl_CopyPropertyToSTATSTG(currentReturnStruct, - ¤tProperty, + StorageUtl_CopyDirEntryToSTATSTG(This->parentStorage, + currentReturnStruct, + ¤tEntry, STATFLAG_DEFAULT); /* @@ -3874,22 +4611,12 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Next( */ (*pceltFetched)++; currentReturnStruct++; - - /* - * Push the next search node in the search stack. - */ - IEnumSTATSTGImpl_PushSearchNode(This, currentProperty.nextProperty); - - /* - * continue the iteration. - */ - currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); } - if (*pceltFetched == celt) - return S_OK; + if (SUCCEEDED(hr) && *pceltFetched != celt) + hr = S_FALSE; - return S_FALSE; + return hr; } @@ -3899,50 +4626,27 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Skip( { IEnumSTATSTGImpl* const This=(IEnumSTATSTGImpl*)iface; - StgProperty currentProperty; ULONG objectFetched = 0; - ULONG currentSearchNode; + DirRef currentSearchNode; + HRESULT hr=S_OK; - /* - * Start with the node at the top of the stack. - */ - currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); + if (This->parentStorage->reverted) + return STG_E_REVERTED; - while ( (objectFetched < celt) && - (currentSearchNode!=PROPERTY_NULL) ) + while ( (objectFetched < celt) ) { - /* - * Remove the top node from the stack - */ - IEnumSTATSTGImpl_PopSearchNode(This, TRUE); + hr = IEnumSTATSTGImpl_GetNextRef(This, ¤tSearchNode); - /* - * Read the property from the storage. - */ - StorageImpl_ReadProperty(This->parentStorage, - currentSearchNode, - ¤tProperty); + if (FAILED(hr) || currentSearchNode == DIRENTRY_NULL) + break; - /* - * Step to the next item in the iteration - */ objectFetched++; - - /* - * Push the next search node in the search stack. - */ - IEnumSTATSTGImpl_PushSearchNode(This, currentProperty.nextProperty); - - /* - * continue the iteration. - */ - currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); } - if (objectFetched == celt) - return S_OK; + if (SUCCEEDED(hr) && objectFetched != celt) + return S_FALSE; - return S_FALSE; + return hr; } static HRESULT WINAPI IEnumSTATSTGImpl_Reset( @@ -3950,31 +4654,10 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Reset( { IEnumSTATSTGImpl* const This=(IEnumSTATSTGImpl*)iface; - StgProperty rootProperty; - BOOL readSuccessful; + if (This->parentStorage->reverted) + return STG_E_REVERTED; - /* - * Re-initialize the search stack to an empty stack - */ - This->stackSize = 0; - - /* - * Read the root property from the storage. - */ - readSuccessful = StorageImpl_ReadProperty( - This->parentStorage, - This->firstPropertyNode, - &rootProperty); - - if (readSuccessful) - { - assert(rootProperty.sizeOfNameString!=0); - - /* - * Push the search node in the search stack. - */ - IEnumSTATSTGImpl_PushSearchNode(This, rootProperty.dirProperty); - } + This->name[0] = 0; return S_OK; } @@ -3987,6 +4670,9 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Clone( IEnumSTATSTGImpl* newClone; + if (This->parentStorage->reverted) + return STG_E_REVERTED; + /* * Perform a sanity check on the parameters. */ @@ -3994,22 +4680,14 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Clone( return E_INVALIDARG; newClone = IEnumSTATSTGImpl_Construct(This->parentStorage, - This->firstPropertyNode); + This->storageDirEntry); /* * The new clone enumeration must point to the same current node as * the ole one. */ - newClone->stackSize = This->stackSize ; - newClone->stackMaxSize = This->stackMaxSize ; - newClone->stackToVisit = - HeapAlloc(GetProcessHeap(), 0, sizeof(ULONG) * newClone->stackMaxSize); - - memcpy( - newClone->stackToVisit, - This->stackToVisit, - sizeof(ULONG) * newClone->stackSize); + memcpy(newClone->name, This->name, sizeof(newClone->name)); *ppenum = (IEnumSTATSTG*)newClone; @@ -4022,180 +4700,6 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Clone( return S_OK; } -static INT IEnumSTATSTGImpl_FindParentProperty( - IEnumSTATSTGImpl *This, - ULONG childProperty, - StgProperty *currentProperty, - ULONG *thisNodeId) -{ - ULONG currentSearchNode; - ULONG foundNode; - - /* - * To avoid the special case, get another pointer to a ULONG value if - * the caller didn't supply one. - */ - if (thisNodeId==0) - thisNodeId = &foundNode; - - /* - * Start with the node at the top of the stack. - */ - currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); - - - while (currentSearchNode!=PROPERTY_NULL) - { - /* - * Store the current node in the returned parameters - */ - *thisNodeId = currentSearchNode; - - /* - * Remove the top node from the stack - */ - IEnumSTATSTGImpl_PopSearchNode(This, TRUE); - - /* - * Read the property from the storage. - */ - StorageImpl_ReadProperty( - This->parentStorage, - currentSearchNode, - currentProperty); - - if (currentProperty->previousProperty == childProperty) - return PROPERTY_RELATION_PREVIOUS; - - else if (currentProperty->nextProperty == childProperty) - return PROPERTY_RELATION_NEXT; - - else if (currentProperty->dirProperty == childProperty) - return PROPERTY_RELATION_DIR; - - /* - * Push the next search node in the search stack. - */ - IEnumSTATSTGImpl_PushSearchNode(This, currentProperty->nextProperty); - - /* - * continue the iteration. - */ - currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); - } - - return PROPERTY_NULL; -} - -static ULONG IEnumSTATSTGImpl_FindProperty( - IEnumSTATSTGImpl* This, - const OLECHAR* lpszPropName, - StgProperty* currentProperty) -{ - ULONG currentSearchNode; - - /* - * Start with the node at the top of the stack. - */ - currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); - - while (currentSearchNode!=PROPERTY_NULL) - { - /* - * Remove the top node from the stack - */ - IEnumSTATSTGImpl_PopSearchNode(This, TRUE); - - /* - * Read the property from the storage. - */ - StorageImpl_ReadProperty(This->parentStorage, - currentSearchNode, - currentProperty); - - if (propertyNameCmp(currentProperty->name, lpszPropName) == 0) - return currentSearchNode; - - /* - * Push the next search node in the search stack. - */ - IEnumSTATSTGImpl_PushSearchNode(This, currentProperty->nextProperty); - - /* - * continue the iteration. - */ - currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); - } - - return PROPERTY_NULL; -} - -static void IEnumSTATSTGImpl_PushSearchNode( - IEnumSTATSTGImpl* This, - ULONG nodeToPush) -{ - StgProperty rootProperty; - BOOL readSuccessful; - - /* - * First, make sure we're not trying to push an unexisting node. - */ - if (nodeToPush==PROPERTY_NULL) - return; - - /* - * First push the node to the stack - */ - if (This->stackSize == This->stackMaxSize) - { - This->stackMaxSize += ENUMSTATSGT_SIZE_INCREMENT; - - This->stackToVisit = HeapReAlloc( - GetProcessHeap(), - 0, - This->stackToVisit, - sizeof(ULONG) * This->stackMaxSize); - } - - This->stackToVisit[This->stackSize] = nodeToPush; - This->stackSize++; - - /* - * Read the root property from the storage. - */ - readSuccessful = StorageImpl_ReadProperty( - This->parentStorage, - nodeToPush, - &rootProperty); - - if (readSuccessful) - { - assert(rootProperty.sizeOfNameString!=0); - - /* - * Push the previous search node in the search stack. - */ - IEnumSTATSTGImpl_PushSearchNode(This, rootProperty.previousProperty); - } -} - -static ULONG IEnumSTATSTGImpl_PopSearchNode( - IEnumSTATSTGImpl* This, - BOOL remove) -{ - ULONG topNode; - - if (This->stackSize == 0) - return PROPERTY_NULL; - - topNode = This->stackToVisit[This->stackSize-1]; - - if (remove) - This->stackSize--; - - return topNode; -} - /* * Virtual function table for the IEnumSTATSTGImpl class. */ @@ -4215,8 +4719,8 @@ static const IEnumSTATSTGVtbl IEnumSTATSTGImpl_Vtbl = */ static IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct( - StorageImpl* parentStorage, - ULONG firstPropertyNode) + StorageBaseImpl* parentStorage, + DirRef storageDirEntry) { IEnumSTATSTGImpl* newEnumeration; @@ -4237,15 +4741,7 @@ static IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct( newEnumeration->parentStorage = parentStorage; IStorage_AddRef((IStorage*)newEnumeration->parentStorage); - newEnumeration->firstPropertyNode = firstPropertyNode; - - /* - * Initialize the search stack - */ - newEnumeration->stackSize = 0; - newEnumeration->stackMaxSize = ENUMSTATSGT_SIZE_INCREMENT; - newEnumeration->stackToVisit = - HeapAlloc(GetProcessHeap(), 0, sizeof(ULONG)*ENUMSTATSGT_SIZE_INCREMENT); + newEnumeration->storageDirEntry = storageDirEntry; /* * Make sure the current node of the iterator is the first one. @@ -4266,61 +4762,72 @@ static const IStorageVtbl Storage32InternalImpl_Vtbl = StorageBaseImpl_Release, StorageBaseImpl_CreateStream, StorageBaseImpl_OpenStream, - StorageImpl_CreateStorage, + StorageBaseImpl_CreateStorage, StorageBaseImpl_OpenStorage, - StorageImpl_CopyTo, - StorageImpl_MoveElementTo, + StorageBaseImpl_CopyTo, + StorageBaseImpl_MoveElementTo, StorageInternalImpl_Commit, StorageInternalImpl_Revert, StorageBaseImpl_EnumElements, - StorageImpl_DestroyElement, + StorageBaseImpl_DestroyElement, StorageBaseImpl_RenameElement, - StorageImpl_SetElementTimes, + StorageBaseImpl_SetElementTimes, StorageBaseImpl_SetClass, - StorageImpl_SetStateBits, + StorageBaseImpl_SetStateBits, StorageBaseImpl_Stat }; +static const StorageBaseImplVtbl StorageInternalImpl_BaseVtbl = +{ + StorageInternalImpl_Destroy, + StorageInternalImpl_Invalidate, + StorageInternalImpl_CreateDirEntry, + StorageInternalImpl_WriteDirEntry, + StorageInternalImpl_ReadDirEntry, + StorageInternalImpl_DestroyDirEntry, + StorageInternalImpl_StreamReadAt, + StorageInternalImpl_StreamWriteAt, + StorageInternalImpl_StreamSetSize +}; + /****************************************************************************** ** Storage32InternalImpl implementation */ static StorageInternalImpl* StorageInternalImpl_Construct( - StorageImpl* ancestorStorage, + StorageBaseImpl* parentStorage, DWORD openFlags, - ULONG rootPropertyIndex) + DirRef storageDirEntry) { StorageInternalImpl* newStorage; - /* - * Allocate space for the new storage object - */ newStorage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(StorageInternalImpl)); if (newStorage!=0) { - /* - * Initialize the stream list - */ list_init(&newStorage->base.strmHead); + list_init(&newStorage->base.storageHead); + /* * Initialize the virtual function table. */ newStorage->base.lpVtbl = &Storage32InternalImpl_Vtbl; - newStorage->base.v_destructor = StorageInternalImpl_Destroy; + newStorage->base.baseVtbl = &StorageInternalImpl_BaseVtbl; newStorage->base.openFlags = (openFlags & ~STGM_CREATE); - /* - * Keep the ancestor storage pointer and nail a reference to it. - */ - newStorage->base.ancestorStorage = ancestorStorage; - StorageBaseImpl_AddRef((IStorage*)(newStorage->base.ancestorStorage)); + newStorage->base.reverted = 0; + + newStorage->base.ref = 1; + + newStorage->parentStorage = parentStorage; /* - * Keep the index of the root property set for this storage, + * Keep a reference to the directory entry of this storage */ - newStorage->base.rootPropertySetIndex = rootPropertyIndex; + newStorage->base.storageDirEntry = storageDirEntry; + + newStorage->base.create = 0; return newStorage; } @@ -4406,35 +4913,48 @@ void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value) memcpy(buffer+offset+8, value->Data4, sizeof(value->Data4)); } -void StorageUtl_CopyPropertyToSTATSTG( +void StorageUtl_CopyDirEntryToSTATSTG( + StorageBaseImpl* storage, STATSTG* destination, - const StgProperty* source, + const DirEntry* source, int statFlags) { + LPCWSTR entryName; + + if (source->stgType == STGTY_ROOT) + { + /* replace the name of root entry (often "Root Entry") by the file name */ + entryName = storage->filename; + } + else + { + entryName = source->name; + } + /* * The copy of the string occurs only when the flag is not set */ if( ((statFlags & STATFLAG_NONAME) != 0) || - (source->name == NULL) || - (source->name[0] == 0) ) + (entryName == NULL) || + (entryName[0] == 0) ) { destination->pwcsName = 0; } else { destination->pwcsName = - CoTaskMemAlloc((lstrlenW(source->name)+1)*sizeof(WCHAR)); + CoTaskMemAlloc((lstrlenW(entryName)+1)*sizeof(WCHAR)); - strcpyW(destination->pwcsName, source->name); + strcpyW(destination->pwcsName, entryName); } - switch (source->propertyType) + switch (source->stgType) { - case PROPTYPE_STORAGE: - case PROPTYPE_ROOT: + case STGTY_STORAGE: + case STGTY_ROOT: destination->type = STGTY_STORAGE; break; - case PROPTYPE_STREAM: + case STGTY_STREAM: destination->type = STGTY_STREAM; break; default: @@ -4450,7 +4970,7 @@ void StorageUtl_CopyPropertyToSTATSTG( */ destination->grfMode = 0; destination->grfLocksSupported = 0; - destination->clsid = source->propertyUniqueID; + destination->clsid = source->clsid; destination->grfStateBits = 0; destination->reserved = 0; } @@ -4462,7 +4982,7 @@ void StorageUtl_CopyPropertyToSTATSTG( BlockChainStream* BlockChainStream_Construct( StorageImpl* parentStorage, ULONG* headOfStreamPlaceHolder, - ULONG propertyIndex) + DirRef dirEntry) { BlockChainStream* newStream; ULONG blockIndex; @@ -4471,7 +4991,7 @@ BlockChainStream* BlockChainStream_Construct( newStream->parentStorage = parentStorage; newStream->headOfStreamPlaceHolder = headOfStreamPlaceHolder; - newStream->ownerPropertyIndex = propertyIndex; + newStream->ownerDirEntry = dirEntry; newStream->lastBlockNoInSequence = 0xFFFFFFFF; newStream->tailIndex = BLOCK_END_OF_CHAIN; newStream->numBlocks = 0; @@ -4505,28 +5025,28 @@ void BlockChainStream_Destroy(BlockChainStream* This) * BlockChainStream_GetHeadOfChain * * Returns the head of this stream chain. - * Some special chains don't have properties, their heads are kept in + * Some special chains don't have directory entries, their heads are kept in * This->headOfStreamPlaceHolder. * */ static ULONG BlockChainStream_GetHeadOfChain(BlockChainStream* This) { - StgProperty chainProperty; - BOOL readSuccessful; + DirEntry chainEntry; + HRESULT hr; if (This->headOfStreamPlaceHolder != 0) return *(This->headOfStreamPlaceHolder); - if (This->ownerPropertyIndex != PROPERTY_NULL) + if (This->ownerDirEntry != DIRENTRY_NULL) { - readSuccessful = StorageImpl_ReadProperty( + hr = StorageImpl_ReadDirEntry( This->parentStorage, - This->ownerPropertyIndex, - &chainProperty); + This->ownerDirEntry, + &chainEntry); - if (readSuccessful) + if (SUCCEEDED(hr)) { - return chainProperty.startingBlock; + return chainEntry.startingBlock; } } @@ -4853,20 +5373,20 @@ static BOOL BlockChainStream_Enlarge(BlockChainStream* This, } else { - StgProperty chainProp; - assert(This->ownerPropertyIndex != PROPERTY_NULL); + DirEntry chainEntry; + assert(This->ownerDirEntry != DIRENTRY_NULL); - StorageImpl_ReadProperty( + StorageImpl_ReadDirEntry( This->parentStorage, - This->ownerPropertyIndex, - &chainProp); + This->ownerDirEntry, + &chainEntry); - chainProp.startingBlock = blockIndex; + chainEntry.startingBlock = blockIndex; - StorageImpl_WriteProperty( + StorageImpl_WriteDirEntry( This->parentStorage, - This->ownerPropertyIndex, - &chainProp); + This->ownerDirEntry, + &chainEntry); } This->tailIndex = blockIndex; @@ -4969,29 +5489,28 @@ BOOL BlockChainStream_SetSize( * BlockChainStream_GetSize * * Returns the size of this chain. - * Will return the block count if this chain doesn't have a property. + * Will return the block count if this chain doesn't have a directory entry. */ static ULARGE_INTEGER BlockChainStream_GetSize(BlockChainStream* This) { - StgProperty chainProperty; + DirEntry chainEntry; if(This->headOfStreamPlaceHolder == NULL) { /* - * This chain is a data stream read the property and return - * the appropriate size + * This chain has a directory entry so use the size value from there. */ - StorageImpl_ReadProperty( + StorageImpl_ReadDirEntry( This->parentStorage, - This->ownerPropertyIndex, - &chainProperty); + This->ownerDirEntry, + &chainEntry); - return chainProperty.size; + return chainEntry.size; } else { /* - * this chain is a chain that does not have a property, figure out the + * this chain is a chain that does not have a directory entry, figure out the * size by making the product number of used blocks times the * size of them */ @@ -5013,7 +5532,7 @@ static ULARGE_INTEGER BlockChainStream_GetSize(BlockChainStream* This) SmallBlockChainStream* SmallBlockChainStream_Construct( StorageImpl* parentStorage, ULONG* headOfStreamPlaceHolder, - ULONG propertyIndex) + DirRef dirEntry) { SmallBlockChainStream* newStream; @@ -5021,7 +5540,7 @@ SmallBlockChainStream* SmallBlockChainStream_Construct( newStream->parentStorage = parentStorage; newStream->headOfStreamPlaceHolder = headOfStreamPlaceHolder; - newStream->ownerPropertyIndex = propertyIndex; + newStream->ownerDirEntry = dirEntry; return newStream; } @@ -5040,22 +5559,22 @@ void SmallBlockChainStream_Destroy( static ULONG SmallBlockChainStream_GetHeadOfChain( SmallBlockChainStream* This) { - StgProperty chainProperty; - BOOL readSuccessful; + DirEntry chainEntry; + HRESULT hr; if (This->headOfStreamPlaceHolder != NULL) return *(This->headOfStreamPlaceHolder); - if (This->ownerPropertyIndex) + if (This->ownerDirEntry) { - readSuccessful = StorageImpl_ReadProperty( + hr = StorageImpl_ReadDirEntry( This->parentStorage, - This->ownerPropertyIndex, - &chainProperty); + This->ownerDirEntry, + &chainEntry); - if (readSuccessful) + if (SUCCEEDED(hr)) { - return chainProperty.startingBlock; + return chainEntry.startingBlock; } } @@ -5234,7 +5753,7 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock( /* * We have just created the small block depot. */ - StgProperty rootProp; + DirEntry rootEntry; ULONG sbStartIndex; /* @@ -5254,19 +5773,19 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock( sbStartIndex, BLOCK_END_OF_CHAIN); - StorageImpl_ReadProperty( + StorageImpl_ReadDirEntry( This->parentStorage, - This->parentStorage->base.rootPropertySetIndex, - &rootProp); + This->parentStorage->base.storageDirEntry, + &rootEntry); - rootProp.startingBlock = sbStartIndex; - rootProp.size.u.HighPart = 0; - rootProp.size.u.LowPart = This->parentStorage->bigBlockSize; + rootEntry.startingBlock = sbStartIndex; + rootEntry.size.u.HighPart = 0; + rootEntry.size.u.LowPart = This->parentStorage->bigBlockSize; - StorageImpl_WriteProperty( + StorageImpl_WriteDirEntry( This->parentStorage, - This->parentStorage->base.rootPropertySetIndex, - &rootProp); + This->parentStorage->base.storageDirEntry, + &rootEntry); } else StorageImpl_SaveFileHeader(This->parentStorage); @@ -5281,27 +5800,27 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock( */ if (blockIndex % smallBlocksPerBigBlock == 0) { - StgProperty rootProp; + DirEntry rootEntry; ULONG blocksRequired = (blockIndex / smallBlocksPerBigBlock) + 1; - StorageImpl_ReadProperty( + StorageImpl_ReadDirEntry( This->parentStorage, - This->parentStorage->base.rootPropertySetIndex, - &rootProp); + This->parentStorage->base.storageDirEntry, + &rootEntry); - if (rootProp.size.u.LowPart < + if (rootEntry.size.u.LowPart < (blocksRequired * This->parentStorage->bigBlockSize)) { - rootProp.size.u.LowPart += This->parentStorage->bigBlockSize; + rootEntry.size.u.LowPart += This->parentStorage->bigBlockSize; BlockChainStream_SetSize( This->parentStorage->smallBlockRootChain, - rootProp.size); + rootEntry.size); - StorageImpl_WriteProperty( + StorageImpl_WriteDirEntry( This->parentStorage, - This->parentStorage->base.rootPropertySetIndex, - &rootProp); + This->parentStorage->base.storageDirEntry, + &rootEntry); } } @@ -5531,17 +6050,17 @@ static BOOL SmallBlockChainStream_Shrink( */ if (count == 0) { - StgProperty chainProp; + DirEntry chainEntry; - StorageImpl_ReadProperty(This->parentStorage, - This->ownerPropertyIndex, - &chainProp); + StorageImpl_ReadDirEntry(This->parentStorage, + This->ownerDirEntry, + &chainEntry); - chainProp.startingBlock = BLOCK_END_OF_CHAIN; + chainEntry.startingBlock = BLOCK_END_OF_CHAIN; - StorageImpl_WriteProperty(This->parentStorage, - This->ownerPropertyIndex, - &chainProp); + StorageImpl_WriteDirEntry(This->parentStorage, + This->ownerDirEntry, + &chainEntry); /* * We start freeing the chain at the head block. @@ -5609,15 +6128,15 @@ static BOOL SmallBlockChainStream_Enlarge( } else { - StgProperty chainProp; + DirEntry chainEntry; - StorageImpl_ReadProperty(This->parentStorage, This->ownerPropertyIndex, - &chainProp); + StorageImpl_ReadDirEntry(This->parentStorage, This->ownerDirEntry, + &chainEntry); - chainProp.startingBlock = blockIndex; + chainEntry.startingBlock = blockIndex; - StorageImpl_WriteProperty(This->parentStorage, This->ownerPropertyIndex, - &chainProp); + StorageImpl_WriteDirEntry(This->parentStorage, This->ownerDirEntry, + &chainEntry); } } @@ -5726,7 +6245,7 @@ static ULONG SmallBlockChainStream_GetCount(SmallBlockChainStream* This) */ static ULARGE_INTEGER SmallBlockChainStream_GetSize(SmallBlockChainStream* This) { - StgProperty chainProperty; + DirEntry chainEntry; if(This->headOfStreamPlaceHolder != NULL) { @@ -5739,12 +6258,12 @@ static ULARGE_INTEGER SmallBlockChainStream_GetSize(SmallBlockChainStream* This) return result; } - StorageImpl_ReadProperty( + StorageImpl_ReadDirEntry( This->parentStorage, - This->ownerPropertyIndex, - &chainProperty); + This->ownerDirEntry, + &chainEntry); - return chainProperty.size; + return chainEntry.size; } /****************************************************************************** @@ -5772,7 +6291,7 @@ HRESULT WINAPI StgCreateDocfile( DWORD reserved, IStorage **ppstgOpen) { - StorageImpl* newStorage = 0; + StorageBaseImpl* newStorage = 0; HANDLE hFile = INVALID_HANDLE_VALUE; HRESULT hr = STG_E_INVALIDFLAG; DWORD shareMode; @@ -5785,9 +6304,6 @@ HRESULT WINAPI StgCreateDocfile( debugstr_w(pwcsName), grfMode, reserved, ppstgOpen); - /* - * Validate the parameters - */ if (ppstgOpen == 0) return STG_E_INVALIDPOINTER; if (reserved != 0) @@ -5797,9 +6313,6 @@ HRESULT WINAPI StgCreateDocfile( if (STGM_SHARE_MODE(grfMode) == 0) grfMode |= STGM_SHARE_DENY_NONE; - /* - * Validate the STGM flags - */ if ( FAILED( validateSTGM(grfMode) )) goto end; @@ -5860,14 +6373,12 @@ HRESULT WINAPI StgCreateDocfile( fileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS; if (STGM_SHARE_MODE(grfMode) && !(grfMode & STGM_SHARE_DENY_NONE)) + { + static int fixme; + if (!fixme++) FIXME("Storage share mode not implemented.\n"); + } - if (grfMode & STGM_TRANSACTED) - FIXME("Transacted mode not implemented.\n"); - - /* - * Initialize the "out" parameter. - */ *ppstgOpen = 0; hFile = CreateFileW(pwcsName, @@ -5890,36 +6401,25 @@ HRESULT WINAPI StgCreateDocfile( /* * Allocate and initialize the new IStorage32object. */ - newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl)); - - if (newStorage == 0) - { - hr = STG_E_INSUFFICIENTMEMORY; - goto end; - } - - hr = StorageImpl_Construct( - newStorage, + hr = Storage_Construct( hFile, pwcsName, NULL, grfMode, TRUE, - TRUE); + TRUE, + &newStorage); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, newStorage); goto end; } /* * Get an "out" pointer for the caller. */ - hr = StorageBaseImpl_QueryInterface( - (IStorage*)newStorage, - &IID_IStorage, - (void**)ppstgOpen); + *ppstgOpen = (IStorage*)newStorage; + end: TRACE("<-- %p r = %08x\n", *ppstgOpen, hr); @@ -6034,20 +6534,16 @@ HRESULT WINAPI StgOpenStorage( DWORD reserved, IStorage **ppstgOpen) { - StorageImpl* newStorage = 0; + StorageBaseImpl* newStorage = 0; HRESULT hr = S_OK; HANDLE hFile = 0; DWORD shareMode; DWORD accessMode; - WCHAR fullname[MAX_PATH]; TRACE("(%s, %p, %x, %p, %d, %p)\n", debugstr_w(pwcsName), pstgPriority, grfMode, snbExclude, reserved, ppstgOpen); - /* - * Perform sanity checks - */ if (pwcsName == 0) { hr = STG_E_INVALIDNAME; @@ -6099,9 +6595,6 @@ HRESULT WINAPI StgOpenStorage( goto end; } - /* - * Validate the STGM flags - */ if ( FAILED( validateSTGM(grfMode) ) || (grfMode&STGM_CREATE)) { @@ -6124,9 +6617,6 @@ HRESULT WINAPI StgOpenStorage( shareMode = GetShareModeFromSTGM(grfMode); accessMode = GetAccessModeFromSTGM(grfMode); - /* - * Initialize the "out" parameter. - */ *ppstgOpen = 0; hFile = CreateFileW( pwcsName, @@ -6183,27 +6673,17 @@ HRESULT WINAPI StgOpenStorage( /* * Allocate and initialize the new IStorage32object. */ - newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl)); - - if (newStorage == 0) - { - hr = STG_E_INSUFFICIENTMEMORY; - goto end; - } - - /* Initialize the storage */ - hr = StorageImpl_Construct( - newStorage, + hr = Storage_Construct( hFile, pwcsName, NULL, grfMode, TRUE, - FALSE ); + FALSE, + &newStorage); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, newStorage); /* * According to the docs if the file is not a storage, return STG_E_FILEALREADYEXISTS */ @@ -6212,18 +6692,10 @@ HRESULT WINAPI StgOpenStorage( goto end; } - /* prepare the file name string given in lieu of the root property name */ - GetFullPathNameW(pwcsName, MAX_PATH, fullname, NULL); - memcpy(newStorage->filename, fullname, PROPERTY_NAME_BUFFER_LEN); - newStorage->filename[PROPERTY_NAME_BUFFER_LEN-1] = '\0'; - /* * Get an "out" pointer for the caller. */ - hr = StorageBaseImpl_QueryInterface( - (IStorage*)newStorage, - &IID_IStorage, - (void**)ppstgOpen); + *ppstgOpen = (IStorage*)newStorage; end: TRACE("<-- %08x, IStorage %p\n", hr, ppstgOpen ? *ppstgOpen : NULL); @@ -6239,45 +6711,33 @@ HRESULT WINAPI StgCreateDocfileOnILockBytes( DWORD reserved, IStorage** ppstgOpen) { - StorageImpl* newStorage = 0; + StorageBaseImpl* newStorage = 0; HRESULT hr = S_OK; - /* - * Validate the parameters - */ if ((ppstgOpen == 0) || (plkbyt == 0)) return STG_E_INVALIDPOINTER; /* * Allocate and initialize the new IStorage object. */ - newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl)); - - if (newStorage == 0) - return STG_E_INSUFFICIENTMEMORY; - - hr = StorageImpl_Construct( - newStorage, + hr = Storage_Construct( 0, 0, plkbyt, grfMode, FALSE, - TRUE); + TRUE, + &newStorage); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, newStorage); return hr; } /* * Get an "out" pointer for the caller. */ - hr = StorageBaseImpl_QueryInterface( - (IStorage*)newStorage, - &IID_IStorage, - (void**)ppstgOpen); + *ppstgOpen = (IStorage*)newStorage; return hr; } @@ -6293,56 +6753,38 @@ HRESULT WINAPI StgOpenStorageOnILockBytes( DWORD reserved, IStorage **ppstgOpen) { - StorageImpl* newStorage = 0; + StorageBaseImpl* newStorage = 0; HRESULT hr = S_OK; - /* - * Perform a sanity check - */ if ((plkbyt == 0) || (ppstgOpen == 0)) return STG_E_INVALIDPOINTER; - /* - * Validate the STGM flags - */ if ( FAILED( validateSTGM(grfMode) )) return STG_E_INVALIDFLAG; - /* - * Initialize the "out" parameter. - */ *ppstgOpen = 0; /* * Allocate and initialize the new IStorage object. */ - newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl)); - - if (newStorage == 0) - return STG_E_INSUFFICIENTMEMORY; - - hr = StorageImpl_Construct( - newStorage, + hr = Storage_Construct( 0, 0, plkbyt, grfMode, FALSE, - FALSE); + FALSE, + &newStorage); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, newStorage); return hr; } /* * Get an "out" pointer for the caller. */ - hr = StorageBaseImpl_QueryInterface( - (IStorage*)newStorage, - &IID_IStorage, - (void**)ppstgOpen); + *ppstgOpen = (IStorage*)newStorage; return hr; } @@ -7005,8 +7447,8 @@ static void OLECONVERT_GetOLE20FromOLE10(LPSTORAGE pDestStorage, const BYTE *pBu hRes = StgOpenStorage(wstrTempFile, NULL, STGM_READ, NULL, 0, &pTempStorage); if(hRes == S_OK) { - hRes = StorageImpl_CopyTo(pTempStorage, 0, NULL, NULL, pDestStorage); - StorageBaseImpl_Release(pTempStorage); + hRes = IStorage_CopyTo(pTempStorage, 0, NULL, NULL, pDestStorage); + IStorage_Release(pTempStorage); } DeleteFileW(wstrTempFile); } @@ -7050,8 +7492,8 @@ static DWORD OLECONVERT_WriteOLE20ToBuffer(LPSTORAGE pStorage, BYTE **pData) if(hRes == S_OK) { /* Copy Src Storage to the Temp Storage */ - StorageImpl_CopyTo(pStorage, 0, NULL, NULL, pTempStorage); - StorageBaseImpl_Release(pTempStorage); + IStorage_CopyTo(pStorage, 0, NULL, NULL, pTempStorage); + IStorage_Release(pTempStorage); /* Open Temp Storage as a file and copy to memory */ hFile = CreateFileW(wstrTempFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); @@ -7969,16 +8411,16 @@ StgIsStorageFile(LPCOLESTR fn) CloseHandle(hf); if (bytes_read != 8) { - WARN(" too short\n"); + TRACE(" too short\n"); return S_FALSE; } if (!memcmp(magic,STORAGE_magic,8)) { - WARN(" -> YES\n"); + TRACE(" -> YES\n"); return S_OK; } - WARN(" -> Invalid header.\n"); + TRACE(" -> Invalid header.\n"); return S_FALSE; } diff --git a/reactos/dll/win32/ole32/storage32.h b/reactos/dll/win32/ole32/storage32.h index fc4af325552..03328b29708 100644 --- a/reactos/dll/win32/ole32/storage32.h +++ b/reactos/dll/win32/ole32/storage32.h @@ -53,15 +53,15 @@ static const ULONG OFFSET_EXTBBDEPOTCOUNT = 0x00000048; static const ULONG OFFSET_BBDEPOTSTART = 0x0000004C; static const ULONG OFFSET_PS_NAME = 0x00000000; static const ULONG OFFSET_PS_NAMELENGTH = 0x00000040; -static const ULONG OFFSET_PS_PROPERTYTYPE = 0x00000042; -static const ULONG OFFSET_PS_PREVIOUSPROP = 0x00000044; -static const ULONG OFFSET_PS_NEXTPROP = 0x00000048; -static const ULONG OFFSET_PS_DIRPROP = 0x0000004C; +static const ULONG OFFSET_PS_STGTYPE = 0x00000042; +static const ULONG OFFSET_PS_LEFTCHILD = 0x00000044; +static const ULONG OFFSET_PS_RIGHTCHILD = 0x00000048; +static const ULONG OFFSET_PS_DIRROOT = 0x0000004C; static const ULONG OFFSET_PS_GUID = 0x00000050; -static const ULONG OFFSET_PS_TSS1 = 0x00000064; -static const ULONG OFFSET_PS_TSD1 = 0x00000068; -static const ULONG OFFSET_PS_TSS2 = 0x0000006C; -static const ULONG OFFSET_PS_TSD2 = 0x00000070; +static const ULONG OFFSET_PS_CTIMELOW = 0x00000064; +static const ULONG OFFSET_PS_CTIMEHIGH = 0x00000068; +static const ULONG OFFSET_PS_MTIMELOW = 0x0000006C; +static const ULONG OFFSET_PS_MTIMEHIGH = 0x00000070; static const ULONG OFFSET_PS_STARTBLOCK = 0x00000074; static const ULONG OFFSET_PS_SIZE = 0x00000078; static const WORD DEF_BIG_BLOCK_SIZE_BITS = 0x0009; @@ -72,26 +72,24 @@ static const ULONG BLOCK_EXTBBDEPOT = 0xFFFFFFFC; static const ULONG BLOCK_SPECIAL = 0xFFFFFFFD; static const ULONG BLOCK_END_OF_CHAIN = 0xFFFFFFFE; static const ULONG BLOCK_UNUSED = 0xFFFFFFFF; -static const ULONG PROPERTY_NULL = 0xFFFFFFFF; +static const ULONG DIRENTRY_NULL = 0xFFFFFFFF; -#define PROPERTY_NAME_MAX_LEN 0x20 -#define PROPERTY_NAME_BUFFER_LEN 0x40 +#define DIRENTRY_NAME_MAX_LEN 0x20 +#define DIRENTRY_NAME_BUFFER_LEN 0x40 -#define PROPSET_BLOCK_SIZE 0x00000080 +#define RAW_DIRENTRY_SIZE 0x00000080 /* - * Property type of relation + * Type of child entry link */ -#define PROPERTY_RELATION_PREVIOUS 0 -#define PROPERTY_RELATION_NEXT 1 -#define PROPERTY_RELATION_DIR 2 +#define DIRENTRY_RELATION_PREVIOUS 0 +#define DIRENTRY_RELATION_NEXT 1 +#define DIRENTRY_RELATION_DIR 2 /* - * Property type constants + * type constant used in files for the root storage */ -#define PROPTYPE_STORAGE 0x01 -#define PROPTYPE_STREAM 0x02 -#define PROPTYPE_ROOT 0x05 +#define STGTY_ROOT 0x05 /* * These defines assume a hardcoded blocksize. The code will assert @@ -116,30 +114,34 @@ static const ULONG PROPERTY_NULL = 0xFFFFFFFF; * module. */ typedef struct StorageBaseImpl StorageBaseImpl; +typedef struct StorageBaseImplVtbl StorageBaseImplVtbl; typedef struct StorageImpl StorageImpl; typedef struct BlockChainStream BlockChainStream; typedef struct SmallBlockChainStream SmallBlockChainStream; typedef struct IEnumSTATSTGImpl IEnumSTATSTGImpl; -typedef struct StgProperty StgProperty; +typedef struct DirEntry DirEntry; typedef struct StgStreamImpl StgStreamImpl; /* - * This utility structure is used to read/write the information in a storage - * property. + * A reference to a directory entry in the file or a transacted cache. */ -struct StgProperty +typedef ULONG DirRef; + +/* + * This utility structure is used to read/write the information in a directory + * entry. + */ +struct DirEntry { - WCHAR name[PROPERTY_NAME_MAX_LEN]; + WCHAR name[DIRENTRY_NAME_MAX_LEN]; WORD sizeOfNameString; - BYTE propertyType; - ULONG previousProperty; - ULONG nextProperty; - ULONG dirProperty; - GUID propertyUniqueID; - ULONG timeStampS1; - ULONG timeStampD1; - ULONG timeStampS2; - ULONG timeStampD2; + BYTE stgType; + DirRef leftChild; + DirRef rightChild; + DirRef dirRootEntry; + GUID clsid; + FILETIME ctime; + FILETIME mtime; ULONG startingBlock; ULARGE_INTEGER size; }; @@ -178,6 +180,7 @@ HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset, void OLECONVERT_CreateOleStream(LPSTORAGE pStorage); HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName); + /**************************************************************************** * Storage32BaseImpl definitions. * @@ -200,26 +203,30 @@ struct StorageBaseImpl struct list strmHead; + /* + * Storage tracking list + */ + struct list storageHead; + /* * Reference count of this object */ LONG ref; /* - * Ancestor storage (top level) + * TRUE if this object has been invalidated */ - StorageImpl* ancestorStorage; + int reverted; /* - * Index of the property for the root of - * this storage + * Index of the directory entry of this storage */ - ULONG rootPropertySetIndex; + DirRef storageDirEntry; /* - * virtual Destructor method. + * virtual methods. */ - void (*v_destructor)(StorageBaseImpl*); + const StorageBaseImplVtbl *baseVtbl; /* * flags that this storage was opened or created with @@ -230,8 +237,87 @@ struct StorageBaseImpl * State bits appear to only be preserved while running. No in the stream */ DWORD stateBits; + + /* If set, this overrides the root storage name returned by IStorage_Stat */ + LPCWSTR filename; + + BOOL create; /* Was the storage created or opened. + The behaviour of STGM_SIMPLE depends on this */ + /* + * If this storage was opened in transacted mode, the object that implements + * the transacted snapshot or cache. + */ + StorageBaseImpl *transactedChild; }; +/* virtual methods for StorageBaseImpl objects */ +struct StorageBaseImplVtbl { + void (*Destroy)(StorageBaseImpl*); + void (*Invalidate)(StorageBaseImpl*); + HRESULT (*CreateDirEntry)(StorageBaseImpl*,const DirEntry*,DirRef*); + HRESULT (*WriteDirEntry)(StorageBaseImpl*,DirRef,const DirEntry*); + HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*); + HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef); + HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*); + HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*); + HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER); +}; + +static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This) +{ + This->baseVtbl->Destroy(This); +} + +static inline void StorageBaseImpl_Invalidate(StorageBaseImpl *This) +{ + This->baseVtbl->Invalidate(This); +} + +static inline HRESULT StorageBaseImpl_CreateDirEntry(StorageBaseImpl *This, + const DirEntry *newData, DirRef *index) +{ + return This->baseVtbl->CreateDirEntry(This, newData, index); +} + +static inline HRESULT StorageBaseImpl_WriteDirEntry(StorageBaseImpl *This, + DirRef index, const DirEntry *data) +{ + return This->baseVtbl->WriteDirEntry(This, index, data); +} + +static inline HRESULT StorageBaseImpl_ReadDirEntry(StorageBaseImpl *This, + DirRef index, DirEntry *data) +{ + return This->baseVtbl->ReadDirEntry(This, index, data); +} + +static inline HRESULT StorageBaseImpl_DestroyDirEntry(StorageBaseImpl *This, + DirRef index) +{ + return This->baseVtbl->DestroyDirEntry(This, index); +} + +/* Read up to size bytes from this directory entry's stream at the given offset. */ +static inline HRESULT StorageBaseImpl_StreamReadAt(StorageBaseImpl *This, + DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) +{ + return This->baseVtbl->StreamReadAt(This, index, offset, size, buffer, bytesRead); +} + +/* Write size bytes to this directory entry's stream at the given offset, + * growing the stream if necessary. */ +static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This, + DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) +{ + return This->baseVtbl->StreamWriteAt(This, index, offset, size, buffer, bytesWritten); +} + +static inline HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This, + DirRef index, ULARGE_INTEGER newsize) +{ + return This->baseVtbl->StreamSetSize(This, index, newsize); +} + /**************************************************************************** * StorageBaseImpl stream list handlers */ @@ -239,6 +325,9 @@ struct StorageBaseImpl void StorageBaseImpl_AddStream(StorageBaseImpl * stg, StgStreamImpl * strm); void StorageBaseImpl_RemoveStream(StorageBaseImpl * stg, StgStreamImpl * strm); +/* Number of BlockChainStream objects to cache in a StorageImpl */ +#define BLOCKCHAIN_CACHE_SIZE 4 + /**************************************************************************** * Storage32Impl definitions. * @@ -255,11 +344,6 @@ struct StorageImpl */ HANDLE hFile; /* Physical support for the Docfile */ LPOLESTR pwcsName; /* Full path of the document file */ - BOOL create; /* Was the storage created or opened. - The behaviour of STGM_SIMPLE depends on this */ - - /* FIXME: should this be in Storage32BaseImpl ? */ - WCHAR filename[PROPERTY_NAME_BUFFER_LEN]; /* * File header @@ -286,21 +370,39 @@ struct StorageImpl BlockChainStream* smallBlockDepotChain; BlockChainStream* smallBlockRootChain; + /* Cache of block chain streams objects for directory entries */ + BlockChainStream* blockChainCache[BLOCKCHAIN_CACHE_SIZE]; + UINT blockChainToEvict; + /* * Pointer to the big block file abstraction */ BigBlockFile* bigBlockFile; }; -BOOL StorageImpl_ReadProperty( - StorageImpl* This, - ULONG index, - StgProperty* buffer); +HRESULT StorageImpl_ReadRawDirEntry( + StorageImpl *This, + ULONG index, + BYTE *buffer); -BOOL StorageImpl_WriteProperty( +void UpdateRawDirEntry( + BYTE *buffer, + const DirEntry *newData); + +HRESULT StorageImpl_WriteRawDirEntry( + StorageImpl *This, + ULONG index, + const BYTE *buffer); + +HRESULT StorageImpl_ReadDirEntry( + StorageImpl* This, + DirRef index, + DirEntry* buffer); + +HRESULT StorageImpl_WriteDirEntry( StorageImpl* This, - ULONG index, - const StgProperty* buffer); + DirRef index, + const DirEntry* buffer); BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks( StorageImpl* This, @@ -343,27 +445,14 @@ struct StgStreamImpl DWORD grfMode; /* - * Index of the property that owns (points to) this stream. + * Index of the directory entry that owns (points to) this stream. */ - ULONG ownerProperty; - - /* - * Helper variable that contains the size of the stream - */ - ULARGE_INTEGER streamSize; + DirRef dirEntry; /* * This is the current position of the cursor in the stream */ ULARGE_INTEGER currentPosition; - - /* - * The information in the stream is represented by a chain of small blocks - * or a chain of large blocks. Depending on the case, one of the two - * following variables points to that information. - */ - BlockChainStream* bigBlockChain; - SmallBlockChainStream* smallBlockChain; }; /* @@ -372,7 +461,7 @@ struct StgStreamImpl StgStreamImpl* StgStreamImpl_Construct( StorageBaseImpl* parentStorage, DWORD grfMode, - ULONG ownerProperty); + DirRef dirEntry); /****************************************************************************** @@ -409,8 +498,8 @@ void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset, const ULARGE_INTEGER *value); void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value); void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value); -void StorageUtl_CopyPropertyToSTATSTG(STATSTG* destination, const StgProperty* source, - int statFlags); +void StorageUtl_CopyDirEntryToSTATSTG(StorageBaseImpl *storage,STATSTG* destination, + const DirEntry* source, int statFlags); /**************************************************************************** * BlockChainStream definitions. @@ -422,7 +511,7 @@ struct BlockChainStream { StorageImpl* parentStorage; ULONG* headOfStreamPlaceHolder; - ULONG ownerPropertyIndex; + DirRef ownerDirEntry; ULONG lastBlockNoInSequence; ULONG lastBlockNoInSequenceIndex; ULONG tailIndex; @@ -435,7 +524,7 @@ struct BlockChainStream BlockChainStream* BlockChainStream_Construct( StorageImpl* parentStorage, ULONG* headOfStreamPlaceHolder, - ULONG propertyIndex); + DirRef dirEntry); void BlockChainStream_Destroy( BlockChainStream* This); @@ -467,7 +556,7 @@ BOOL BlockChainStream_SetSize( struct SmallBlockChainStream { StorageImpl* parentStorage; - ULONG ownerPropertyIndex; + DirRef ownerDirEntry; ULONG* headOfStreamPlaceHolder; }; @@ -477,7 +566,7 @@ struct SmallBlockChainStream SmallBlockChainStream* SmallBlockChainStream_Construct( StorageImpl* parentStorage, ULONG* headOfStreamPlaceHolder, - ULONG propertyIndex); + DirRef dirEntry); void SmallBlockChainStream_Destroy( SmallBlockChainStream* This); diff --git a/reactos/dll/win32/ole32/stubmanager.c b/reactos/dll/win32/ole32/stubmanager.c index 12813c6a5d7..f6b8bfa1a86 100644 --- a/reactos/dll/win32/ole32/stubmanager.c +++ b/reactos/dll/win32/ole32/stubmanager.c @@ -406,13 +406,15 @@ ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tablewea rc = (m->extrefs -= refs); if (tableweak) - rc += --m->weakrefs; + --m->weakrefs; + if (!last_unlock_releases) + rc += m->weakrefs; LeaveCriticalSection(&m->lock); TRACE("removed %u refs from %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc); - if (rc == 0 && last_unlock_releases) + if (rc == 0) stub_manager_int_release(m); return rc; @@ -551,7 +553,7 @@ void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const else if (ifstub->flags & MSHLFLAGS_TABLESTRONG) refs = 1; - stub_manager_ext_release(m, refs, tableweak, TRUE); + stub_manager_ext_release(m, refs, tableweak, FALSE); } /* is an ifstub table marshaled? */ diff --git a/reactos/dll/win32/ole32/usrmarshal.c b/reactos/dll/win32/ole32/usrmarshal.c index f180f42f8ca..ed316201f69 100644 --- a/reactos/dll/win32/ole32/usrmarshal.c +++ b/reactos/dll/win32/ole32/usrmarshal.c @@ -170,11 +170,9 @@ unsigned char * __RPC_USER CLIPFORMAT_UserMarshal(ULONG *pFlags, unsigned char * pBuffer += sizeof(UINT); *(UINT *)pBuffer = len; pBuffer += sizeof(UINT); - TRACE("marshaling format name %s\n", debugstr_wn(format, len-1)); - lstrcpynW((LPWSTR)pBuffer, format, len); + TRACE("marshaling format name %s\n", debugstr_w(format)); + memcpy(pBuffer, format, len * sizeof(WCHAR)); pBuffer += len * sizeof(WCHAR); - *(WCHAR *)pBuffer = '\0'; - pBuffer += sizeof(WCHAR); } else { @@ -238,11 +236,11 @@ unsigned char * __RPC_USER CLIPFORMAT_UserUnmarshal(ULONG *pFlags, unsigned char if (*(UINT *)pBuffer != len) RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL); pBuffer += sizeof(UINT); - if (((WCHAR *)pBuffer)[len] != '\0') + if (((WCHAR *)pBuffer)[len - 1] != '\0') RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL); TRACE("unmarshaling clip format %s\n", debugstr_w((LPCWSTR)pBuffer)); cf = RegisterClipboardFormatW((LPCWSTR)pBuffer); - pBuffer += (len + 1) * sizeof(WCHAR); + pBuffer += len * sizeof(WCHAR); if (!cf) RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL); *pCF = cf; From 93343602664a9e4429e5c5ca2de0539e59252027 Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Wed, 10 Mar 2010 15:00:25 +0000 Subject: [PATCH 21/64] Updated README.WINE. Additionally I added a * to all Autosyncs which lie a bit back already. Will look through them and check which are still recent. svn path=/trunk/; revision=46058 --- reactos/media/doc/README.WINE | 175 +++++++++++++++++----------------- 1 file changed, 89 insertions(+), 86 deletions(-) diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index c10502a8f18..6bbe28d21b2 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -37,155 +37,158 @@ reactos/dll/directx/dmusic # Synced to Wine-1_1_23 reactos/dll/directx/dplay # Synced to Wine-0_9_5 reactos/dll/directx/dplayx # Synced to Wine-0_9_5 reactos/dll/directx/dxdiagn # Synced to Wine-0_9_5 -reactos/dll/directx/msdmo # Autosync +reactos/dll/directx/msdmo # Autosync* reactos/dll/directx/qedit # Autosync reactos/dll/directx/quartz # Autosync -reactos/dll/win32/advpack # Autosync +reactos/dll/win32/advpack # Autosync* reactos/dll/win32/atl # Autosync -reactos/dll/win32/avifil32 # Autosync -reactos/dll/win32/bcrypt # Autosync +reactos/dll/win32/avifil32 # Autosync* +reactos/dll/win32/bcrypt # Autosync* reactos/dll/win32/browseui # Out of sync -reactos/dll/win32/cabinet # Autosync +reactos/dll/win32/cabinet # Autosync* reactos/dll/win32/clusapi # Autosync -reactos/dll/win32/comcat # Autosync -reactos/dll/win32/comctl32 # Autosync -reactos/dll/win32/comdlg32 # Autosync -reactos/dll/win32/compstui # Autosync +reactos/dll/win32/comcat # Autosync* +reactos/dll/win32/comctl32 # Autosync* +reactos/dll/win32/comdlg32 # Autosync* +reactos/dll/win32/compstui # Autosync* reactos/dll/win32/credui # Autosync -reactos/dll/win32/crypt32 # Synced to Wine-1_1_21 +reactos/dll/win32/crypt32 # Synced to Wine-1_1_40 reactos/dll/win32/cryptdlg # Autosync -reactos/dll/win32/cryptdll # Autosync +reactos/dll/win32/cryptdll # Autosync* reactos/dll/win32/cryptnet # Autosync reactos/dll/win32/cryptui # Autosync reactos/dll/win32/dbghelp # Synced to Wine-20080802 reactos/dll/win32/dciman32 # Synced to Wine-1_0-rc2 +reactos/dll/win32/dwmapi # Autosync +reactos/dll/win32/fusion # Autosync reactos/dll/win32/gdiplus # Autosync reactos/dll/win32/hhctrl.ocx # Autosync reactos/dll/win32/hlink # Autosync -reactos/dll/win32/hnetcfg # Autosync -reactos/dll/win32/httpapi # Autosync +reactos/dll/win32/hnetcfg # Autosync* +reactos/dll/win32/httpapi # Autosync* reactos/dll/win32/iccvid # Autosync reactos/dll/win32/icmp # Synced to Wine-0_9_10 -reactos/dll/win32/imaadp32.acm # Autosync +reactos/dll/win32/imaadp32.acm # Autosync* reactos/dll/win32/imm32 # Autosync reactos/dll/win32/imagehlp # Patches for BindImage need review and submission to winehq. reactos/dll/win32/inetcomm # Autosync reactos/dll/win32/inetmib1 # Autosync -reactos/dll/win32/initpki # Autosync -reactos/dll/win32/inseng # Autosync +reactos/dll/win32/initpki # Autosync* +reactos/dll/win32/inseng # Autosync* reactos/dll/win32/iphlpapi # Out of sync reactos/dll/win32/itircl # Autosync reactos/dll/win32/itss # Autosync reactos/dll/win32/jscript # Autosync -reactos/dll/win32/localspl # Autosync -reactos/dll/win32/localui # Autosync -reactos/dll/win32/lz32 # Autosync +reactos/dll/win32/localspl # Autosync* +reactos/dll/win32/localui # Autosync* +reactos/dll/win32/lz32 # Autosync* reactos/dll/win32/mapi32 # Autosync -reactos/dll/win32/mciavi32 # Autosync -reactos/dll/win32/mcicda # Autosync -reactos/dll/win32/mciqtz32 # Autosync -reactos/dll/win32/mciseq # Autosync +reactos/dll/win32/mciavi32 # Autosync* +reactos/dll/win32/mcicda # Autosync* +reactos/dll/win32/mciqtz32 # Autosync* +reactos/dll/win32/mciseq # Autosync* reactos/dll/win32/mciwave # Autosync -reactos/dll/win32/mlang # Autosync +reactos/dll/win32/mlang # Autosync* reactos/dll/win32/mpr # Autosync reactos/dll/win32/msacm32 # Out of sync -reactos/dll/win32/msadp32.acm # Autosync -reactos/dll/win32/mscat32 # Autosync -reactos/dll/win32/mscms # Autosync +reactos/dll/win32/msadp32.acm # Autosync* +reactos/dll/win32/mscat32 # Autosync* +reactos/dll/win32/mscms # Autosync* reactos/dll/win32/mscoree # Autosync reactos/dll/win32/msctf # Autosync -reactos/dll/win32/msftedit # Autosync -reactos/dll/win32/msg711.acm # Autosync -reactos/dll/win32/msgsm32.acm # Autosync +reactos/dll/win32/msftedit # Autosync* +reactos/dll/win32/msg711.acm # Autosync* +reactos/dll/win32/msgsm32.acm # Autosync* reactos/dll/win32/mshtml # Autosync -reactos/dll/win32/msimg32 # Autosync +reactos/dll/win32/msimg32 # Autosync* reactos/dll/win32/msi # Autosync -reactos/dll/win32/msimtf # Autosync -reactos/dll/win32/msisip # Autosync -reactos/dll/win32/msisys.ocx # Autosync -reactos/dll/win32/msnet32 # Autosync -reactos/dll/win32/msrle32 # Autosync -reactos/dll/win32/mssign32 # Autosync -reactos/dll/win32/mssip32 # Autosync -reactos/dll/win32/mstask # Autosync -reactos/dll/win32/msvcrt20 # Autosync -reactos/dll/win32/msvfw32 # Autosync -reactos/dll/win32/msvidc32 # Autosync -reactos/dll/win32/msxml3 # Synced to Wine-1_1_20 -reactos/dll/win32/nddeapi # Autosync +reactos/dll/win32/msimtf # Autosync* +reactos/dll/win32/msisip # Autosync* +reactos/dll/win32/msisys.ocx # Autosync* +reactos/dll/win32/msnet32 # Autosync* +reactos/dll/win32/msrle32 # Autosync* +reactos/dll/win32/mssign32 # Autosync* +reactos/dll/win32/mssip32 # Autosync* +reactos/dll/win32/mstask # Autosync* +reactos/dll/win32/msvcrt20 # Autosync* +reactos/dll/win32/msvfw32 # Autosync* +reactos/dll/win32/msvidc32 # Autosync* +reactos/dll/win32/msxml3 # Synced to Wine-1_1_40 +reactos/dll/win32/nddeapi # Autosync* reactos/dll/win32/netapi32 # Autosync -reactos/dll/win32/ntdsapi # Autosync -reactos/dll/win32/ntprint # Autosync +reactos/dll/win32/ntdsapi # Autosync* +reactos/dll/win32/ntprint # Autosync* reactos/dll/win32/objsel # Autosync reactos/dll/win32/odbc32 # Out of sync. Depends on port of Linux ODBC. -reactos/dll/win32/odbccp32 # Autosync +reactos/dll/win32/odbccp32 # Autosync* reactos/dll/win32/ole32 # Autosync reactos/dll/win32/oleacc # Autosync -reactos/dll/win32/oleaut32 # Autosync -reactos/dll/win32/olecli32 # Autosync +reactos/dll/win32/oleaut32 # Autosync* +reactos/dll/win32/olecli32 # Autosync* reactos/dll/win32/oledlg # Autosync reactos/dll/win32/olepro32 # Autosync -reactos/dll/win32/olesvr32 # Autosync -reactos/dll/win32/olethk32 # Autosync +reactos/dll/win32/olesvr32 # Autosync* +reactos/dll/win32/olethk32 # Autosync* reactos/dll/win32/pdh # Autosync -reactos/dll/win32/pidgen # Autosync +reactos/dll/win32/pidgen # Autosync* reactos/dll/win32/powrprof # Forked at Wine-1.0rc5 -reactos/dll/win32/printui # Autosync +reactos/dll/win32/printui # Autosync* reactos/dll/win32/pstorec # Autosync reactos/dll/win32/query # Autosync -reactos/dll/win32/rasapi32 # Autosync -reactos/dll/win32/resutils # Autosync -reactos/dll/win32/riched20 # Autosync -reactos/dll/win32/riched32 # Autosync +reactos/dll/win32/rasapi32 # Autosync* +reactos/dll/win32/resutils # Autosync* +reactos/dll/win32/riched20 # Autosync* +reactos/dll/win32/riched32 # Autosync* reactos/dll/win32/rpcrt4 # Synced to Wine-0_9_55 -reactos/dll/win32/rsabase # Autosync +reactos/dll/win32/rsabase # Autosync* reactos/dll/win32/rsaenh # Autosync -reactos/dll/win32/sccbase # Autosync -reactos/dll/win32/schannel # Autosync -reactos/dll/win32/sensapi # Autosync +reactos/dll/win32/sccbase # Autosync* +reactos/dll/win32/schannel # Autosync* +reactos/dll/win32/sensapi # Autosync* reactos/dll/win32/setupapi # Forked at Wine-20050524 reactos/dll/win32/shell32 # Forked at Wine-20071011 -reactos/dll/win32/shdocvw # Synced to Wine-1_1_20 -reactos/dll/win32/shfolder # Autosync +reactos/dll/win32/shdocvw # Synced to Wine-1_1_40 +reactos/dll/win32/shfolder # Autosync* reactos/dll/win32/shlwapi # Autosync -reactos/dll/win32/slbcsp # Autosync -reactos/dll/win32/softpub # Autosync -reactos/dll/win32/spoolss # Autosync -reactos/dll/win32/stdole2.tlb # Autosync -reactos/dll/win32/sti # Autosync -reactos/dll/win32/sxs # Autosync +reactos/dll/win32/slbcsp # Autosync* +reactos/dll/win32/softpub # Autosync* +reactos/dll/win32/spoolss # Autosync* +reactos/dll/win32/stdole2.tlb # Autosync* +reactos/dll/win32/sti # Autosync* +reactos/dll/win32/sxs # Autosync* reactos/dll/win32/tapi32 # Autosync -reactos/dll/win32/traffic # Autosync +reactos/dll/win32/traffic # Autosync* reactos/dll/win32/twain_32 # Out of sync -reactos/dll/win32/updspapi # Autosync -reactos/dll/win32/url # Autosync +reactos/dll/win32/updspapi # Autosync* +reactos/dll/win32/url # Autosync* reactos/dll/win32/urlmon # Autosync -reactos/dll/win32/usp10 # Autosync +reactos/dll/win32/usp10 # Autosync* reactos/dll/win32/uxtheme # Autosync -reactos/dll/win32/version # Autosync +reactos/dll/win32/version # Autosync* reactos/dll/win32/windowscodecs # Autosync -reactos/dll/win32/winemp3.acm # Autosync -reactos/dll/win32/wininet # Autosync -reactos/dll/win32/winhttp # Autosync +reactos/dll/win32/winemp3.acm # Autosync* +reactos/dll/win32/wininet # Autosync* +reactos/dll/win32/winhttp # Autosync* reactos/dll/win32/winmm # Forked at Wine-20050628 reactos/dll/win32/winmm/midimap # Forked at Wine-20050628 reactos/dll/win32/winmm/wavemap # Forked at Wine-20050628 -reactos/dll/win32/wintab32 # Autosync -reactos/dll/win32/wintrust # Out of sync -reactos/dll/win32/wldap32 # Autosync -reactos/dll/win32/wmi # Autosync +reactos/dll/win32/wintab32 # Autosync* +reactos/dll/win32/wintrust # Autosync +reactos/dll/win32/wldap32 # Autosync* +reactos/dll/win32/wmi # Autosync* reactos/dll/win32/wtsapi32 # Forked -reactos/dll/win32/wuapi # Autosync -reactos/dll/win32/xinput1_1 # Autosync -reactos/dll/win32/xinput1_2 # Autosync -reactos/dll/win32/xinput1_3 # Autosync -reactos/dll/win32/xinput9_1_0 # Autosync +reactos/dll/win32/wuapi # Autosync* +reactos/dll/win32/xinput1_1 # Autosync* +reactos/dll/win32/xinput1_2 # Autosync* +reactos/dll/win32/xinput1_3 # Autosync* +reactos/dll/win32/xinput9_1_0 # Autosync* reactos/dll/win32/xmllite # Autosync ReactOS shares the following programs with Winehq. reactos/base/applications/cmdutils/xcopy # Autosync reactos/base/applications/games/winemine # Out of sync +reactos/base/applications/extrac32 # Autosync reactos/base/applications/iexplore # Autosync reactos/base/applications/notepad # Forked at Wine-20041201 reactos/base/applications/reg # Autosync From 5e3123f80a18a778d0c00ad08c1b414646b43f8c Mon Sep 17 00:00:00 2001 From: Sylvain Petreolle Date: Wed, 10 Mar 2010 16:18:32 +0000 Subject: [PATCH 22/64] [WLANSVC] - Add required libary iphlpapi svn path=/trunk/; revision=46061 --- reactos/base/services/wlansvc/rpcserver.c | 2 +- reactos/base/services/wlansvc/wlansvc.rbuild | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/reactos/base/services/wlansvc/rpcserver.c b/reactos/base/services/wlansvc/rpcserver.c index b6475257b5e..bb010368669 100644 --- a/reactos/base/services/wlansvc/rpcserver.c +++ b/reactos/base/services/wlansvc/rpcserver.c @@ -14,7 +14,7 @@ #define NDEBUG #include - +//#define GET_IF_ENTRY2_IMPLEMENTED 1 DWORD _RpcOpenHandle( wchar_t *arg_1, diff --git a/reactos/base/services/wlansvc/wlansvc.rbuild b/reactos/base/services/wlansvc/wlansvc.rbuild index da8bf8259ff..4f656380d58 100644 --- a/reactos/base/services/wlansvc/wlansvc.rbuild +++ b/reactos/base/services/wlansvc/wlansvc.rbuild @@ -8,6 +8,7 @@ advapi32 rpcrt4 pseh + iphlpapi wlansvc.c rpcserver.c From 94e01c6025a06f1e70f15e8e930be265a337e39d Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Wed, 10 Mar 2010 16:21:22 +0000 Subject: [PATCH 23/64] Sync avifil32, hnetcfg, initpki, localspl, localui, mciavi32, mciqtz32, mciseq and mlang to Wine 1.1.40 More will come. svn path=/trunk/; revision=46062 --- reactos/dll/win32/avifil32/avifile_De.rc | 1 - reactos/dll/win32/avifil32/avifile_Fr.rc | 1 - reactos/dll/win32/avifil32/avifile_Ja.rc | 2 - reactos/dll/win32/avifil32/avifile_Lt.rc | 1 - reactos/dll/win32/avifil32/avifile_Ro.rc | 1 - reactos/dll/win32/avifil32/avifile_Ru.rc | 1 - reactos/dll/win32/avifil32/avifile_Si.rc | 2 - reactos/dll/win32/avifil32/avifile_Tr.rc | 2 + reactos/dll/win32/avifil32/avifile_Uk.rc | 1 + reactos/dll/win32/avifil32/avifile_Zh.rc | 4 +- reactos/dll/win32/avifil32/rsrc.rc | 16 +- reactos/dll/win32/hnetcfg/hnetcfg.c | 1 - reactos/dll/win32/hnetcfg/hnetcfg.rbuild | 2 + reactos/dll/win32/hnetcfg/hnetcfg_private.h | 2 + reactos/dll/win32/hnetcfg/port.c | 544 ++++++++++++++++ reactos/dll/win32/hnetcfg/profile.c | 8 +- reactos/dll/win32/hnetcfg/regsvr.c | 4 +- reactos/dll/win32/hnetcfg/service.c | 479 ++++++++++++++ reactos/dll/win32/initpki/initpki.spec | 4 +- reactos/dll/win32/initpki/main.c | 18 + reactos/dll/win32/localspl/localspl.rc | 10 +- reactos/dll/win32/localspl/localspl_private.h | 1 + reactos/dll/win32/localspl/provider.c | 582 +++++++++++++++++- reactos/dll/win32/localspl/spl_Da.rc | 4 +- reactos/dll/win32/localspl/spl_De.rc | 4 + reactos/dll/win32/localspl/spl_En.rc | 2 + reactos/dll/win32/localspl/spl_Es.rc | 32 + reactos/dll/win32/localspl/spl_Fr.rc | 2 + reactos/dll/win32/localspl/spl_Ko.rc | 2 + reactos/dll/win32/localspl/spl_Lt.rc | 32 + reactos/dll/win32/localspl/spl_Nl.rc | 2 + reactos/dll/win32/localspl/spl_No.rc | 2 + reactos/dll/win32/localspl/spl_Pl.rc | 2 + reactos/dll/win32/localspl/spl_Pt.rc | 2 + reactos/dll/win32/localspl/spl_Ro.rc | 4 + reactos/dll/win32/localspl/spl_Ru.rc | 9 +- reactos/dll/win32/localspl/spl_Si.rc | 4 +- reactos/dll/win32/localspl/spl_Sv.rc | 2 + reactos/dll/win32/localspl/spl_Zh.rc | 4 +- reactos/dll/win32/localui/localui.c | 10 +- reactos/dll/win32/localui/localui.h | 2 + reactos/dll/win32/localui/localui.rc | 10 +- reactos/dll/win32/localui/ui_Da.rc | 2 + reactos/dll/win32/localui/ui_De.rc | 14 +- reactos/dll/win32/localui/ui_En.rc | 2 + reactos/dll/win32/localui/ui_Fr.rc | 5 +- reactos/dll/win32/localui/ui_Ko.rc | 2 + reactos/dll/win32/localui/ui_Lt.rc | 3 +- reactos/dll/win32/localui/ui_Nl.rc | 2 + reactos/dll/win32/localui/ui_No.rc | 2 + reactos/dll/win32/localui/ui_Pl.rc | 2 + reactos/dll/win32/localui/ui_Pt.rc | 2 + reactos/dll/win32/localui/ui_Ro.rc | 4 +- reactos/dll/win32/localui/ui_Ru.rc | 27 +- reactos/dll/win32/localui/ui_Si.rc | 4 +- reactos/dll/win32/localui/ui_Sv.rc | 2 + reactos/dll/win32/localui/ui_Zh.rc | 4 +- reactos/dll/win32/mciavi32/info.c | 136 +++- reactos/dll/win32/mciavi32/mciavi.c | 478 +++----------- reactos/dll/win32/mciavi32/mciavi_res.rc | 8 + reactos/dll/win32/mciavi32/mmoutput.c | 2 + reactos/dll/win32/mciavi32/wnd.c | 3 + reactos/dll/win32/mciqtz32/mciqtz.c | 93 ++- reactos/dll/win32/mciseq/mcimidi.c | 9 +- reactos/dll/win32/mlang/mlang.c | 12 +- 65 files changed, 2124 insertions(+), 512 deletions(-) create mode 100644 reactos/dll/win32/hnetcfg/port.c create mode 100644 reactos/dll/win32/hnetcfg/service.c create mode 100644 reactos/dll/win32/localspl/spl_Es.rc create mode 100644 reactos/dll/win32/localspl/spl_Lt.rc diff --git a/reactos/dll/win32/avifil32/avifile_De.rc b/reactos/dll/win32/avifil32/avifile_De.rc index 7b40709b9a6..0730046dc20 100644 --- a/reactos/dll/win32/avifil32/avifile_De.rc +++ b/reactos/dll/win32/avifil32/avifile_De.rc @@ -52,4 +52,3 @@ STRINGTABLE DISCARDABLE IDS_AVIFILETYPE "Wine AVI-Standard-Dateibehandlungsroutine" IDS_UNCOMPRESSED "Unkomprimiert" } -#pragma code_page(default) diff --git a/reactos/dll/win32/avifil32/avifile_Fr.rc b/reactos/dll/win32/avifil32/avifile_Fr.rc index 45adafe8f02..d313226b0a1 100644 --- a/reactos/dll/win32/avifil32/avifile_Fr.rc +++ b/reactos/dll/win32/avifil32/avifile_Fr.rc @@ -57,4 +57,3 @@ STRINGTABLE DISCARDABLE IDS_AVIFILETYPE "Gestionnaire de fichiers AVI par défaut de Wine" IDS_UNCOMPRESSED "non compressé" } -#pragma code_page(default) diff --git a/reactos/dll/win32/avifil32/avifile_Ja.rc b/reactos/dll/win32/avifil32/avifile_Ja.rc index 4ac229c21fe..847a1fd471f 100644 --- a/reactos/dll/win32/avifil32/avifile_Ja.rc +++ b/reactos/dll/win32/avifil32/avifile_Ja.rc @@ -53,5 +53,3 @@ STRINGTABLE DISCARDABLE IDS_AVIFILETYPE "Wine AVI-default-filehandler" IDS_UNCOMPRESSED "未圧縮" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/avifil32/avifile_Lt.rc b/reactos/dll/win32/avifil32/avifile_Lt.rc index ca93ba6ad2d..e4795b5ea03 100644 --- a/reactos/dll/win32/avifil32/avifile_Lt.rc +++ b/reactos/dll/win32/avifil32/avifile_Lt.rc @@ -53,4 +53,3 @@ STRINGTABLE DISCARDABLE IDS_AVIFILETYPE "Wine numatyta-AVI-doroklÄ—" IDS_UNCOMPRESSED "neglaudintas" } -#pragma code_page(default) diff --git a/reactos/dll/win32/avifil32/avifile_Ro.rc b/reactos/dll/win32/avifil32/avifile_Ro.rc index 1e5d710b8c8..6e63780045f 100644 --- a/reactos/dll/win32/avifil32/avifile_Ro.rc +++ b/reactos/dll/win32/avifil32/avifile_Ro.rc @@ -55,4 +55,3 @@ STRINGTABLE DISCARDABLE IDS_AVIFILETYPE "Tratare implicită Wine pentru AVI" IDS_UNCOMPRESSED "necomprimat" } -#pragma code_page(default) diff --git a/reactos/dll/win32/avifil32/avifile_Ru.rc b/reactos/dll/win32/avifil32/avifile_Ru.rc index 4a75a6721b6..12ac27d3b98 100644 --- a/reactos/dll/win32/avifil32/avifile_Ru.rc +++ b/reactos/dll/win32/avifil32/avifile_Ru.rc @@ -55,4 +55,3 @@ STRINGTABLE DISCARDABLE IDS_AVIFILETYPE "Обработчик по умолчанию avi-файлов в Wine" IDS_UNCOMPRESSED "без ÑжатиÑ" } -#pragma code_page(default) diff --git a/reactos/dll/win32/avifil32/avifile_Si.rc b/reactos/dll/win32/avifil32/avifile_Si.rc index e7d90f65893..0840321eaa1 100644 --- a/reactos/dll/win32/avifil32/avifile_Si.rc +++ b/reactos/dll/win32/avifil32/avifile_Si.rc @@ -52,5 +52,3 @@ STRINGTABLE DISCARDABLE IDS_AVIFILETYPE "Wine privzeti-upravljalec-AVI-datotek" IDS_UNCOMPRESSED "nestisnjeno" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/avifil32/avifile_Tr.rc b/reactos/dll/win32/avifil32/avifile_Tr.rc index 451802f42bf..c5dbf6e818d 100644 --- a/reactos/dll/win32/avifil32/avifile_Tr.rc +++ b/reactos/dll/win32/avifil32/avifile_Tr.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "avifile_private.h" + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT IDD_SAVEOPTIONS DIALOG FIXED IMPURE 43, 37, 226, 82 diff --git a/reactos/dll/win32/avifil32/avifile_Uk.rc b/reactos/dll/win32/avifil32/avifile_Uk.rc index d380c8ad78c..9934ab411fa 100644 --- a/reactos/dll/win32/avifil32/avifile_Uk.rc +++ b/reactos/dll/win32/avifil32/avifile_Uk.rc @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "avifile_private.h" LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT diff --git a/reactos/dll/win32/avifil32/avifile_Zh.rc b/reactos/dll/win32/avifil32/avifile_Zh.rc index 0075ed8ecfe..5d962e7fdd5 100644 --- a/reactos/dll/win32/avifil32/avifile_Zh.rc +++ b/reactos/dll/win32/avifil32/avifile_Zh.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "avifile_private.h" + /* Chinese text is encoded in UTF-8 */ #pragma code_page(65001) @@ -86,5 +88,3 @@ STRINGTABLE DISCARDABLE IDS_AVIFILETYPE "Wine AVI-默èªè™•ç†å™¨" IDS_UNCOMPRESSED "未壓縮" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/avifil32/rsrc.rc b/reactos/dll/win32/avifil32/rsrc.rc index e4363a7d7cb..d86578c5a6b 100644 --- a/reactos/dll/win32/avifil32/rsrc.rc +++ b/reactos/dll/win32/avifil32/rsrc.rc @@ -40,23 +40,25 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL */ #include "avifile_Cs.rc" #include "avifile_Da.rc" -#include "avifile_De.rc" #include "avifile_En.rc" #include "avifile_Es.rc" -#include "avifile_Fr.rc" #include "avifile_Hu.rc" #include "avifile_It.rc" -#include "avifile_Ja.rc" #include "avifile_Ko.rc" -#include "avifile_Lt.rc" #include "avifile_Nl.rc" #include "avifile_No.rc" #include "avifile_Pl.rc" #include "avifile_Pt.rc" -#include "avifile_Ro.rc" -#include "avifile_Ru.rc" -#include "avifile_Si.rc" #include "avifile_Sv.rc" #include "avifile_Tr.rc" #include "avifile_Uk.rc" + +/* UTF-8 */ +#include "avifile_De.rc" +#include "avifile_Fr.rc" +#include "avifile_Ja.rc" +#include "avifile_Lt.rc" +#include "avifile_Ro.rc" +#include "avifile_Ru.rc" +#include "avifile_Si.rc" #include "avifile_Zh.rc" diff --git a/reactos/dll/win32/hnetcfg/hnetcfg.c b/reactos/dll/win32/hnetcfg/hnetcfg.c index 72336f91210..3ecc8c23219 100644 --- a/reactos/dll/win32/hnetcfg/hnetcfg.c +++ b/reactos/dll/win32/hnetcfg/hnetcfg.c @@ -147,6 +147,5 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) HRESULT WINAPI DllCanUnloadNow( void ) { - FIXME("\n"); return S_FALSE; } diff --git a/reactos/dll/win32/hnetcfg/hnetcfg.rbuild b/reactos/dll/win32/hnetcfg/hnetcfg.rbuild index dd4612f360c..91c8fcb7b81 100644 --- a/reactos/dll/win32/hnetcfg/hnetcfg.rbuild +++ b/reactos/dll/win32/hnetcfg/hnetcfg.rbuild @@ -12,6 +12,8 @@ hnetcfg.c manager.c policy.c + port.c profile.c regsvr.c + service.c diff --git a/reactos/dll/win32/hnetcfg/hnetcfg_private.h b/reactos/dll/win32/hnetcfg/hnetcfg_private.h index 933782950bb..c64bdc2820b 100644 --- a/reactos/dll/win32/hnetcfg/hnetcfg_private.h +++ b/reactos/dll/win32/hnetcfg/hnetcfg_private.h @@ -21,3 +21,5 @@ HRESULT NetFwPolicy_create(IUnknown *, LPVOID *); HRESULT NetFwProfile_create(IUnknown *, LPVOID *); HRESULT NetFwAuthorizedApplication_create(IUnknown *, LPVOID *); HRESULT NetFwAuthorizedApplications_create(IUnknown *, LPVOID *); +HRESULT NetFwOpenPorts_create(IUnknown *, LPVOID *); +HRESULT NetFwServices_create(IUnknown *, LPVOID *); diff --git a/reactos/dll/win32/hnetcfg/port.c b/reactos/dll/win32/hnetcfg/port.c new file mode 100644 index 00000000000..c80b5f7bfce --- /dev/null +++ b/reactos/dll/win32/hnetcfg/port.c @@ -0,0 +1,544 @@ +/* + * Copyright 2009 Hans Leidekker 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 "config.h" +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "ole2.h" +#include "netfw.h" + +#include "wine/debug.h" +#include "wine/unicode.h" +#include "hnetcfg_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(hnetcfg); + +typedef struct fw_port +{ + const INetFwOpenPortVtbl *vtbl; + LONG refs; +} fw_port; + +static inline fw_port *impl_from_INetFwOpenPort( INetFwOpenPort *iface ) +{ + return (fw_port *)((char *)iface - FIELD_OFFSET( fw_port, vtbl )); +} + +static ULONG WINAPI fw_port_AddRef( + INetFwOpenPort *iface ) +{ + fw_port *fw_port = impl_from_INetFwOpenPort( iface ); + return InterlockedIncrement( &fw_port->refs ); +} + +static ULONG WINAPI fw_port_Release( + INetFwOpenPort *iface ) +{ + fw_port *fw_port = impl_from_INetFwOpenPort( iface ); + LONG refs = InterlockedDecrement( &fw_port->refs ); + if (!refs) + { + TRACE("destroying %p\n", fw_port); + HeapFree( GetProcessHeap(), 0, fw_port ); + } + return refs; +} + +static HRESULT WINAPI fw_port_QueryInterface( + INetFwOpenPort *iface, + REFIID riid, + void **ppvObject ) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_INetFwOpenPort ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + INetFwOpenPort_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI fw_port_GetTypeInfoCount( + INetFwOpenPort *iface, + UINT *pctinfo ) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %p\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_GetTypeInfo( + INetFwOpenPort *iface, + UINT iTInfo, + LCID lcid, + ITypeInfo **ppTInfo ) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %u %u %p\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_GetIDsOfNames( + INetFwOpenPort *iface, + REFIID riid, + LPOLESTR *rgszNames, + UINT cNames, + LCID lcid, + DISPID *rgDispId ) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %s %p %u %u %p\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_Invoke( + INetFwOpenPort *iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS *pDispParams, + VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, + UINT *puArgErr ) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %d %s %d %d %p %p %p %p\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_get_Name( + INetFwOpenPort *iface, + BSTR *name) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %p\n", This, name); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_put_Name( + INetFwOpenPort *iface, + BSTR name) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %s\n", This, debugstr_w(name)); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_get_IpVersion( + INetFwOpenPort *iface, + NET_FW_IP_VERSION *ipVersion) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %p\n", This, ipVersion); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_put_IpVersion( + INetFwOpenPort *iface, + NET_FW_IP_VERSION ipVersion) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %u\n", This, ipVersion); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_get_Protocol( + INetFwOpenPort *iface, + NET_FW_IP_PROTOCOL *ipProtocol) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %p\n", This, ipProtocol); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_put_Protocol( + INetFwOpenPort *iface, + NET_FW_IP_PROTOCOL ipProtocol) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %u\n", This, ipProtocol); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_get_Port( + INetFwOpenPort *iface, + LONG *portNumber) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %p\n", This, portNumber); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_put_Port( + INetFwOpenPort *iface, + LONG portNumber) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %d\n", This, portNumber); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_get_Scope( + INetFwOpenPort *iface, + NET_FW_SCOPE *scope) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %p\n", This, scope); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_put_Scope( + INetFwOpenPort *iface, + NET_FW_SCOPE scope) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %u\n", This, scope); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_get_RemoteAddresses( + INetFwOpenPort *iface, + BSTR *remoteAddrs) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %p\n", This, remoteAddrs); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_put_RemoteAddresses( + INetFwOpenPort *iface, + BSTR remoteAddrs) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %s\n", This, debugstr_w(remoteAddrs)); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_get_Enabled( + INetFwOpenPort *iface, + VARIANT_BOOL *enabled) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %p\n", This, enabled); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_put_Enabled( + INetFwOpenPort *iface, + VARIANT_BOOL enabled) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %d\n", This, enabled); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_port_get_BuiltIn( + INetFwOpenPort *iface, + VARIANT_BOOL *builtIn) +{ + fw_port *This = impl_from_INetFwOpenPort( iface ); + + FIXME("%p %p\n", This, builtIn); + return E_NOTIMPL; +} + +static const struct INetFwOpenPortVtbl fw_port_vtbl = +{ + fw_port_QueryInterface, + fw_port_AddRef, + fw_port_Release, + fw_port_GetTypeInfoCount, + fw_port_GetTypeInfo, + fw_port_GetIDsOfNames, + fw_port_Invoke, + fw_port_get_Name, + fw_port_put_Name, + fw_port_get_IpVersion, + fw_port_put_IpVersion, + fw_port_get_Protocol, + fw_port_put_Protocol, + fw_port_get_Port, + fw_port_put_Port, + fw_port_get_Scope, + fw_port_put_Scope, + fw_port_get_RemoteAddresses, + fw_port_put_RemoteAddresses, + fw_port_get_Enabled, + fw_port_put_Enabled, + fw_port_get_BuiltIn +}; + +static HRESULT NetFwOpenPort_create( IUnknown *pUnkOuter, LPVOID *ppObj ) +{ + fw_port *fp; + + TRACE("(%p,%p)\n", pUnkOuter, ppObj); + + fp = HeapAlloc( GetProcessHeap(), 0, sizeof(*fp) ); + if (!fp) return E_OUTOFMEMORY; + + fp->vtbl = &fw_port_vtbl; + fp->refs = 1; + + *ppObj = &fp->vtbl; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} + +typedef struct fw_ports +{ + const INetFwOpenPortsVtbl *vtbl; + LONG refs; +} fw_ports; + +static inline fw_ports *impl_from_INetFwOpenPorts( INetFwOpenPorts *iface ) +{ + return (fw_ports *)((char *)iface - FIELD_OFFSET( fw_ports, vtbl )); +} + +static ULONG WINAPI fw_ports_AddRef( + INetFwOpenPorts *iface ) +{ + fw_ports *fw_ports = impl_from_INetFwOpenPorts( iface ); + return InterlockedIncrement( &fw_ports->refs ); +} + +static ULONG WINAPI fw_ports_Release( + INetFwOpenPorts *iface ) +{ + fw_ports *fw_ports = impl_from_INetFwOpenPorts( iface ); + LONG refs = InterlockedDecrement( &fw_ports->refs ); + if (!refs) + { + TRACE("destroying %p\n", fw_ports); + HeapFree( GetProcessHeap(), 0, fw_ports ); + } + return refs; +} + +static HRESULT WINAPI fw_ports_QueryInterface( + INetFwOpenPorts *iface, + REFIID riid, + void **ppvObject ) +{ + fw_ports *This = impl_from_INetFwOpenPorts( iface ); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_INetFwOpenPorts ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + INetFwOpenPorts_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI fw_ports_GetTypeInfoCount( + INetFwOpenPorts *iface, + UINT *pctinfo ) +{ + fw_ports *This = impl_from_INetFwOpenPorts( iface ); + + FIXME("%p %p\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_ports_GetTypeInfo( + INetFwOpenPorts *iface, + UINT iTInfo, + LCID lcid, + ITypeInfo **ppTInfo ) +{ + fw_ports *This = impl_from_INetFwOpenPorts( iface ); + + FIXME("%p %u %u %p\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_ports_GetIDsOfNames( + INetFwOpenPorts *iface, + REFIID riid, + LPOLESTR *rgszNames, + UINT cNames, + LCID lcid, + DISPID *rgDispId ) +{ + fw_ports *This = impl_from_INetFwOpenPorts( iface ); + + FIXME("%p %s %p %u %u %p\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_ports_Invoke( + INetFwOpenPorts *iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS *pDispParams, + VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, + UINT *puArgErr ) +{ + fw_ports *This = impl_from_INetFwOpenPorts( iface ); + + FIXME("%p %d %s %d %d %p %p %p %p\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_ports_get_Count( + INetFwOpenPorts *iface, + LONG *count) +{ + fw_ports *This = impl_from_INetFwOpenPorts( iface ); + + FIXME("%p, %p\n", This, count); + + *count = 0; + return S_OK; +} + +static HRESULT WINAPI fw_ports_Add( + INetFwOpenPorts *iface, + INetFwOpenPort *port) +{ + fw_ports *This = impl_from_INetFwOpenPorts( iface ); + + FIXME("%p, %p\n", This, port); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_ports_Remove( + INetFwOpenPorts *iface, + LONG portNumber, + NET_FW_IP_PROTOCOL ipProtocol) +{ + fw_ports *This = impl_from_INetFwOpenPorts( iface ); + + FIXME("%p, %d, %u\n", This, portNumber, ipProtocol); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_ports_Item( + INetFwOpenPorts *iface, + LONG portNumber, + NET_FW_IP_PROTOCOL ipProtocol, + INetFwOpenPort **openPort) +{ + HRESULT hr; + fw_ports *This = impl_from_INetFwOpenPorts( iface ); + + FIXME("%p, %d, %u, %p\n", This, portNumber, ipProtocol, openPort); + + hr = NetFwOpenPort_create( NULL, (void **)openPort ); + if (SUCCEEDED(hr)) + { + INetFwOpenPort_put_Protocol( *openPort, ipProtocol ); + INetFwOpenPort_put_Port( *openPort, portNumber ); + } + return hr; +} + +static HRESULT WINAPI fw_ports_get__NewEnum( + INetFwOpenPorts *iface, + IUnknown **newEnum) +{ + fw_ports *This = impl_from_INetFwOpenPorts( iface ); + + FIXME("%p, %p\n", This, newEnum); + return E_NOTIMPL; +} + +static const struct INetFwOpenPortsVtbl fw_ports_vtbl = +{ + fw_ports_QueryInterface, + fw_ports_AddRef, + fw_ports_Release, + fw_ports_GetTypeInfoCount, + fw_ports_GetTypeInfo, + fw_ports_GetIDsOfNames, + fw_ports_Invoke, + fw_ports_get_Count, + fw_ports_Add, + fw_ports_Remove, + fw_ports_Item, + fw_ports_get__NewEnum +}; + +HRESULT NetFwOpenPorts_create( IUnknown *pUnkOuter, LPVOID *ppObj ) +{ + fw_ports *fp; + + TRACE("(%p,%p)\n", pUnkOuter, ppObj); + + fp = HeapAlloc( GetProcessHeap(), 0, sizeof(*fp) ); + if (!fp) return E_OUTOFMEMORY; + + fp->vtbl = &fw_ports_vtbl; + fp->refs = 1; + + *ppObj = &fp->vtbl; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} diff --git a/reactos/dll/win32/hnetcfg/profile.c b/reactos/dll/win32/hnetcfg/profile.c index 91c73afbf21..8536bd7ce69 100644 --- a/reactos/dll/win32/hnetcfg/profile.c +++ b/reactos/dll/win32/hnetcfg/profile.c @@ -261,8 +261,8 @@ static HRESULT WINAPI fw_profile_get_GloballyOpenPorts( { fw_profile *This = impl_from_INetFwProfile( iface ); - FIXME("%p, %p\n", This, openPorts); - return E_NOTIMPL; + TRACE("%p, %p\n", This, openPorts); + return NetFwOpenPorts_create( NULL, (void **)openPorts ); } static HRESULT WINAPI fw_profile_get_Services( @@ -271,8 +271,8 @@ static HRESULT WINAPI fw_profile_get_Services( { fw_profile *This = impl_from_INetFwProfile( iface ); - FIXME("%p, %p\n", This, Services); - return E_NOTIMPL; + TRACE("%p, %p\n", This, Services); + return NetFwServices_create( NULL, (void **)Services ); } static HRESULT WINAPI fw_profile_get_AuthorizedApplications( diff --git a/reactos/dll/win32/hnetcfg/regsvr.c b/reactos/dll/win32/hnetcfg/regsvr.c index e739cc0b76d..829590a3f9a 100644 --- a/reactos/dll/win32/hnetcfg/regsvr.c +++ b/reactos/dll/win32/hnetcfg/regsvr.c @@ -400,7 +400,7 @@ static struct regsvr_interface const interface_list[] = { }; /*********************************************************************** - * DllRegisterServer (INETCOMM.@) + * DllRegisterServer (HNETCFG.@) */ HRESULT WINAPI DllRegisterServer(void) { @@ -415,7 +415,7 @@ HRESULT WINAPI DllRegisterServer(void) } /*********************************************************************** - * DllUnregisterServer (INETCOMM.@) + * DllUnregisterServer (HNETCFG.@) */ HRESULT WINAPI DllUnregisterServer(void) { diff --git a/reactos/dll/win32/hnetcfg/service.c b/reactos/dll/win32/hnetcfg/service.c new file mode 100644 index 00000000000..ecfc00cba25 --- /dev/null +++ b/reactos/dll/win32/hnetcfg/service.c @@ -0,0 +1,479 @@ +/* + * Copyright 2009 Hans Leidekker 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 "config.h" +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "ole2.h" +#include "netfw.h" + +#include "wine/debug.h" +#include "wine/unicode.h" +#include "hnetcfg_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(hnetcfg); + +typedef struct fw_service +{ + const INetFwServiceVtbl *vtbl; + LONG refs; +} fw_service; + +static inline fw_service *impl_from_INetFwService( INetFwService *iface ) +{ + return (fw_service *)((char *)iface - FIELD_OFFSET( fw_service, vtbl )); +} + +static ULONG WINAPI fw_service_AddRef( + INetFwService *iface ) +{ + fw_service *fw_service = impl_from_INetFwService( iface ); + return InterlockedIncrement( &fw_service->refs ); +} + +static ULONG WINAPI fw_service_Release( + INetFwService *iface ) +{ + fw_service *fw_service = impl_from_INetFwService( iface ); + LONG refs = InterlockedDecrement( &fw_service->refs ); + if (!refs) + { + TRACE("destroying %p\n", fw_service); + HeapFree( GetProcessHeap(), 0, fw_service ); + } + return refs; +} + +static HRESULT WINAPI fw_service_QueryInterface( + INetFwService *iface, + REFIID riid, + void **ppvObject ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_INetFwService ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + INetFwService_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI fw_service_GetTypeInfoCount( + INetFwService *iface, + UINT *pctinfo ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %p\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_GetTypeInfo( + INetFwService *iface, + UINT iTInfo, + LCID lcid, + ITypeInfo **ppTInfo ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %u %u %p\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_GetIDsOfNames( + INetFwService *iface, + REFIID riid, + LPOLESTR *rgszNames, + UINT cNames, + LCID lcid, + DISPID *rgDispId ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %s %p %u %u %p\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_Invoke( + INetFwService *iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS *pDispParams, + VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, + UINT *puArgErr ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %d %s %d %d %p %p %p %p\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_get_Name( + INetFwService *iface, + BSTR *name ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %p\n", This, name); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_get_Type( + INetFwService *iface, + NET_FW_SERVICE_TYPE *type ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %p\n", This, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_get_Customized( + INetFwService *iface, + VARIANT_BOOL *customized ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %p\n", This, customized); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_get_IpVersion( + INetFwService *iface, + NET_FW_IP_VERSION *ipVersion ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %p\n", This, ipVersion); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_put_IpVersion( + INetFwService *iface, + NET_FW_IP_VERSION ipVersion ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %u\n", This, ipVersion); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_get_Scope( + INetFwService *iface, + NET_FW_SCOPE *scope ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %p\n", This, scope); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_put_Scope( + INetFwService *iface, + NET_FW_SCOPE scope ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %u\n", This, scope); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_get_RemoteAddresses( + INetFwService *iface, + BSTR *remoteAddrs ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %p\n", This, remoteAddrs); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_put_RemoteAddresses( + INetFwService *iface, + BSTR remoteAddrs ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %s\n", This, debugstr_w(remoteAddrs)); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_get_Enabled( + INetFwService *iface, + VARIANT_BOOL *enabled ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %p\n", This, enabled); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_put_Enabled( + INetFwService *iface, + VARIANT_BOOL enabled ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + FIXME("%p %d\n", This, enabled); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_service_get_GloballyOpenPorts( + INetFwService *iface, + INetFwOpenPorts **openPorts ) +{ + fw_service *This = impl_from_INetFwService( iface ); + + TRACE("%p %p\n", This, openPorts); + return NetFwOpenPorts_create( NULL, (void **)openPorts ); +} + +static const struct INetFwServiceVtbl fw_service_vtbl = +{ + fw_service_QueryInterface, + fw_service_AddRef, + fw_service_Release, + fw_service_GetTypeInfoCount, + fw_service_GetTypeInfo, + fw_service_GetIDsOfNames, + fw_service_Invoke, + fw_service_get_Name, + fw_service_get_Type, + fw_service_get_Customized, + fw_service_get_IpVersion, + fw_service_put_IpVersion, + fw_service_get_Scope, + fw_service_put_Scope, + fw_service_get_RemoteAddresses, + fw_service_put_RemoteAddresses, + fw_service_get_Enabled, + fw_service_put_Enabled, + fw_service_get_GloballyOpenPorts +}; + +static HRESULT NetFwService_create( IUnknown *pUnkOuter, LPVOID *ppObj ) +{ + fw_service *fp; + + TRACE("(%p,%p)\n", pUnkOuter, ppObj); + + fp = HeapAlloc( GetProcessHeap(), 0, sizeof(*fp) ); + if (!fp) return E_OUTOFMEMORY; + + fp->vtbl = &fw_service_vtbl; + fp->refs = 1; + + *ppObj = &fp->vtbl; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} + +typedef struct fw_services +{ + const INetFwServicesVtbl *vtbl; + LONG refs; +} fw_services; + +static inline fw_services *impl_from_INetFwServices( INetFwServices *iface ) +{ + return (fw_services *)((char *)iface - FIELD_OFFSET( fw_services, vtbl )); +} + +static ULONG WINAPI fw_services_AddRef( + INetFwServices *iface ) +{ + fw_services *fw_services = impl_from_INetFwServices( iface ); + return InterlockedIncrement( &fw_services->refs ); +} + +static ULONG WINAPI fw_services_Release( + INetFwServices *iface ) +{ + fw_services *fw_services = impl_from_INetFwServices( iface ); + LONG refs = InterlockedDecrement( &fw_services->refs ); + if (!refs) + { + TRACE("destroying %p\n", fw_services); + HeapFree( GetProcessHeap(), 0, fw_services ); + } + return refs; +} + +static HRESULT WINAPI fw_services_QueryInterface( + INetFwServices *iface, + REFIID riid, + void **ppvObject ) +{ + fw_services *This = impl_from_INetFwServices( iface ); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_INetFwServices ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + INetFwServices_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI fw_services_GetTypeInfoCount( + INetFwServices *iface, + UINT *pctinfo ) +{ + fw_services *This = impl_from_INetFwServices( iface ); + + FIXME("%p %p\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_services_GetTypeInfo( + INetFwServices *iface, + UINT iTInfo, + LCID lcid, + ITypeInfo **ppTInfo ) +{ + fw_services *This = impl_from_INetFwServices( iface ); + + FIXME("%p %u %u %p\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_services_GetIDsOfNames( + INetFwServices *iface, + REFIID riid, + LPOLESTR *rgszNames, + UINT cNames, + LCID lcid, + DISPID *rgDispId ) +{ + fw_services *This = impl_from_INetFwServices( iface ); + + FIXME("%p %s %p %u %u %p\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_services_Invoke( + INetFwServices *iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS *pDispParams, + VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, + UINT *puArgErr ) +{ + fw_services *This = impl_from_INetFwServices( iface ); + + FIXME("%p %d %s %d %d %p %p %p %p\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_NOTIMPL; +} + +static HRESULT WINAPI fw_services_get_Count( + INetFwServices *iface, + LONG *count ) +{ + fw_services *This = impl_from_INetFwServices( iface ); + + FIXME("%p, %p\n", This, count); + + *count = 0; + return S_OK; +} + +static HRESULT WINAPI fw_services_Item( + INetFwServices *iface, + NET_FW_SERVICE_TYPE svcType, + INetFwService **service ) +{ + fw_services *This = impl_from_INetFwServices( iface ); + + FIXME("%p, %u, %p\n", This, svcType, service); + return NetFwService_create( NULL, (void **)service ); +} + +static HRESULT WINAPI fw_services_get__NewEnum( + INetFwServices *iface, + IUnknown **newEnum ) +{ + fw_services *This = impl_from_INetFwServices( iface ); + + FIXME("%p, %p\n", This, newEnum); + return E_NOTIMPL; +} + +static const struct INetFwServicesVtbl fw_services_vtbl = +{ + fw_services_QueryInterface, + fw_services_AddRef, + fw_services_Release, + fw_services_GetTypeInfoCount, + fw_services_GetTypeInfo, + fw_services_GetIDsOfNames, + fw_services_Invoke, + fw_services_get_Count, + fw_services_Item, + fw_services_get__NewEnum +}; + +HRESULT NetFwServices_create( IUnknown *pUnkOuter, LPVOID *ppObj ) +{ + fw_services *fp; + + TRACE("(%p,%p)\n", pUnkOuter, ppObj); + + fp = HeapAlloc( GetProcessHeap(), 0, sizeof(*fp) ); + if (!fp) return E_OUTOFMEMORY; + + fp->vtbl = &fw_services_vtbl; + fp->refs = 1; + + *ppObj = &fp->vtbl; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} diff --git a/reactos/dll/win32/initpki/initpki.spec b/reactos/dll/win32/initpki/initpki.spec index 51d80bc8ea3..e9db624e78a 100644 --- a/reactos/dll/win32/initpki/initpki.spec +++ b/reactos/dll/win32/initpki/initpki.spec @@ -1,4 +1,4 @@ @ stub DllInstall -@ stub DllRegisterServer -@ stub DllUnregisterServer +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() @ stub InitializePKI diff --git a/reactos/dll/win32/initpki/main.c b/reactos/dll/win32/initpki/main.c index d936dd819de..caa00365649 100644 --- a/reactos/dll/win32/initpki/main.c +++ b/reactos/dll/win32/initpki/main.c @@ -44,3 +44,21 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) } return TRUE; } + +/***************************************************** + * DllRegisterServer (INITPKI.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + FIXME("Not implemented.\n"); + return E_UNEXPECTED; +} + +/***************************************************** + * DllUnregisterServer (INITPKI.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + FIXME("Not implemented.\n"); + return E_UNEXPECTED; +} diff --git a/reactos/dll/win32/localspl/localspl.rc b/reactos/dll/win32/localspl/localspl.rc index 71c1e4604b9..baaba648f02 100644 --- a/reactos/dll/win32/localspl/localspl.rc +++ b/reactos/dll/win32/localspl/localspl.rc @@ -36,17 +36,21 @@ #include "wine/wine_common_ver.rc" -#include "spl_En.rc" #include "spl_Da.rc" -#include "spl_De.rc" +#include "spl_En.rc" #include "spl_Fr.rc" #include "spl_Ko.rc" #include "spl_Nl.rc" #include "spl_No.rc" #include "spl_Pl.rc" #include "spl_Pt.rc" +#include "spl_Sv.rc" + +/* UTF-8 */ +#include "spl_De.rc" +#include "spl_Es.rc" +#include "spl_Lt.rc" #include "spl_Ro.rc" #include "spl_Ru.rc" #include "spl_Si.rc" -#include "spl_Sv.rc" #include "spl_Zh.rc" diff --git a/reactos/dll/win32/localspl/localspl_private.h b/reactos/dll/win32/localspl/localspl_private.h index 5174a1a847e..952c1f6652d 100644 --- a/reactos/dll/win32/localspl/localspl_private.h +++ b/reactos/dll/win32/localspl/localspl_private.h @@ -21,6 +21,7 @@ #ifndef __WINE_LOCALSPL_PRIVATE__ #define __WINE_LOCALSPL_PRIVATE__ +#include /* ## DLL-wide Globals ## */ extern HINSTANCE LOCALSPL_hInstance; diff --git a/reactos/dll/win32/localspl/provider.c b/reactos/dll/win32/localspl/provider.c index 79541db9937..b17e074b845 100644 --- a/reactos/dll/win32/localspl/provider.c +++ b/reactos/dll/win32/localspl/provider.c @@ -103,14 +103,23 @@ static const WCHAR default_devmodeW[] = {'D','e','f','a','u','l','t',' ','D','e' static const WCHAR dependent_filesW[] = {'D','e','p','e','n','d','e','n','t',' ','F','i','l','e','s',0}; static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0}; static const WCHAR driverW[] = {'D','r','i','v','e','r',0}; +static const WCHAR emptyW[] = {0}; static const WCHAR fmt_driversW[] = { 'S','y','s','t','e','m','\\', 'C','u', 'r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', 'c','o','n','t','r','o','l','\\', 'P','r','i','n','t','\\', 'E','n','v','i','r','o','n','m','e','n','t','s','\\', '%','s','\\','D','r','i','v','e','r','s','%','s',0 }; +static const WCHAR fmt_printprocessorsW[] = { 'S','y','s','t','e','m','\\', + 'C','u', 'r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', + 'C','o','n','t','r','o','l','\\', + 'P','r','i','n','t','\\', + 'E','n','v','i','r','o','n','m','e','n','t','s','\\','%','s','\\', + 'P','r','i','n','t',' ','P','r','o','c','e','s','s','o','r','s',0 }; static const WCHAR hardwareidW[] = {'H','a','r','d','w','a','r','e','I','D',0}; static const WCHAR help_fileW[] = {'H','e','l','p',' ','F','i','l','e',0}; +static const WCHAR ia64_envnameW[] = {'W','i','n','d','o','w','s',' ','I','A','6','4',0}; +static const WCHAR ia64_subdirW[] = {'i','a','6','4',0}; static const WCHAR localportW[] = {'L','o','c','a','l',' ','P','o','r','t',0}; static const WCHAR locationW[] = {'L','o','c','a','t','i','o','n',0}; static const WCHAR manufacturerW[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0}; @@ -132,6 +141,7 @@ static const WCHAR printersW[] = {'S','y','s','t','e','m','\\', 'P','r','i','n','t','\\', 'P','r','i','n','t','e','r','s',0}; static const WCHAR spooldriversW[] = {'\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\',0}; +static const WCHAR spoolprtprocsW[] = {'\\','s','p','o','o','l','\\','p','r','t','p','r','o','c','s','\\',0}; static const WCHAR version0_regpathW[] = {'\\','V','e','r','s','i','o','n','-','0',0}; static const WCHAR version0_subdirW[] = {'\\','0',0}; static const WCHAR version3_regpathW[] = {'\\','V','e','r','s','i','o','n','-','3',0}; @@ -144,6 +154,7 @@ static const WCHAR winnt_cv_portsW[] = {'S','o','f','t','w','a','r','e','\\', 'W','i','n','d','o','w','s',' ','N','T','\\', 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 'P','o','r','t','s',0}; +static const WCHAR winprintW[] = {'w','i','n','p','r','i','n','t',0}; static const WCHAR x64_envnameW[] = {'W','i','n','d','o','w','s',' ','x','6','4',0}; static const WCHAR x64_subdirW[] = {'x','6','4',0}; static const WCHAR x86_envnameW[] = {'W','i','n','d','o','w','s',' ','N','T',' ','x','8','6',0}; @@ -152,6 +163,9 @@ static const WCHAR XcvMonitorW[] = {',','X','c','v','M','o','n','i','t','o','r', static const WCHAR XcvPortW[] = {',','X','c','v','P','o','r','t',' ',0}; +static const printenv_t env_ia64 = {ia64_envnameW, ia64_subdirW, 3, + version3_regpathW, version3_subdirW}; + static const printenv_t env_x86 = {x86_envnameW, x86_subdirW, 3, version3_regpathW, version3_subdirW}; @@ -161,7 +175,7 @@ static const printenv_t env_x64 = {x64_envnameW, x64_subdirW, 3, static const printenv_t env_win40 = {win40_envnameW, win40_subdirW, 0, version0_regpathW, version0_subdirW}; -static const printenv_t * const all_printenv[] = {&env_x86, &env_x64, &env_win40}; +static const printenv_t * const all_printenv[] = {&env_x86, &env_x64, &env_ia64, &env_win40}; static const DWORD di_sizeof[] = {0, sizeof(DRIVER_INFO_1W), sizeof(DRIVER_INFO_2W), @@ -184,7 +198,7 @@ static LPWSTR strdupW(LPCWSTR p) if(!p) return NULL; len = (lstrlenW(p) + 1) * sizeof(WCHAR); ret = heap_alloc(len); - memcpy(ret, p, len); + if (ret) memcpy(ret, p, len); return ret; } @@ -345,7 +359,7 @@ static void monitor_unload(monitor_t * pm) /****************************************************************** * monitor_unloadall [internal] * - * release all printmonitors and unload them from memory, when needed + * release all registered printmonitors and unload them from memory, when needed * */ @@ -358,7 +372,8 @@ static void monitor_unloadall(void) /* iterate through the list, with safety against removal */ LIST_FOR_EACH_ENTRY_SAFE(pm, next, &monitor_handles, monitor_t, entry) { - monitor_unload(pm); + /* skip monitorui dlls */ + if (pm->monitor) monitor_unload(pm); } LeaveCriticalSection(&monitor_handles_cs); } @@ -556,6 +571,47 @@ static DWORD monitor_loadall(void) return loaded; } +/****************************************************************** + * monitor_loadui [internal] + * + * load the userinterface-dll for a given portmonitor + * + * On failure, NULL is returned + */ +static monitor_t * monitor_loadui(monitor_t * pm) +{ + monitor_t * pui = NULL; + WCHAR buffer[MAX_PATH]; + HANDLE hXcv; + DWORD len; + DWORD res; + + if (pm == NULL) return NULL; + TRACE("(%p) => dllname: %s\n", pm, debugstr_w(pm->dllname)); + + /* Try the Portmonitor first; works for many monitors */ + if (pm->monitorUI) { + EnterCriticalSection(&monitor_handles_cs); + pm->refcount++; + LeaveCriticalSection(&monitor_handles_cs); + return pm; + } + + /* query the userinterface-dllname from the Portmonitor */ + if ((pm->monitor) && (pm->monitor->pfnXcvDataPort)) { + /* building (",XcvMonitor %s",pm->name) not needed yet */ + res = pm->monitor->pfnXcvOpenPort(emptyW, SERVER_ACCESS_ADMINISTER, &hXcv); + TRACE("got %u with %p\n", res, hXcv); + if (res) { + res = pm->monitor->pfnXcvDataPort(hXcv, monitorUIW, NULL, 0, (BYTE *) buffer, sizeof(buffer), &len); + TRACE("got %u with %s\n", res, debugstr_w(buffer)); + if (res == ERROR_SUCCESS) pui = monitor_load(NULL, buffer); + pm->monitor->pfnXcvClosePort(hXcv); + } + } + return pui; +} + /****************************************************************** * monitor_load_by_port [internal] * @@ -776,6 +832,92 @@ static DWORD get_local_monitors(DWORD level, LPBYTE pMonitors, DWORD cbBuf, LPDW return needed; } +/***************************************************************************** + * enumerate the local print processors (INTERNAL) + * + * returns the needed size (in bytes) for pPPInfo + * and *lpreturned is set to number of entries returned in pPPInfo + * + */ +static DWORD get_local_printprocessors(LPWSTR regpathW, LPBYTE pPPInfo, DWORD cbBuf, LPDWORD lpreturned) +{ + HKEY hroot = NULL; + HKEY hentry = NULL; + LPWSTR ptr; + PPRINTPROCESSOR_INFO_1W ppi; + WCHAR buffer[MAX_PATH]; + WCHAR dllname[MAX_PATH]; + DWORD dllsize; + DWORD len; + DWORD index = 0; + DWORD needed = 0; + DWORD numentries; + + numentries = *lpreturned; /* this is 0, when we scan the registry */ + len = numentries * sizeof(PRINTPROCESSOR_INFO_1W); + ptr = (LPWSTR) &pPPInfo[len]; + + numentries = 0; + len = sizeof(buffer)/sizeof(buffer[0]); + buffer[0] = '\0'; + + if (RegCreateKeyW(HKEY_LOCAL_MACHINE, regpathW, &hroot) == ERROR_SUCCESS) { + /* add "winprint" first */ + numentries++; + needed = sizeof(PRINTPROCESSOR_INFO_1W) + sizeof(winprintW); + if (pPPInfo && (cbBuf >= needed)){ + ppi = (PPRINTPROCESSOR_INFO_1W) pPPInfo; + pPPInfo += sizeof(PRINTPROCESSOR_INFO_1W); + + TRACE("%p: writing PRINTPROCESSOR_INFO_1W #%d\n", ppi, numentries); + ppi->pName = ptr; + lstrcpyW(ptr, winprintW); /* Name of the Print Processor */ + ptr += sizeof(winprintW) / sizeof(WCHAR); + } + + /* Scan all Printprocessor Keys */ + while ((RegEnumKeyExW(hroot, index, buffer, &len, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) && + (lstrcmpiW(buffer, winprintW) != 0)) { + TRACE("PrintProcessor_%d: %s\n", numentries, debugstr_w(buffer)); + dllsize = sizeof(dllname); + dllname[0] = '\0'; + + /* The Print Processor must have a Driver-DLL */ + if (RegOpenKeyExW(hroot, buffer, 0, KEY_READ, &hentry) == ERROR_SUCCESS) { + if (RegQueryValueExW(hentry, driverW, NULL, NULL, (LPBYTE) dllname, &dllsize) == ERROR_SUCCESS) { + /* We found a valid DLL for this Print Processor */ + TRACE("using Driver: %s\n", debugstr_w(dllname)); + } + RegCloseKey(hentry); + } + + if (dllname[0]) { + numentries++; + needed += sizeof(PRINTPROCESSOR_INFO_1W); + needed += (len+1) * sizeof(WCHAR); /* len is lstrlenW(printprocessor name) */ + + /* required size is calculated. Now fill the user-buffer */ + if (pPPInfo && (cbBuf >= needed)){ + ppi = (PPRINTPROCESSOR_INFO_1W) pPPInfo; + pPPInfo += sizeof(PRINTPROCESSOR_INFO_1W); + + TRACE("%p: writing PRINTPROCESSOR_INFO_1W #%d\n", ppi, numentries); + ppi->pName = ptr; + lstrcpyW(ptr, buffer); /* Name of the Print Processor */ + ptr += (len+1); /* len is lstrlenW(printprosessor name) */ + } + } + index++; + len = sizeof(buffer)/sizeof(buffer[0]); + buffer[0] = '\0'; + } + RegCloseKey(hroot); + } + *lpreturned = numentries; + TRACE("need %d byte for %d entries\n", needed, numentries); + return needed; +} + /****************************************************************** * enumerate the local Ports from all loaded monitors (internal) * @@ -1152,7 +1294,6 @@ end: */ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCopyFlags, BOOL lazy) { - static const WCHAR emptyW[1]; const printenv_t *env; apd_data_t apd; DRIVER_INFO_8W di; @@ -1415,6 +1556,136 @@ static BOOL WINAPI fpAddMonitor(LPWSTR pName, DWORD Level, LPBYTE pMonitors) return (res); } +/****************************************************************************** + * fpAddPort [exported through PRINTPROVIDOR] + * + * Add a Port for a specific Monitor + * + * PARAMS + * pName [I] Servername or NULL (local Computer) + * hWnd [I] Handle to parent Window for the Dialog-Box + * pMonitorName [I] Name of the Monitor that manage the Port + * + * RETURNS + * Success: TRUE + * Failure: FALSE + * + */ +static BOOL WINAPI fpAddPort(LPWSTR pName, HWND hWnd, LPWSTR pMonitorName) +{ + monitor_t * pm; + monitor_t * pui; + LONG lres; + DWORD res; + + TRACE("(%s, %p, %s)\n", debugstr_w(pName), hWnd, debugstr_w(pMonitorName)); + + lres = copy_servername_from_name(pName, NULL); + if (lres) { + FIXME("server %s not supported\n", debugstr_w(pName)); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + /* an empty Monitorname is Invalid */ + if (!pMonitorName[0]) { + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + + pm = monitor_load(pMonitorName, NULL); + if (pm && pm->monitor && pm->monitor->pfnAddPort) { + res = pm->monitor->pfnAddPort(pName, hWnd, pMonitorName); + TRACE("got %d with %u (%s)\n", res, GetLastError(), debugstr_w(pm->dllname)); + } + else + { + pui = monitor_loadui(pm); + if (pui && pui->monitorUI && pui->monitorUI->pfnAddPortUI) { + res = pui->monitorUI->pfnAddPortUI(pName, hWnd, pMonitorName, NULL); + TRACE("got %d with %u (%s)\n", res, GetLastError(), debugstr_w(pui->dllname)); + } + else + { + FIXME("not implemented for %s (monitor %p: %s / monitorui %p: %s)\n", + debugstr_w(pMonitorName), pm, debugstr_w(pm ? pm->dllname : NULL), + pui, debugstr_w(pui ? pui->dllname : NULL)); + + SetLastError(ERROR_NOT_SUPPORTED); + res = FALSE; + } + monitor_unload(pui); + } + monitor_unload(pm); + + TRACE("returning %d with %u\n", res, GetLastError()); + return res; +} + +/****************************************************************************** + * fpAddPortEx [exported through PRINTPROVIDOR] + * + * Add a Port for a specific Monitor, without presenting a user interface + * + * PARAMS + * pName [I] Servername or NULL (local Computer) + * level [I] Structure-Level (1 or 2) for pBuffer + * pBuffer [I] PTR to: PORT_INFO_1 or PORT_INFO_2 + * pMonitorName [I] Name of the Monitor that manage the Port + * + * RETURNS + * Success: TRUE + * Failure: FALSE + * + */ +static BOOL WINAPI fpAddPortEx(LPWSTR pName, DWORD level, LPBYTE pBuffer, LPWSTR pMonitorName) +{ + PORT_INFO_2W * pi2; + monitor_t * pm; + DWORD lres; + DWORD res; + + pi2 = (PORT_INFO_2W *) pBuffer; + + TRACE("(%s, %d, %p, %s): %s %s %s\n", debugstr_w(pName), level, pBuffer, + debugstr_w(pMonitorName), debugstr_w(pi2 ? pi2->pPortName : NULL), + debugstr_w(((level > 1) && pi2) ? pi2->pMonitorName : NULL), + debugstr_w(((level > 1) && pi2) ? pi2->pDescription : NULL)); + + lres = copy_servername_from_name(pName, NULL); + if (lres) { + FIXME("server %s not supported\n", debugstr_w(pName)); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if ((level < 1) || (level > 2)) { + SetLastError(ERROR_INVALID_LEVEL); + return FALSE; + } + + if ((!pi2) || (!pMonitorName) || (!pMonitorName[0])) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + /* load the Monitor */ + pm = monitor_load(pMonitorName, NULL); + if (pm && pm->monitor && pm->monitor->pfnAddPortEx) { + res = pm->monitor->pfnAddPortEx(pName, level, pBuffer, pMonitorName); + TRACE("got %d with %u (%s)\n", res, GetLastError(), debugstr_w(pm->dllname)); + } + else + { + FIXME("not implemented for %s (monitor %p: %s)\n", + debugstr_w(pMonitorName), pm, pm ? debugstr_w(pm->dllname) : NULL); + SetLastError(ERROR_INVALID_PARAMETER); + res = FALSE; + } + monitor_unload(pm); + return res; +} + /****************************************************************************** * fpAddPrinterDriverEx [exported through PRINTPROVIDOR] * @@ -1476,6 +1747,75 @@ static BOOL WINAPI fpClosePrinter(HANDLE hPrinter) return FALSE; } +/****************************************************************************** + * fpConfigurePort [exported through PRINTPROVIDOR] + * + * Display the Configuration-Dialog for a specific Port + * + * PARAMS + * pName [I] Servername or NULL (local Computer) + * hWnd [I] Handle to parent Window for the Dialog-Box + * pPortName [I] Name of the Port, that should be configured + * + * RETURNS + * Success: TRUE + * Failure: FALSE + * + */ +static BOOL WINAPI fpConfigurePort(LPWSTR pName, HWND hWnd, LPWSTR pPortName) +{ + monitor_t * pm; + monitor_t * pui; + LONG lres; + DWORD res; + + TRACE("(%s, %p, %s)\n", debugstr_w(pName), hWnd, debugstr_w(pPortName)); + + lres = copy_servername_from_name(pName, NULL); + if (lres) { + FIXME("server %s not supported\n", debugstr_w(pName)); + SetLastError(ERROR_INVALID_NAME); + return FALSE; + } + + /* an empty Portname is Invalid, but can popup a Dialog */ + if (!pPortName[0]) { + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + + pm = monitor_load_by_port(pPortName); + if (pm && pm->monitor && pm->monitor->pfnConfigurePort) { + TRACE("use %s for %s (monitor %p: %s)\n", debugstr_w(pm->name), + debugstr_w(pPortName), pm, debugstr_w(pm->dllname)); + res = pm->monitor->pfnConfigurePort(pName, hWnd, pPortName); + TRACE("got %d with %u\n", res, GetLastError()); + } + else + { + pui = monitor_loadui(pm); + if (pui && pui->monitorUI && pui->monitorUI->pfnConfigurePortUI) { + TRACE("use %s for %s (monitorui %p: %s)\n", debugstr_w(pui->name), + debugstr_w(pPortName), pui, debugstr_w(pui->dllname)); + res = pui->monitorUI->pfnConfigurePortUI(pName, hWnd, pPortName); + TRACE("got %d with %u\n", res, GetLastError()); + } + else + { + FIXME("not implemented for %s (monitor %p: %s / monitorui %p: %s)\n", + debugstr_w(pPortName), pm, debugstr_w(pm ? pm->dllname : NULL), + pui, debugstr_w(pui ? pui->dllname : NULL)); + + SetLastError(ERROR_NOT_SUPPORTED); + res = FALSE; + } + monitor_unload(pui); + } + monitor_unload(pm); + + TRACE("returning %d with %u\n", res, GetLastError()); + return res; +} /****************************************************************** * fpDeleteMonitor [exported through PRINTPROVIDOR] @@ -1537,6 +1877,76 @@ static BOOL WINAPI fpDeleteMonitor(LPWSTR pName, LPWSTR pEnvironment, LPWSTR pMo return FALSE; } +/***************************************************************************** + * fpDeletePort [exported through PRINTPROVIDOR] + * + * Delete a specific Port + * + * PARAMS + * pName [I] Servername or NULL (local Computer) + * hWnd [I] Handle to parent Window for the Dialog-Box + * pPortName [I] Name of the Port, that should be deleted + * + * RETURNS + * Success: TRUE + * Failure: FALSE + * + */ +static BOOL WINAPI fpDeletePort(LPWSTR pName, HWND hWnd, LPWSTR pPortName) +{ + monitor_t * pm; + monitor_t * pui; + LONG lres; + DWORD res; + + TRACE("(%s, %p, %s)\n", debugstr_w(pName), hWnd, debugstr_w(pPortName)); + + lres = copy_servername_from_name(pName, NULL); + if (lres) { + FIXME("server %s not supported\n", debugstr_w(pName)); + SetLastError(ERROR_INVALID_NAME); + return FALSE; + } + + /* an empty Portname is Invalid */ + if (!pPortName[0]) { + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + + pm = monitor_load_by_port(pPortName); + if (pm && pm->monitor && pm->monitor->pfnDeletePort) { + TRACE("use %s for %s (monitor %p: %s)\n", debugstr_w(pm->name), + debugstr_w(pPortName), pm, debugstr_w(pm->dllname)); + res = pm->monitor->pfnDeletePort(pName, hWnd, pPortName); + TRACE("got %d with %u\n", res, GetLastError()); + } + else + { + pui = monitor_loadui(pm); + if (pui && pui->monitorUI && pui->monitorUI->pfnDeletePortUI) { + TRACE("use %s for %s (monitorui %p: %s)\n", debugstr_w(pui->name), + debugstr_w(pPortName), pui, debugstr_w(pui->dllname)); + res = pui->monitorUI->pfnDeletePortUI(pName, hWnd, pPortName); + TRACE("got %d with %u\n", res, GetLastError()); + } + else + { + FIXME("not implemented for %s (monitor %p: %s / monitorui %p: %s)\n", + debugstr_w(pPortName), pm, debugstr_w(pm ? pm->dllname : NULL), + pui, debugstr_w(pui ? pui->dllname : NULL)); + + SetLastError(ERROR_NOT_SUPPORTED); + res = FALSE; + } + monitor_unload(pui); + } + monitor_unload(pm); + + TRACE("returning %d with %u\n", res, GetLastError()); + return res; +} + /***************************************************************************** * fpEnumMonitors [exported through PRINTPROVIDOR] * @@ -1689,6 +2099,156 @@ emP_cleanup: return (res); } +/***************************************************************************** + * fpEnumPrintProcessors [exported through PRINTPROVIDOR] + * + * Enumerate available Print Processors + * + * PARAMS + * pName [I] Servername or NULL (local Computer) + * pEnvironment [I] Printing-Environment or NULL (Default) + * Level [I] Structure-Level (Only 1 is allowed) + * pPPInfo [O] PTR to Buffer that receives the Result + * cbBuf [I] Size of Buffer at pMonitors + * pcbNeeded [O] PTR to DWORD that receives the size in Bytes used / required for pPPInfo + * pcReturned [O] PTR to DWORD that receives the number of Print Processors in pPPInfo + * + * RETURNS + * Success: TRUE + * Failure: FALSE and in pcbNeeded the Bytes required for pPPInfo, if cbBuf is too small + * + */ +static BOOL WINAPI fpEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, + LPBYTE pPPInfo, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned) +{ + const printenv_t * env; + LPWSTR regpathW = NULL; + DWORD numentries = 0; + DWORD needed = 0; + LONG lres; + BOOL res = FALSE; + + TRACE("(%s, %s, %d, %p, %d, %p, %p)\n", debugstr_w(pName), debugstr_w(pEnvironment), + Level, pPPInfo, cbBuf, pcbNeeded, pcReturned); + + lres = copy_servername_from_name(pName, NULL); + if (lres) { + FIXME("server %s not supported\n", debugstr_w(pName)); + SetLastError(ERROR_INVALID_NAME); + goto epp_cleanup; + } + + if (Level != 1) { + SetLastError(ERROR_INVALID_LEVEL); + goto epp_cleanup; + } + + env = validate_envW(pEnvironment); + if (!env) + goto epp_cleanup; /* ERROR_INVALID_ENVIRONMENT */ + + regpathW = heap_alloc(sizeof(fmt_printprocessorsW) + + (lstrlenW(env->envname) * sizeof(WCHAR))); + + if (!regpathW) + goto epp_cleanup; + + wsprintfW(regpathW, fmt_printprocessorsW, env->envname); + + /* Scan all Printprocessor-Keys */ + numentries = 0; + needed = get_local_printprocessors(regpathW, NULL, 0, &numentries); + + /* we calculated the needed buffersize. now do more error-checks */ + if (cbBuf < needed) { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + goto epp_cleanup; + } + + /* fill the Buffer with the Printprocessor Infos */ + needed = get_local_printprocessors(regpathW, pPPInfo, cbBuf, &numentries); + res = TRUE; + +epp_cleanup: + heap_free(regpathW); + if (pcbNeeded) *pcbNeeded = needed; + if (pcReturned) *pcReturned = numentries; + + TRACE("returning %d with %d (%d byte for %d entries)\n", + res, GetLastError(), needed, numentries); + + return (res); +} + +/****************************************************************************** + * fpGetPrintProcessorDirectory [exported through PRINTPROVIDOR] + * + * Return the PATH for the Print-Processors + * + * PARAMS + * pName [I] Servername or NULL (this computer) + * pEnvironment [I] Printing-Environment or NULL (Default) + * level [I] Structure-Level (must be 1) + * pPPInfo [O] PTR to Buffer that receives the Result + * cbBuf [I] Size of Buffer at pPPInfo + * pcbNeeded [O] PTR to DWORD that receives the size in Bytes used / required for pPPInfo + * + * RETURNS + * Success: TRUE + * Failure: FALSE and in pcbNeeded the Bytes required for pPPInfo, if cbBuf is too small + * + * Native Values returned in pPPInfo on Success for this computer: + *| NT(Windows x64): "%winsysdir%\\spool\\PRTPROCS\\x64" + *| NT(Windows NT x86): "%winsysdir%\\spool\\PRTPROCS\\w32x86" + *| NT(Windows 4.0): "%winsysdir%\\spool\\PRTPROCS\\win40" + * + * "%winsysdir%" is the Value from GetSystemDirectoryW() + * + */ +static BOOL WINAPI fpGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironment, DWORD level, + LPBYTE pPPInfo, DWORD cbBuf, LPDWORD pcbNeeded) +{ + const printenv_t * env; + DWORD needed; + LONG lres; + + TRACE("(%s, %s, %d, %p, %d, %p)\n", debugstr_w(pName), debugstr_w(pEnvironment), + level, pPPInfo, cbBuf, pcbNeeded); + + *pcbNeeded = 0; + lres = copy_servername_from_name(pName, NULL); + if (lres) { + FIXME("server %s not supported\n", debugstr_w(pName)); + SetLastError(RPC_S_SERVER_UNAVAILABLE); + return FALSE; + } + + env = validate_envW(pEnvironment); + if (!env) + return FALSE; /* ERROR_INVALID_ENVIRONMENT */ + + /* GetSystemDirectoryW returns number of WCHAR including the '\0' */ + needed = GetSystemDirectoryW(NULL, 0); + /* add the Size for the Subdirectories */ + needed += lstrlenW(spoolprtprocsW); + needed += lstrlenW(env->subdir); + needed *= sizeof(WCHAR); /* return-value is size in Bytes */ + + *pcbNeeded = needed; + + if (needed > cbBuf) { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + + GetSystemDirectoryW((LPWSTR) pPPInfo, cbBuf/sizeof(WCHAR)); + /* add the Subdirectories */ + lstrcatW((LPWSTR) pPPInfo, spoolprtprocsW); + lstrcatW((LPWSTR) pPPInfo, env->subdir); + TRACE("==> %s\n", debugstr_w((LPWSTR) pPPInfo)); + return TRUE; +} + /****************************************************************************** * fpOpenPrinter [exported through PRINTPROVIDOR] * @@ -1812,8 +2372,8 @@ void setup_provider(void) fpGetPrinterDriverDirectory, NULL, /* fpDeletePrinterDriver */ NULL, /* fpAddPrintProcessor */ - NULL, /* fpEnumPrintProcessors */ - NULL, /* fpGetPrintProcessorDirectory */ + fpEnumPrintProcessors, + fpGetPrintProcessorDirectory, NULL, /* fpDeletePrintProcessor */ NULL, /* fpEnumPrintProcessorDatatypes */ NULL, /* fpStartDocPrinter */ @@ -1836,9 +2396,9 @@ void setup_provider(void) NULL, /* fpEnumForms */ fpEnumMonitors, fpEnumPorts, - NULL, /* fpAddPort */ - NULL, /* fpConfigurePort */ - NULL, /* fpDeletePort */ + fpAddPort, + fpConfigurePort, + fpDeletePort, NULL, /* fpCreatePrinterIC */ NULL, /* fpPlayGdiScriptOnPrinterIC */ NULL, /* fpDeletePrinterIC */ @@ -1851,7 +2411,7 @@ void setup_provider(void) NULL, /* fpGetPrinterDriverEx */ NULL, /* fpFindFirstPrinterChangeNotification */ NULL, /* fpFindClosePrinterChangeNotification */ - NULL, /* fpAddPortEx */ + fpAddPortEx, NULL, /* fpShutDown */ NULL, /* fpRefreshPrinterChangeNotification */ NULL, /* fpOpenPrinterEx */ diff --git a/reactos/dll/win32/localspl/spl_Da.rc b/reactos/dll/win32/localspl/spl_Da.rc index a149cabc20a..cf1f3189904 100644 --- a/reactos/dll/win32/localspl/spl_Da.rc +++ b/reactos/dll/win32/localspl/spl_Da.rc @@ -18,7 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ - LANGUAGE LANG_DANISH, SUBLANG_DEFAULT +#include "localspl_private.h" + +LANGUAGE LANG_DANISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { diff --git a/reactos/dll/win32/localspl/spl_De.rc b/reactos/dll/win32/localspl/spl_De.rc index 4c95e2bcfa5..b30e13c903b 100644 --- a/reactos/dll/win32/localspl/spl_De.rc +++ b/reactos/dll/win32/localspl/spl_De.rc @@ -19,6 +19,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localspl_private.h" + +#pragma code_page(65001) + LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/localspl/spl_En.rc b/reactos/dll/win32/localspl/spl_En.rc index c9d12f4f16a..d189c26a132 100644 --- a/reactos/dll/win32/localspl/spl_En.rc +++ b/reactos/dll/win32/localspl/spl_En.rc @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localspl_private.h" + LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/localspl/spl_Es.rc b/reactos/dll/win32/localspl/spl_Es.rc new file mode 100644 index 00000000000..9b9a5580d64 --- /dev/null +++ b/reactos/dll/win32/localspl/spl_Es.rc @@ -0,0 +1,32 @@ +/* + * Spanish resources for localspl + * + * Copyright 2010 José Manuel Ferrer Ortiz + * + * 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 "localspl_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + IDS_LOCALPORT "Puerto local" + IDS_LOCALMONITOR "Monitor local" +} diff --git a/reactos/dll/win32/localspl/spl_Fr.rc b/reactos/dll/win32/localspl/spl_Fr.rc index 95269727162..0e93dc8b72b 100644 --- a/reactos/dll/win32/localspl/spl_Fr.rc +++ b/reactos/dll/win32/localspl/spl_Fr.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localspl_private.h" + LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/localspl/spl_Ko.rc b/reactos/dll/win32/localspl/spl_Ko.rc index fe2d5720a56..86db86797f6 100644 --- a/reactos/dll/win32/localspl/spl_Ko.rc +++ b/reactos/dll/win32/localspl/spl_Ko.rc @@ -20,6 +20,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localspl_private.h" + LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/localspl/spl_Lt.rc b/reactos/dll/win32/localspl/spl_Lt.rc new file mode 100644 index 00000000000..4c72767105d --- /dev/null +++ b/reactos/dll/win32/localspl/spl_Lt.rc @@ -0,0 +1,32 @@ +/* + * Lithuanian resources for localspl + * + * Copyright 2009 Aurimas FiÅ¡eras + * + * 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 "localspl_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + IDS_LOCALPORT "Vietinis prievadas" + IDS_LOCALMONITOR "Vietinis monitorius" +} diff --git a/reactos/dll/win32/localspl/spl_Nl.rc b/reactos/dll/win32/localspl/spl_Nl.rc index b9d4c5ca608..bd024469e80 100644 --- a/reactos/dll/win32/localspl/spl_Nl.rc +++ b/reactos/dll/win32/localspl/spl_Nl.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localspl_private.h" + LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/localspl/spl_No.rc b/reactos/dll/win32/localspl/spl_No.rc index 5efa5631e9b..b81a7b7d1ce 100644 --- a/reactos/dll/win32/localspl/spl_No.rc +++ b/reactos/dll/win32/localspl/spl_No.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localspl_private.h" + LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/localspl/spl_Pl.rc b/reactos/dll/win32/localspl/spl_Pl.rc index a0802088666..cdbb4226771 100644 --- a/reactos/dll/win32/localspl/spl_Pl.rc +++ b/reactos/dll/win32/localspl/spl_Pl.rc @@ -20,6 +20,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localspl_private.h" + LANGUAGE LANG_POLISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/localspl/spl_Pt.rc b/reactos/dll/win32/localspl/spl_Pt.rc index 8ec66c55f36..79506c34dc2 100644 --- a/reactos/dll/win32/localspl/spl_Pt.rc +++ b/reactos/dll/win32/localspl/spl_Pt.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localspl_private.h" + LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/localspl/spl_Ro.rc b/reactos/dll/win32/localspl/spl_Ro.rc index 44321957313..7f988001687 100644 --- a/reactos/dll/win32/localspl/spl_Ro.rc +++ b/reactos/dll/win32/localspl/spl_Ro.rc @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localspl_private.h" + +#pragma code_page(65001) + LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/localspl/spl_Ru.rc b/reactos/dll/win32/localspl/spl_Ru.rc index 1ee1e2f327b..085488d460d 100644 --- a/reactos/dll/win32/localspl/spl_Ru.rc +++ b/reactos/dll/win32/localspl/spl_Ru.rc @@ -18,10 +18,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localspl_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { - IDS_LOCALPORT "Ëîêàëüíûé ïîðò" - IDS_LOCALMONITOR "Ëîêàëüíûé ìîíèòîð" + IDS_LOCALPORT "Локальный порт" + IDS_LOCALMONITOR "Локальный монитор" } diff --git a/reactos/dll/win32/localspl/spl_Si.rc b/reactos/dll/win32/localspl/spl_Si.rc index 66ca2c4ce76..11928abfa37 100644 --- a/reactos/dll/win32/localspl/spl_Si.rc +++ b/reactos/dll/win32/localspl/spl_Si.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localspl_private.h" + #pragma code_page(65001) LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT @@ -27,5 +29,3 @@ STRINGTABLE DISCARDABLE IDS_LOCALPORT "Lokalna vrata" IDS_LOCALMONITOR "Lokalen monitor" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/localspl/spl_Sv.rc b/reactos/dll/win32/localspl/spl_Sv.rc index fca0d6b0835..2831da64e11 100644 --- a/reactos/dll/win32/localspl/spl_Sv.rc +++ b/reactos/dll/win32/localspl/spl_Sv.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localspl_private.h" + LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/localspl/spl_Zh.rc b/reactos/dll/win32/localspl/spl_Zh.rc index c5db382ffe3..108cb50ee96 100644 --- a/reactos/dll/win32/localspl/spl_Zh.rc +++ b/reactos/dll/win32/localspl/spl_Zh.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localspl_private.h" + /* Chinese text is encoded in UTF-8 */ #pragma code_page(65001) @@ -36,5 +38,3 @@ STRINGTABLE DISCARDABLE IDS_LOCALPORT "本地端å£" IDS_LOCALMONITOR "本地監視器" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/localui/localui.c b/reactos/dll/win32/localui/localui.c index 2acfc7ecafa..b9e4c4ee324 100644 --- a/reactos/dll/win32/localui/localui.c +++ b/reactos/dll/win32/localui/localui.c @@ -503,7 +503,6 @@ static BOOL WINAPI localui_AddPortUI(PCWSTR pName, HWND hWnd, PCWSTR pMonitorNam { addportui_t data; HANDLE hXcv; - LPWSTR ptr = NULL; DWORD needed; DWORD dummy; DWORD status; @@ -529,14 +528,11 @@ static BOOL WINAPI localui_AddPortUI(PCWSTR pName, HWND hWnd, PCWSTR pMonitorNam (PBYTE) &dummy, 0, &needed, &status); TRACE("got %u with status %u\n", res, status); - if (res && (status == ERROR_SUCCESS)) { + if (res && (status == ERROR_SUCCESS) && ppPortName) { /* Native localui uses GlobalAlloc also. The caller must GlobalFree the buffer */ - ptr = GlobalAlloc(GPTR, (lstrlenW(data.portname)+1) * sizeof(WCHAR)); - if (ptr) { - lstrcpyW(ptr, data.portname); - if (ppPortName) *ppPortName = ptr; - } + *ppPortName = GlobalAlloc(GPTR, (lstrlenW(data.portname)+1) * sizeof(WCHAR)); + if (*ppPortName) lstrcpyW(*ppPortName, data.portname); } if (res && (status == ERROR_ALREADY_EXISTS)) { diff --git a/reactos/dll/win32/localui/localui.h b/reactos/dll/win32/localui/localui.h index aa244bdc824..25424da568c 100644 --- a/reactos/dll/win32/localui/localui.h +++ b/reactos/dll/win32/localui/localui.h @@ -21,6 +21,8 @@ #ifndef __WINE_LOCALUI__ #define __WINE_LOCALUI__ +#include +#include /* ## Resource-ID ## */ #define ADDPORT_DIALOG 100 diff --git a/reactos/dll/win32/localui/localui.rc b/reactos/dll/win32/localui/localui.rc index 9963acb20ae..f229f722cc9 100644 --- a/reactos/dll/win32/localui/localui.rc +++ b/reactos/dll/win32/localui/localui.rc @@ -39,17 +39,19 @@ #include "ui_Da.rc" -#include "ui_De.rc" #include "ui_En.rc" -#include "ui_Fr.rc" #include "ui_Ko.rc" -#include "ui_Lt.rc" #include "ui_Nl.rc" #include "ui_No.rc" #include "ui_Pl.rc" #include "ui_Pt.rc" +#include "ui_Sv.rc" + +/* UTF-8 */ +#include "ui_De.rc" +#include "ui_Fr.rc" +#include "ui_Lt.rc" #include "ui_Ro.rc" #include "ui_Ru.rc" #include "ui_Si.rc" -#include "ui_Sv.rc" #include "ui_Zh.rc" diff --git a/reactos/dll/win32/localui/ui_Da.rc b/reactos/dll/win32/localui/ui_Da.rc index 97299266959..861ba8f2ddf 100644 --- a/reactos/dll/win32/localui/ui_Da.rc +++ b/reactos/dll/win32/localui/ui_Da.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localui.h" + LANGUAGE LANG_DANISH, SUBLANG_DEFAULT ADDPORT_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 6, 18, 245, 47 diff --git a/reactos/dll/win32/localui/ui_De.rc b/reactos/dll/win32/localui/ui_De.rc index 2fe35fc4e77..74148c3441b 100644 --- a/reactos/dll/win32/localui/ui_De.rc +++ b/reactos/dll/win32/localui/ui_De.rc @@ -18,14 +18,18 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localui.h" + +#pragma code_page(65001) + LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL ADDPORT_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 6, 18, 245, 47 STYLE DS_CONTEXTHELP | DS_MODALFRAME | DS_SETFONT | DS_SETFOREGROUND | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION -CAPTION "Lokalen Anschluss hinzufügen" +CAPTION "Lokalen Anschluss hinzufügen" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "&Lokaler Anschuss, der hinzugefügt werden soll:", -1, 7, 13, 194, 13, WS_VISIBLE + LTEXT "&Lokaler Anschuss, der hinzugefügt werden soll:", -1, 7, 13, 194, 13, WS_VISIBLE EDITTEXT ADDPORT_EDIT, 6, 28, 174, 12, WS_VISIBLE | ES_AUTOHSCROLL DEFPUSHBUTTON "OK", IDOK, 188, 10, 50, 14, WS_VISIBLE PUSHBUTTON "Abbrechen", IDCANCEL, 188, 27, 50, 14, WS_VISIBLE @@ -37,8 +41,8 @@ STYLE DS_CONTEXTHELP | DS_MODALFRAME | DS_SETFONT | DS_SETFOREGROUND | WS_POPUPW CAPTION "LPT-Anschluss konfigurieren" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Zeitüberschreitung (Sekunden)", LPTCONFIG_GROUP, 6, 6, 150, 35, BS_GROUPBOX - LTEXT "Ü&bertragung wiederholen:", -1, 14, 22, 90, 13, WS_VISIBLE + GROUPBOX "Zeitüberschreitung (Sekunden)", LPTCONFIG_GROUP, 6, 6, 150, 35, BS_GROUPBOX + LTEXT "Ü&bertragung wiederholen:", -1, 14, 22, 90, 13, WS_VISIBLE EDITTEXT LPTCONFIG_EDIT, 112, 20, 32, 13, WS_VISIBLE | ES_NUMBER DEFPUSHBUTTON "OK", IDOK, 164, 10, 50, 14, WS_VISIBLE PUSHBUTTON "Abbrechen", IDCANCEL, 164, 27, 50, 14, WS_VISIBLE @@ -48,7 +52,7 @@ END STRINGTABLE DISCARDABLE { IDS_LOCALPORT "Lokaler Anschluss" - IDS_INVALIDNAME "'%s' ist kein gültiger Anschlussname" + IDS_INVALIDNAME "'%s' ist kein gültiger Anschlussname" IDS_PORTEXISTS "Der Anschluss %s existiert bereits" IDS_NOTHINGTOCONFIG "Dieser Anschluss hat keine Optionen zum Konfigurieren" } diff --git a/reactos/dll/win32/localui/ui_En.rc b/reactos/dll/win32/localui/ui_En.rc index c2de6263a8a..5a218680472 100644 --- a/reactos/dll/win32/localui/ui_En.rc +++ b/reactos/dll/win32/localui/ui_En.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localui.h" + LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT ADDPORT_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 6, 18, 245, 47 diff --git a/reactos/dll/win32/localui/ui_Fr.rc b/reactos/dll/win32/localui/ui_Fr.rc index 261fa0b7dd2..70e4baf06ee 100644 --- a/reactos/dll/win32/localui/ui_Fr.rc +++ b/reactos/dll/win32/localui/ui_Fr.rc @@ -17,6 +17,9 @@ * 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 "localui.h" + #pragma code_page(65001) LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL @@ -53,5 +56,3 @@ STRINGTABLE DISCARDABLE IDS_PORTEXISTS "Le port %s existe déjà" IDS_NOTHINGTOCONFIG "Ce port n'a pas d'options de configuration" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/localui/ui_Ko.rc b/reactos/dll/win32/localui/ui_Ko.rc index 9a380308422..d86b7ef58a5 100644 --- a/reactos/dll/win32/localui/ui_Ko.rc +++ b/reactos/dll/win32/localui/ui_Ko.rc @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localui.h" + LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT ADDPORT_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 6, 18, 245, 47 diff --git a/reactos/dll/win32/localui/ui_Lt.rc b/reactos/dll/win32/localui/ui_Lt.rc index 698918afb85..ff789e17fba 100644 --- a/reactos/dll/win32/localui/ui_Lt.rc +++ b/reactos/dll/win32/localui/ui_Lt.rc @@ -53,8 +53,7 @@ END STRINGTABLE DISCARDABLE { IDS_LOCALPORT "Vietinis prievadas" - IDS_INVALIDNAME "'%s' yra netinkamas prievado vardas" + IDS_INVALIDNAME "„%s“ yra netinkamas prievado vardas" IDS_PORTEXISTS "Prievadas %s jau egzistuoja" IDS_NOTHINGTOCONFIG "Å is prievadas neturi parinkÄių konfigÅ«ravimui" } -#pragma code_page(default) diff --git a/reactos/dll/win32/localui/ui_Nl.rc b/reactos/dll/win32/localui/ui_Nl.rc index 59c58ffd3aa..21d7cc84fae 100644 --- a/reactos/dll/win32/localui/ui_Nl.rc +++ b/reactos/dll/win32/localui/ui_Nl.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localui.h" + LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL ADDPORT_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 6, 18, 245, 47 diff --git a/reactos/dll/win32/localui/ui_No.rc b/reactos/dll/win32/localui/ui_No.rc index 3a46bc8ee88..8ed9e00c8aa 100644 --- a/reactos/dll/win32/localui/ui_No.rc +++ b/reactos/dll/win32/localui/ui_No.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localui.h" + LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL ADDPORT_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 6, 18, 245, 47 diff --git a/reactos/dll/win32/localui/ui_Pl.rc b/reactos/dll/win32/localui/ui_Pl.rc index 74a5015e00a..822763d7dae 100644 --- a/reactos/dll/win32/localui/ui_Pl.rc +++ b/reactos/dll/win32/localui/ui_Pl.rc @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localui.h" + LANGUAGE LANG_POLISH, SUBLANG_DEFAULT ADDPORT_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 6, 18, 245, 47 diff --git a/reactos/dll/win32/localui/ui_Pt.rc b/reactos/dll/win32/localui/ui_Pt.rc index 7bad5211ead..7f1684820f7 100644 --- a/reactos/dll/win32/localui/ui_Pt.rc +++ b/reactos/dll/win32/localui/ui_Pt.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localui.h" + LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL ADDPORT_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 6, 18, 245, 47 diff --git a/reactos/dll/win32/localui/ui_Ro.rc b/reactos/dll/win32/localui/ui_Ro.rc index 43edfe6a4b1..a1b1c771fa1 100644 --- a/reactos/dll/win32/localui/ui_Ro.rc +++ b/reactos/dll/win32/localui/ui_Ro.rc @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localui.h" + LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL #pragma code_page(65001) @@ -53,5 +55,3 @@ STRINGTABLE DISCARDABLE IDS_PORTEXISTS "Portul %s existsă deja" IDS_NOTHINGTOCONFIG "Acest port nu are opÈ›iuni de configurat" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/localui/ui_Ru.rc b/reactos/dll/win32/localui/ui_Ru.rc index 96e78f1971b..04f87b68e70 100644 --- a/reactos/dll/win32/localui/ui_Ru.rc +++ b/reactos/dll/win32/localui/ui_Ru.rc @@ -18,37 +18,42 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localui.h" + +/* UTF-8 */ +#pragma code_page(65001) + LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT ADDPORT_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 6, 18, 245, 47 STYLE DS_CONTEXTHELP | DS_MODALFRAME | DS_SETFONT | DS_SETFOREGROUND | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION -CAPTION "Äîáàâèòü ëîêàëüíûé ïîðò" +CAPTION "Добавить локальный порт" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Ââåäèòå &íàçâàíèå ëîêàëüíîãî ïîðòà:", -1, 7, 13, 194, 13, WS_VISIBLE + LTEXT "Введите &название локального порта:", -1, 7, 13, 194, 13, WS_VISIBLE EDITTEXT ADDPORT_EDIT, 6, 28, 174, 12, WS_VISIBLE | ES_AUTOHSCROLL DEFPUSHBUTTON "OK", IDOK, 199, 10, 40, 14, WS_VISIBLE - PUSHBUTTON "Îòìåíèòü", IDCANCEL, 199, 27, 40, 14, WS_VISIBLE + PUSHBUTTON "Отменить", IDCANCEL, 199, 27, 40, 14, WS_VISIBLE END LPTCONFIG_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 6, 18, 220, 47 STYLE DS_CONTEXTHELP | DS_MODALFRAME | DS_SETFONT | DS_SETFOREGROUND | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION -CAPTION "Óñòàíîâêè ïàðàëëåëüíîãî ïîðòà" +CAPTION "УÑтановки параллельного порта" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Òàéì-àóò (ñåêóíä)", LPTCONFIG_GROUP, 6, 6, 150, 35, BS_GROUPBOX - LTEXT "&Ïîïûòîê ïåðåñûëêè:", -1, 14, 22, 90, 13, WS_VISIBLE + GROUPBOX "Тайм-аут (Ñекунд)", LPTCONFIG_GROUP, 6, 6, 150, 35, BS_GROUPBOX + LTEXT "&Попыток переÑылки:", -1, 14, 22, 90, 13, WS_VISIBLE EDITTEXT LPTCONFIG_EDIT, 112, 20, 32, 13, WS_VISIBLE | ES_NUMBER DEFPUSHBUTTON "OK", IDOK, 164, 10, 50, 14, WS_VISIBLE - PUSHBUTTON "Îòìåíà", IDCANCEL, 164, 27, 50, 14, WS_VISIBLE + PUSHBUTTON "Отмена", IDCANCEL, 164, 27, 50, 14, WS_VISIBLE END STRINGTABLE DISCARDABLE { - IDS_LOCALPORT "Ëîêàëüíûé ïîðò" - IDS_INVALIDNAME "Íå ïðàâèëüíîå íàçâàíèå ïîðòà '%s'" - IDS_PORTEXISTS "Ïîðò '%s' óæå ñóùåñòâóåò" - IDS_NOTHINGTOCONFIG "Ýòîò ïîðò íå èìååò íàñòðîåê" + IDS_LOCALPORT "Локальный порт" + IDS_INVALIDNAME "Ðе правильное название порта '%s'" + IDS_PORTEXISTS "Порт '%s' уже ÑущеÑтвует" + IDS_NOTHINGTOCONFIG "Этот порт не имеет наÑтроек" } diff --git a/reactos/dll/win32/localui/ui_Si.rc b/reactos/dll/win32/localui/ui_Si.rc index 961a2e046d4..6810c7ce733 100644 --- a/reactos/dll/win32/localui/ui_Si.rc +++ b/reactos/dll/win32/localui/ui_Si.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localui.h" + #pragma code_page(65001) LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT @@ -54,5 +56,3 @@ STRINGTABLE DISCARDABLE IDS_PORTEXISTS "Vrata z imenom %s že obstajajo" IDS_NOTHINGTOCONFIG "Ta vrata nimajo možnosti nastavitve" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/localui/ui_Sv.rc b/reactos/dll/win32/localui/ui_Sv.rc index 3cd22fd8c70..e137079ffe4 100644 --- a/reactos/dll/win32/localui/ui_Sv.rc +++ b/reactos/dll/win32/localui/ui_Sv.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localui.h" + LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL ADDPORT_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 6, 18, 245, 47 diff --git a/reactos/dll/win32/localui/ui_Zh.rc b/reactos/dll/win32/localui/ui_Zh.rc index 197ac1dd38d..f43dde9afbd 100644 --- a/reactos/dll/win32/localui/ui_Zh.rc +++ b/reactos/dll/win32/localui/ui_Zh.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "localui.h" + /* Chinese text is encoded in UTF-8 */ #pragma code_page(65001) @@ -90,5 +92,3 @@ STRINGTABLE DISCARDABLE IDS_PORTEXISTS "ç«¯å£ %s 已經存在" IDS_NOTHINGTOCONFIG "é€™å€‹ç«¯å£æ²’有å¯è¨­å®šé¸é …" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/mciavi32/info.c b/reactos/dll/win32/mciavi32/info.c index 64d51eb1010..b2ec0308cdd 100644 --- a/reactos/dll/win32/mciavi32/info.c +++ b/reactos/dll/win32/mciavi32/info.c @@ -80,6 +80,8 @@ DWORD MCIAVI_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS l if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + if (!(dwFlags & MCI_GETDEVCAPS_ITEM)) return MCIERR_MISSING_PARAMETER; + if (dwFlags & MCI_TEST) return 0; EnterCriticalSection(&wma->cs); @@ -130,14 +132,52 @@ DWORD MCIAVI_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS l lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); ret = MCI_RESOURCE_RETURNED; break; + case MCI_DGV_GETDEVCAPS_CAN_REVERSE: + TRACE("MCI_DGV_GETDEVCAPS_CAN_REVERSE !\n"); + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); /* FIXME */ + ret = MCI_RESOURCE_RETURNED; + break; + case MCI_DGV_GETDEVCAPS_CAN_STRETCH: + TRACE("MCI_DGV_GETDEVCAPS_CAN_STRETCH !\n"); + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); /* FIXME */ + ret = MCI_RESOURCE_RETURNED; + break; + case MCI_DGV_GETDEVCAPS_CAN_LOCK: + TRACE("MCI_DGV_GETDEVCAPS_CAN_LOCK !\n"); + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); + ret = MCI_RESOURCE_RETURNED; + break; + case MCI_DGV_GETDEVCAPS_CAN_FREEZE: + TRACE("MCI_DGV_GETDEVCAPS_CAN_FREEZE !\n"); + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); + ret = MCI_RESOURCE_RETURNED; + break; + case MCI_DGV_GETDEVCAPS_CAN_STR_IN: + TRACE("MCI_DGV_GETDEVCAPS_CAN_STRETCH_INPUT !\n"); + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); + ret = MCI_RESOURCE_RETURNED; + break; + case MCI_DGV_GETDEVCAPS_HAS_STILL: + TRACE("MCI_DGV_GETDEVCAPS_HAS_STILL !\n"); + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); + ret = MCI_RESOURCE_RETURNED; + break; + case MCI_DGV_GETDEVCAPS_CAN_TEST: + TRACE("MCI_DGV_GETDEVCAPS_CAN_TEST !\n"); + lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE); + ret = MCI_RESOURCE_RETURNED; + break; + case MCI_DGV_GETDEVCAPS_PALETTES: + TRACE("MCI_DGV_GETDEVCAPS_PALETTES !\n"); + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); /* FIXME */ + ret = MCI_RESOURCE_RETURNED; + break; + /* w2k does not know MAX_WINDOWS or MAX/MINIMUM_RATE */ default: FIXME("Unknown capability (%08x) !\n", lpParms->dwItem); - ret = MCIERR_UNRECOGNIZED_COMMAND; + ret = MCIERR_UNSUPPORTED_FUNCTION; break; } - } else { - WARN("No GetDevCaps-Item !\n"); - ret = MCIERR_UNRECOGNIZED_COMMAND; } LeaveCriticalSection(&wma->cs); @@ -157,6 +197,7 @@ DWORD MCIAVI_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_INFO_PARMSW lpParms) if (lpParms == NULL || lpParms->lpstrReturn == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + if (dwFlags & MCI_TEST) return 0; TRACE("buf=%p, len=%u\n", lpParms->lpstrReturn, lpParms->dwRetSize); @@ -193,6 +234,7 @@ DWORD MCIAVI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SET_PARMS lpParms) if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + if (dwFlags & MCI_TEST) return 0; EnterCriticalSection(&wma->cs); @@ -329,6 +371,8 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSW lpPar if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + if (!(dwFlags & MCI_STATUS_ITEM)) return MCIERR_MISSING_PARAMETER; + if (dwFlags & MCI_TEST) return 0; EnterCriticalSection(&wma->cs); @@ -387,22 +431,28 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSW lpPar TRACE("MCI_STATUS_TIME_FORMAT => %u\n", LOWORD(lpParms->dwReturn)); ret = MCI_RESOURCE_RETURNED; break; + case MCI_DGV_STATUS_AUDIO: + lpParms->dwReturn = (wma->dwSet & 3) ? + MAKEMCIRESOURCE(MCI_ON, MCI_ON_S) : MAKEMCIRESOURCE(MCI_OFF, MCI_OFF_S); + ret = MCI_RESOURCE_RETURNED|MCI_RESOURCE_DRIVER; + TRACE("MCI_STATUS_AUDIO = %u\n", LOWORD(lpParms->dwReturn)); + break; + case MCI_DGV_STATUS_VIDEO: + lpParms->dwReturn = (wma->dwSet & 4) ? + MAKEMCIRESOURCE(MCI_ON, MCI_ON_S) : MAKEMCIRESOURCE(MCI_OFF, MCI_OFF_S); + ret = MCI_RESOURCE_RETURNED|MCI_RESOURCE_DRIVER; + TRACE("MCI_STATUS_VIDEO = %u\n", LOWORD(lpParms->dwReturn)); + break; + #if 0 case MCI_AVI_STATUS_AUDIO_BREAKS: case MCI_AVI_STATUS_FRAMES_SKIPPED: case MCI_AVI_STATUS_LAST_PLAY_SPEED: - case MCI_DGV_STATUS_AUDIO: case MCI_DGV_STATUS_AUDIO_INPUT: case MCI_DGV_STATUS_AUDIO_RECORD: case MCI_DGV_STATUS_AUDIO_SOURCE: - case MCI_DGV_SETAUDIO_AVERAGE: - case MCI_DGV_SETAUDIO_LEFT: - case MCI_DGV_SETAUDIO_RIGHT: - case MCI_DGV_SETAUDIO_STEREO: - case MCI_DGV_STATUS_AUDIO_STREAM: case MCI_DGV_STATUS_AVGBYTESPERSEC: case MCI_DGV_STATUS_BASS: - case MCI_DGV_STATUS_BITSPERPEL: case MCI_DGV_STATUS_BITSPERSAMPLE: case MCI_DGV_STATUS_BLOCKALIGN: case MCI_DGV_STATUS_BRIGHTNESS: @@ -411,10 +461,12 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSW lpPar case MCI_DGV_STATUS_FILEFORMAT: case MCI_DGV_STATUS_FILE_MODE: case MCI_DGV_STATUS_FILE_COMPLETION: - case MCI_DGV_STATUS_FORWARD: - case MCI_DGV_STATUS_FRAME_RATE: case MCI_DGV_STATUS_GAMMA: #endif + case MCI_DGV_STATUS_BITSPERPEL: + lpParms->dwReturn = wma->inbih->biBitCount; + TRACE("MCI_DGV_STATUS_BITSPERPEL => %lu\n", lpParms->dwReturn); + break; case MCI_DGV_STATUS_HPAL: lpParms->dwReturn = 0; TRACE("MCI_DGV_STATUS_HPAL => %lx\n", lpParms->dwReturn); @@ -422,7 +474,52 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSW lpPar case MCI_DGV_STATUS_HWND: lpParms->dwReturn = (DWORD_PTR)wma->hWndPaint; TRACE("MCI_DGV_STATUS_HWND => %p\n", wma->hWndPaint); + break; + case MCI_DGV_STATUS_WINDOW_VISIBLE: + lpParms->dwReturn = IsWindowVisible(wma->hWndPaint) ? + MAKEMCIRESOURCE(TRUE, MCI_TRUE) : MAKEMCIRESOURCE(FALSE, MCI_FALSE); + ret = MCI_RESOURCE_RETURNED; + TRACE("MCI_STATUS_WINDOW_VISIBLE = %u\n", LOWORD(lpParms->dwReturn)); break; + case MCI_DGV_STATUS_WINDOW_MINIMIZED: + lpParms->dwReturn = IsIconic(wma->hWndPaint) ? + MAKEMCIRESOURCE(TRUE, MCI_TRUE) : MAKEMCIRESOURCE(FALSE, MCI_FALSE); + ret = MCI_RESOURCE_RETURNED; + TRACE("MCI_STATUS_WINDOW_MINIMIZED = %u\n", LOWORD(lpParms->dwReturn)); + break; + case MCI_DGV_STATUS_WINDOW_MAXIMIZED: + lpParms->dwReturn = IsZoomed(wma->hWndPaint) ? + MAKEMCIRESOURCE(TRUE, MCI_TRUE) : MAKEMCIRESOURCE(FALSE, MCI_FALSE); + ret = MCI_RESOURCE_RETURNED; + TRACE("MCI_STATUS_WINDOW_MMAXIMIZED = %u\n", LOWORD(lpParms->dwReturn)); + break; + case MCI_DGV_STATUS_SPEED: + lpParms->dwReturn = 1000; + TRACE("MCI_DGV_STATUS_SPEED = %lu\n", lpParms->dwReturn); + break; + case MCI_DGV_STATUS_FRAME_RATE: + /* FIXME: 1000 is a settable speed multiplier */ + lpParms->dwReturn = MulDiv(1000000,1000,wma->mah.dwMicroSecPerFrame); + TRACE("MCI_DGV_STATUS_FRAME_RATE = %lu\n", lpParms->dwReturn); + break; + case MCI_DGV_STATUS_FORWARD: + lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE); + ret = MCI_RESOURCE_RETURNED; + TRACE("MCI_DGV_STATUS_FORWARD = %u\n", LOWORD(lpParms->dwReturn)); + break; + case MCI_DGV_STATUS_PAUSE_MODE: + if (wma->dwStatus != MCI_MODE_PAUSE) { + LeaveCriticalSection(&wma->cs); + return MCIERR_NONAPPLICABLE_FUNCTION; + } + lpParms->dwReturn = MAKEMCIRESOURCE(MCI_MODE_PLAY, MCI_MODE_PLAY); + ret = MCI_RESOURCE_RETURNED; + TRACE("MCI_STATUS_MODE => 0x%04x\n", LOWORD(lpParms->dwReturn)); + break; + case MCI_DGV_STATUS_AUDIO_STREAM: + lpParms->dwReturn = wma->audio_stream_n; + TRACE("MCI_DGV_STATUS_AUDIO_STREAM => %lu\n", lpParms->dwReturn); + break; #if 0 case MCI_DGV_STATUS_KEY_COLOR: case MCI_DGV_STATUS_KEY_INDEX: @@ -430,38 +527,27 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSW lpPar case MCI_DGV_MONITOR_FILE: case MCI_DGV_MONITOR_INPUT: case MCI_DGV_STATUS_MONITOR_METHOD: - case MCI_DGV_STATUS_PAUSE_MODE: case MCI_DGV_STATUS_SAMPLESPERSECOND: case MCI_DGV_STATUS_SEEK_EXACTLY: case MCI_DGV_STATUS_SHARPNESS: case MCI_DGV_STATUS_SIZE: case MCI_DGV_STATUS_SMPTE: - case MCI_DGV_STATUS_SPEED: case MCI_DGV_STATUS_STILL_FILEFORMAT: case MCI_DGV_STATUS_TINT: case MCI_DGV_STATUS_TREBLE: case MCI_DGV_STATUS_UNSAVED: - case MCI_DGV_STATUS_VIDEO: case MCI_DGV_STATUS_VIDEO_RECORD: case MCI_DGV_STATUS_VIDEO_SOURCE: case MCI_DGV_STATUS_VIDEO_SRC_NUM: case MCI_DGV_STATUS_VIDEO_STREAM: case MCI_DGV_STATUS_VOLUME: - case MCI_DGV_STATUS_WINDOW_VISIBLE: - case MCI_DGV_STATUS_WINDOW_MINIMIZED: - case MCI_DGV_STATUS_WINDOW_MAXIMIZED: - case MCI_STATUS_MEDIA_PRESENT: #endif default: FIXME("Unknown command %08X !\n", lpParms->dwItem); TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); LeaveCriticalSection(&wma->cs); - return MCIERR_UNRECOGNIZED_COMMAND; + return MCIERR_UNSUPPORTED_FUNCTION; } - } else { - WARN("No Status-Item!\n"); - LeaveCriticalSection(&wma->cs); - return MCIERR_UNRECOGNIZED_COMMAND; } if (dwFlags & MCI_NOTIFY) { diff --git a/reactos/dll/win32/mciavi32/mciavi.c b/reactos/dll/win32/mciavi32/mciavi.c index 4e5faac7c0a..d77525ca4ff 100644 --- a/reactos/dll/win32/mciavi32/mciavi.c +++ b/reactos/dll/win32/mciavi32/mciavi.c @@ -217,8 +217,6 @@ static DWORD MCIAVI_mciOpen(UINT wDevID, DWORD dwFlags, TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpOpenParms); - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; wma = (WINE_MCIAVI *)mciGetDriverData(wDevID); @@ -250,29 +248,26 @@ static DWORD MCIAVI_mciOpen(UINT wDevID, DWORD dwFlags, * contains the hFile value ? */ dwRet = MCIERR_UNRECOGNIZED_COMMAND; - } else if (strlenW(lpOpenParms->lpstrElementName) > 0) { + } else if (lpOpenParms->lpstrElementName && lpOpenParms->lpstrElementName[0]) { /* FIXME : what should be done id wma->hFile is already != 0, or the driver is playin' */ TRACE("MCI_OPEN_ELEMENT %s!\n", debugstr_w(lpOpenParms->lpstrElementName)); - if (lpOpenParms->lpstrElementName && (strlenW(lpOpenParms->lpstrElementName) > 0)) - { - wma->lpFileName = HeapAlloc(GetProcessHeap(), 0, (strlenW(lpOpenParms->lpstrElementName) + 1) * sizeof(WCHAR)); - strcpyW(wma->lpFileName, lpOpenParms->lpstrElementName); + wma->lpFileName = HeapAlloc(GetProcessHeap(), 0, (strlenW(lpOpenParms->lpstrElementName) + 1) * sizeof(WCHAR)); + strcpyW(wma->lpFileName, lpOpenParms->lpstrElementName); - wma->hFile = mmioOpenW(lpOpenParms->lpstrElementName, NULL, - MMIO_ALLOCBUF | MMIO_DENYWRITE | MMIO_READ); + wma->hFile = mmioOpenW(lpOpenParms->lpstrElementName, NULL, + MMIO_ALLOCBUF | MMIO_DENYWRITE | MMIO_READ); - if (wma->hFile == 0) { - WARN("can't find file=%s!\n", debugstr_w(lpOpenParms->lpstrElementName)); - dwRet = MCIERR_FILE_NOT_FOUND; - } else { - if (!MCIAVI_GetInfo(wma)) - dwRet = MCIERR_INVALID_FILE; - else if (!MCIAVI_OpenVideo(wma)) - dwRet = MCIERR_CANNOT_LOAD_DRIVER; - else if (!MCIAVI_CreateWindow(wma, dwFlags, lpOpenParms)) - dwRet = MCIERR_CREATEWINDOW; - } + if (wma->hFile == 0) { + WARN("can't find file=%s!\n", debugstr_w(lpOpenParms->lpstrElementName)); + dwRet = MCIERR_FILE_NOT_FOUND; + } else { + if (!MCIAVI_GetInfo(wma)) + dwRet = MCIERR_INVALID_FILE; + else if (!MCIAVI_OpenVideo(wma)) + dwRet = MCIERR_CANNOT_LOAD_DRIVER; + else if (!MCIAVI_CreateWindow(wma, dwFlags, lpOpenParms)) + dwRet = MCIERR_CREATEWINDOW; } } else { FIXME("Don't record yet\n"); @@ -303,8 +298,6 @@ DWORD MCIAVI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; @@ -390,13 +383,13 @@ static DWORD MCIAVI_mciPlay_async(WINE_MCIAVI *wma, DWORD dwFlags, LPMCI_PLAY_PA static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) { WINE_MCIAVI *wma; - DWORD tc; DWORD frameTime; - DWORD delta; DWORD dwRet; LPWAVEHDR waveHdr = NULL; unsigned i, nHdr = 0; DWORD dwFromFrame, dwToFrame; + DWORD numEvents = 1; + HANDLE events[2]; TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); @@ -404,6 +397,8 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + if (dwFlags & MCI_DGV_PLAY_REVERSE) return MCIERR_UNSUPPORTED_FUNCTION; + if (dwFlags & MCI_TEST) return 0; EnterCriticalSection(&wma->cs); @@ -464,12 +459,13 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms /* signal the state change */ SetEvent(wma->ack_event); - if (dwFlags & (MCI_DGV_PLAY_REPEAT|MCI_DGV_PLAY_REVERSE|MCI_MCIAVI_PLAY_WINDOW|MCI_MCIAVI_PLAY_FULLSCREEN)) + if (dwFlags & (MCI_DGV_PLAY_REPEAT|MCI_MCIAVI_PLAY_WINDOW|MCI_MCIAVI_PLAY_FULLSCREEN)) FIXME("Unsupported flag %08x\n", dwFlags); /* time is in microseconds, we should convert it to milliseconds */ frameTime = (wma->mah.dwMicroSecPerFrame + 500) / 1000; + events[0] = wma->hStopEvent; if (wma->lpWaveFormat) { if (MCIAVI_OpenAudio(wma, &nHdr, &waveHdr) != 0) { @@ -477,14 +473,19 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms HeapFree(GetProcessHeap(), 0, wma->lpWaveFormat); wma->lpWaveFormat = NULL; } - else - /* fill the queue with as many wave headers as possible */ - MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr); + else + { + /* fill the queue with as many wave headers as possible */ + MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr); + events[1] = wma->hEvent; + numEvents = 2; + } } while (wma->dwStatus == MCI_MODE_PLAY) { HDC hDC; + DWORD tc, delta; DWORD ret; tc = GetTickCount(); @@ -496,21 +497,8 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms ReleaseDC(wma->hWndPaint, hDC); } - if (wma->lpWaveFormat) { - HANDLE events[2]; - - events[0] = wma->hStopEvent; - events[1] = wma->hEvent; - + if (wma->lpWaveFormat) MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr); - delta = GetTickCount() - tc; - - LeaveCriticalSection(&wma->cs); - ret = WaitForMultipleObjects(2, events, FALSE, (delta >= frameTime) ? 0 : frameTime - delta); - EnterCriticalSection(&wma->cs); - - if (ret == WAIT_OBJECT_0 || wma->dwStatus != MCI_MODE_PLAY) break; - } delta = GetTickCount() - tc; if (delta < frameTime) @@ -519,9 +507,9 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms delta = 0; LeaveCriticalSection(&wma->cs); - ret = WaitForMultipleObjects(1, &wma->hStopEvent, FALSE, delta); + ret = WaitForMultipleObjects(numEvents, events, FALSE, delta); EnterCriticalSection(&wma->cs); - if (ret == WAIT_OBJECT_0) break; + if (ret == WAIT_OBJECT_0 || wma->dwStatus != MCI_MODE_PLAY) break; if (wma->dwCurrVideoFrame < dwToFrame) wma->dwCurrVideoFrame++; @@ -572,28 +560,6 @@ mci_play_done: return dwRet; } -/*************************************************************************** - * MCIAVI_mciRecord [internal] - */ -static DWORD MCIAVI_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECORD_PARMS lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08X, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - EnterCriticalSection(&wma->cs); - wma->dwStatus = MCI_MODE_RECORD; - LeaveCriticalSection(&wma->cs); - return 0; -} - /*************************************************************************** * MCIAVI_mciStop [internal] */ @@ -606,6 +572,7 @@ static DWORD MCIAVI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPa wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + if (dwFlags & MCI_TEST) return 0; EnterCriticalSection(&wma->cs); @@ -658,6 +625,7 @@ static DWORD MCIAVI_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpP wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + if (dwFlags & MCI_TEST) return 0; EnterCriticalSection(&wma->cs); @@ -684,6 +652,7 @@ static DWORD MCIAVI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lp wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + if (dwFlags & MCI_TEST) return 0; EnterCriticalSection(&wma->cs); @@ -705,33 +674,36 @@ static DWORD MCIAVI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lp static DWORD MCIAVI_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms) { WINE_MCIAVI *wma; + DWORD position; TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + position = dwFlags & (MCI_SEEK_TO_START|MCI_SEEK_TO_END|MCI_TO); + if (!position) return MCIERR_MISSING_PARAMETER; + if (position&(position-1)) return MCIERR_FLAGS_NOT_COMPATIBLE; + + if (dwFlags & MCI_TO) { + position = MCIAVI_ConvertTimeFormatToFrame(wma, lpParms->dwTo); + if (position >= wma->dwPlayableVideoFrames) + return MCIERR_OUTOFRANGE; + } else if (dwFlags & MCI_SEEK_TO_START) { + position = 0; + } else { + position = wma->dwPlayableVideoFrames - 1; + } + if (dwFlags & MCI_TEST) return 0; + + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + EnterCriticalSection(&wma->cs); - if (dwFlags & MCI_SEEK_TO_START) { - wma->dwCurrVideoFrame = 0; - } else if (dwFlags & MCI_SEEK_TO_END) { - wma->dwCurrVideoFrame = wma->dwPlayableVideoFrames - 1; - } else if (dwFlags & MCI_TO) { - if (lpParms->dwTo > wma->dwPlayableVideoFrames - 1) - lpParms->dwTo = wma->dwPlayableVideoFrames - 1; - wma->dwCurrVideoFrame = MCIAVI_ConvertTimeFormatToFrame(wma, lpParms->dwTo); - } else { - WARN("dwFlag doesn't tell where to seek to...\n"); - LeaveCriticalSection(&wma->cs); - return MCIERR_MISSING_PARAMETER; - } - - TRACE("Seeking to frame=%u bytes\n", wma->dwCurrVideoFrame); + wma->dwCurrVideoFrame = position; + TRACE("Seeking to frame=%u\n", wma->dwCurrVideoFrame); if (dwFlags & MCI_NOTIFY) { mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), @@ -750,52 +722,12 @@ static DWORD MCIAVI_mciLoad(UINT wDevID, DWORD dwFlags, LPMCI_DGV_LOAD_PARMSW lp FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - return 0; -} - -/****************************************************************************** - * MCIAVI_mciSave [internal] - */ -static DWORD MCIAVI_mciSave(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SAVE_PARMSW lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - return 0; -} - -/****************************************************************************** - * MCIAVI_mciFreeze [internal] - */ -static DWORD MCIAVI_mciFreeze(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - return 0; + return MCIERR_UNSUPPORTED_FUNCTION; /* like w2k */ } /****************************************************************************** @@ -807,31 +739,11 @@ static DWORD MCIAVI_mciRealize(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS l FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - return 0; -} - -/****************************************************************************** - * MCIAVI_mciUnFreeze [internal] - */ -static DWORD MCIAVI_mciUnFreeze(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + if (dwFlags & MCI_TEST) return 0; return 0; } @@ -849,6 +761,7 @@ static DWORD MCIAVI_mciUpdate(UINT wDevID, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + /* Ignore MCI_TEST flag. */ EnterCriticalSection(&wma->cs); @@ -866,92 +779,34 @@ static DWORD MCIAVI_mciUpdate(UINT wDevID, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS static DWORD MCIAVI_mciStep(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STEP_PARMS lpParms) { WINE_MCIAVI *wma; + DWORD position; + int delta = 1; - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + TRACE("(%04x, %08x, %p)\n", wDevID, dwFlags, lpParms); if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - return 0; -} - -/****************************************************************************** - * MCIAVI_mciCopy [internal] - */ -static DWORD MCIAVI_mciCopy(UINT wDevID, DWORD dwFlags, LPMCI_DGV_COPY_PARMS lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); + if (dwFlags & MCI_DGV_STEP_FRAMES) delta = lpParms->dwFrames; + if (dwFlags & MCI_DGV_STEP_REVERSE) delta = -delta; + position = wma->dwCurrVideoFrame + delta; + if (position >= wma->dwPlayableVideoFrames) return MCIERR_OUTOFRANGE; + if (dwFlags & MCI_TEST) return 0; MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + EnterCriticalSection(&wma->cs); - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - return 0; -} - -/****************************************************************************** - * MCIAVI_mciCut [internal] - */ -static DWORD MCIAVI_mciCut(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUT_PARMS lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - return 0; -} - -/****************************************************************************** - * MCIAVI_mciDelete [internal] - */ -static DWORD MCIAVI_mciDelete(UINT wDevID, DWORD dwFlags, LPMCI_DGV_DELETE_PARMS lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - return 0; -} - -/****************************************************************************** - * MCIAVI_mciPaste [internal] - */ -static DWORD MCIAVI_mciPaste(UINT wDevID, DWORD dwFlags, LPMCI_DGV_PASTE_PARMS lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + wma->dwCurrVideoFrame = position; + TRACE("Stepping to frame=%u\n", wma->dwCurrVideoFrame); + if (dwFlags & MCI_NOTIFY) { + mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), + wDevID, MCI_NOTIFY_SUCCESSFUL); + } + LeaveCriticalSection(&wma->cs); return 0; } @@ -964,69 +819,12 @@ static DWORD MCIAVI_mciCue(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUE_PARMS lpPar FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - return 0; -} - -/****************************************************************************** - * MCIAVI_mciCapture [internal] - */ -static DWORD MCIAVI_mciCapture(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CAPTURE_PARMSW lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - return 0; -} - -/****************************************************************************** - * MCIAVI_mciMonitor [internal] - */ -static DWORD MCIAVI_mciMonitor(UINT wDevID, DWORD dwFlags, LPMCI_DGV_MONITOR_PARMS lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - return 0; -} - -/****************************************************************************** - * MCIAVI_mciReserve [internal] - */ -static DWORD MCIAVI_mciReserve(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RESERVE_PARMSW lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + if (dwFlags & MCI_DGV_CUE_INPUT) return MCIERR_UNSUPPORTED_FUNCTION; + if (dwFlags & MCI_TEST) return 0; return 0; } @@ -1040,14 +838,12 @@ static DWORD MCIAVI_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_P FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - return 0; + return MCIERR_UNSUPPORTED_FUNCTION; /* like w2k */ } /****************************************************************************** @@ -1059,8 +855,6 @@ static DWORD MCIAVI_mciSignal(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SIGNAL_PARMS FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; wma = MCIAVI_mciGetOpenDev(wDevID); @@ -1078,71 +872,12 @@ static DWORD MCIAVI_mciSetVideo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETVIDEO_P FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - return 0; -} - -/****************************************************************************** - * MCIAVI_mciQuality [internal] - */ -static DWORD MCIAVI_mciQuality(UINT wDevID, DWORD dwFlags, LPMCI_DGV_QUALITY_PARMSW lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - return 0; -} - -/****************************************************************************** - * MCIAVI_mciList [internal] - */ -static DWORD MCIAVI_mciList(UINT wDevID, DWORD dwFlags, LPMCI_DGV_LIST_PARMSW lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - return 0; -} - -/****************************************************************************** - * MCIAVI_mciUndo [internal] - */ -static DWORD MCIAVI_mciUndo(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - return 0; + return MCIERR_UNSUPPORTED_FUNCTION; /* like w2k */ } /****************************************************************************** @@ -1154,31 +889,11 @@ static DWORD MCIAVI_mciConfigure(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; - - wma = MCIAVI_mciGetOpenDev(wDevID); - if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - - return 0; -} - -/****************************************************************************** - * MCIAVI_mciRestore [internal] - */ -static DWORD MCIAVI_mciRestore(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RESTORE_PARMSW lpParms) -{ - WINE_MCIAVI *wma; - - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - - MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + if (dwFlags & MCI_TEST) return 0; return 0; } @@ -1216,7 +931,6 @@ LRESULT CALLBACK MCIAVI_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, case MCI_OPEN_DRIVER: return MCIAVI_mciOpen (dwDevID, dwParam1, (LPMCI_DGV_OPEN_PARMSW) dwParam2); case MCI_CLOSE_DRIVER: return MCIAVI_mciClose (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); case MCI_PLAY: return MCIAVI_mciPlay (dwDevID, dwParam1, (LPMCI_PLAY_PARMS) dwParam2); - case MCI_RECORD: return MCIAVI_mciRecord (dwDevID, dwParam1, (LPMCI_DGV_RECORD_PARMS) dwParam2); case MCI_STOP: return MCIAVI_mciStop (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); case MCI_SET: return MCIAVI_mciSet (dwDevID, dwParam1, (LPMCI_DGV_SET_PARMS) dwParam2); case MCI_PAUSE: return MCIAVI_mciPause (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); @@ -1228,34 +942,38 @@ LRESULT CALLBACK MCIAVI_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, case MCI_PUT: return MCIAVI_mciPut (dwDevID, dwParam1, (LPMCI_DGV_PUT_PARMS) dwParam2); case MCI_WINDOW: return MCIAVI_mciWindow (dwDevID, dwParam1, (LPMCI_DGV_WINDOW_PARMSW) dwParam2); case MCI_LOAD: return MCIAVI_mciLoad (dwDevID, dwParam1, (LPMCI_DGV_LOAD_PARMSW) dwParam2); - case MCI_SAVE: return MCIAVI_mciSave (dwDevID, dwParam1, (LPMCI_DGV_SAVE_PARMSW) dwParam2); - case MCI_FREEZE: return MCIAVI_mciFreeze (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS) dwParam2); case MCI_REALIZE: return MCIAVI_mciRealize (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); - case MCI_UNFREEZE: return MCIAVI_mciUnFreeze (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS) dwParam2); case MCI_UPDATE: return MCIAVI_mciUpdate (dwDevID, dwParam1, (LPMCI_DGV_UPDATE_PARMS) dwParam2); case MCI_WHERE: return MCIAVI_mciWhere (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS) dwParam2); case MCI_STEP: return MCIAVI_mciStep (dwDevID, dwParam1, (LPMCI_DGV_STEP_PARMS) dwParam2); - case MCI_COPY: return MCIAVI_mciCopy (dwDevID, dwParam1, (LPMCI_DGV_COPY_PARMS) dwParam2); - case MCI_CUT: return MCIAVI_mciCut (dwDevID, dwParam1, (LPMCI_DGV_CUT_PARMS) dwParam2); - case MCI_DELETE: return MCIAVI_mciDelete (dwDevID, dwParam1, (LPMCI_DGV_DELETE_PARMS) dwParam2); - case MCI_PASTE: return MCIAVI_mciPaste (dwDevID, dwParam1, (LPMCI_DGV_PASTE_PARMS) dwParam2); case MCI_CUE: return MCIAVI_mciCue (dwDevID, dwParam1, (LPMCI_DGV_CUE_PARMS) dwParam2); /* Digital Video specific */ - case MCI_CAPTURE: return MCIAVI_mciCapture (dwDevID, dwParam1, (LPMCI_DGV_CAPTURE_PARMSW) dwParam2); - case MCI_MONITOR: return MCIAVI_mciMonitor (dwDevID, dwParam1, (LPMCI_DGV_MONITOR_PARMS) dwParam2); - case MCI_RESERVE: return MCIAVI_mciReserve (dwDevID, dwParam1, (LPMCI_DGV_RESERVE_PARMSW) dwParam2); case MCI_SETAUDIO: return MCIAVI_mciSetAudio (dwDevID, dwParam1, (LPMCI_DGV_SETAUDIO_PARMSW) dwParam2); case MCI_SIGNAL: return MCIAVI_mciSignal (dwDevID, dwParam1, (LPMCI_DGV_SIGNAL_PARMS) dwParam2); case MCI_SETVIDEO: return MCIAVI_mciSetVideo (dwDevID, dwParam1, (LPMCI_DGV_SETVIDEO_PARMSW) dwParam2); - case MCI_QUALITY: return MCIAVI_mciQuality (dwDevID, dwParam1, (LPMCI_DGV_QUALITY_PARMSW) dwParam2); - case MCI_LIST: return MCIAVI_mciList (dwDevID, dwParam1, (LPMCI_DGV_LIST_PARMSW) dwParam2); - case MCI_UNDO: return MCIAVI_mciUndo (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); case MCI_CONFIGURE: return MCIAVI_mciConfigure (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); - case MCI_RESTORE: return MCIAVI_mciRestore (dwDevID, dwParam1, (LPMCI_DGV_RESTORE_PARMSW) dwParam2); + /* no editing, recording, saving, locking without inputs */ + case MCI_CAPTURE: + case MCI_COPY: + case MCI_CUT: + case MCI_DELETE: + case MCI_FREEZE: + case MCI_LIST: + case MCI_MONITOR: + case MCI_PASTE: + case MCI_QUALITY: + case MCI_RECORD: + case MCI_RESERVE: + case MCI_RESTORE: + case MCI_SAVE: + case MCI_UNDO: + case MCI_UNFREEZE: + TRACE("Unsupported function [0x%x] flags=%08x\n", wMsg, (DWORD)dwParam1); + return MCIERR_UNSUPPORTED_FUNCTION; case MCI_SPIN: case MCI_ESCAPE: - WARN("Unsupported command [%u]\n", wMsg); + WARN("Unsupported command [0x%x] %08x\n", wMsg, (DWORD)dwParam1); break; case MCI_OPEN: case MCI_CLOSE: diff --git a/reactos/dll/win32/mciavi32/mciavi_res.rc b/reactos/dll/win32/mciavi32/mciavi_res.rc index 5f6d973e54a..d1e8faca3ec 100644 --- a/reactos/dll/win32/mciavi32/mciavi_res.rc +++ b/reactos/dll/win32/mciavi32/mciavi_res.rc @@ -20,6 +20,7 @@ #include "windef.h" #include "winbase.h" #include "mmddk.h" +#include "digitalv.h" MCIAVI RCDATA BEGIN @@ -563,3 +564,10 @@ L"text\0", 0x00080000L, MCI_STRING, L"\0", 0x00000000L, MCI_END_COMMAND, L"\0", 0x00000000L, MCI_END_COMMAND_LIST END + +STRINGTABLE +BEGIN + +MCI_ON_S, "on" +MCI_OFF_S, "off" +END diff --git a/reactos/dll/win32/mciavi32/mmoutput.c b/reactos/dll/win32/mciavi32/mmoutput.c index f9d1ddd9dd4..2cd33398ead 100644 --- a/reactos/dll/win32/mciavi32/mmoutput.c +++ b/reactos/dll/win32/mciavi32/mmoutput.c @@ -333,6 +333,7 @@ BOOL MCIAVI_GetInfo(WINE_MCIAVI* wma) if (!MCIAVI_GetInfoVideo(wma, &mmckList, &mmckStream)) return FALSE; wma->video_stream_n = stream_n; + wma->dwSet |= 4; } } else if (strh.fccType == streamtypeAUDIO) @@ -347,6 +348,7 @@ BOOL MCIAVI_GetInfo(WINE_MCIAVI* wma) if (!MCIAVI_GetInfoAudio(wma, &mmckList, &mmckStream)) return FALSE; wma->audio_stream_n = stream_n; + wma->dwSet |= 3; } } else diff --git a/reactos/dll/win32/mciavi32/wnd.c b/reactos/dll/win32/mciavi32/wnd.c index 36f56e6293a..c7dcf61d07c 100644 --- a/reactos/dll/win32/mciavi32/wnd.c +++ b/reactos/dll/win32/mciavi32/wnd.c @@ -154,6 +154,7 @@ DWORD MCIAVI_mciPut(UINT wDevID, DWORD dwFlags, LPMCI_DGV_PUT_PARMS lpParms) if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + if (dwFlags & MCI_TEST) return 0; EnterCriticalSection(&wma->cs); @@ -211,6 +212,7 @@ DWORD MCIAVI_mciWhere(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms) if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + /* Ignore MCI_TEST flag. */ EnterCriticalSection(&wma->cs); @@ -283,6 +285,7 @@ DWORD MCIAVI_mciWindow(UINT wDevID, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMSW lpPar if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + if (dwFlags & MCI_TEST) return 0; EnterCriticalSection(&wma->cs); diff --git a/reactos/dll/win32/mciqtz32/mciqtz.c b/reactos/dll/win32/mciqtz32/mciqtz.c index 837122747c7..b98e163ebbc 100644 --- a/reactos/dll/win32/mciqtz32/mciqtz.c +++ b/reactos/dll/win32/mciqtz32/mciqtz.c @@ -105,6 +105,7 @@ static DWORD MCIQTZ_drvClose(DWORD dwDevID) /* finish all outstanding things */ MCIQTZ_mciClose(dwDevID, MCI_WAIT, NULL); + mciSetDriverData(dwDevID, 0); HeapFree(GetProcessHeap(), 0, wma); return 1; } @@ -166,7 +167,7 @@ static DWORD MCIQTZ_mciOpen(UINT wDevID, DWORD dwFlags, goto err; } - if (!((dwFlags & MCI_OPEN_ELEMENT) && (dwFlags & MCI_OPEN_ELEMENT))) { + if (!(dwFlags & MCI_OPEN_ELEMENT) || (dwFlags & MCI_OPEN_ELEMENT_ID)) { TRACE("Wrong dwFlags %x\n", dwFlags); goto err; } @@ -353,10 +354,8 @@ static DWORD MCIQTZ_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_P if (!wma) return MCIERR_INVALID_DEVICE_ID; - if (!(dwFlags & MCI_STATUS_ITEM)) { - WARN("No capability item specified\n"); - return MCIERR_UNRECOGNIZED_COMMAND; - } + if (!(dwFlags & MCI_GETDEVCAPS_ITEM)) + return MCIERR_MISSING_PARAMETER; switch (lpParms->dwItem) { case MCI_GETDEVCAPS_CAN_RECORD: @@ -395,9 +394,44 @@ static DWORD MCIQTZ_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_P lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); TRACE("MCI_GETDEVCAPS_CAN_SAVE = %08x\n", lpParms->dwReturn); break; + case MCI_DGV_GETDEVCAPS_CAN_REVERSE: + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); + TRACE("MCI_DGV_GETDEVCAPS_CAN_REVERSE = %08x\n", lpParms->dwReturn); + break; + case MCI_DGV_GETDEVCAPS_CAN_STRETCH: + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); /* FIXME */ + TRACE("MCI_DGV_GETDEVCAPS_CAN_STRETCH = %08x\n", lpParms->dwReturn); + break; + case MCI_DGV_GETDEVCAPS_CAN_LOCK: + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); + TRACE("MCI_DGV_GETDEVCAPS_CAN_LOCK = %08x\n", lpParms->dwReturn); + break; + case MCI_DGV_GETDEVCAPS_CAN_FREEZE: + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); + TRACE("MCI_DGV_GETDEVCAPS_CAN_FREEZE = %08x\n", lpParms->dwReturn); + break; + case MCI_DGV_GETDEVCAPS_CAN_STR_IN: + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); + TRACE("MCI_DGV_GETDEVCAPS_CAN_STRETCH_INPUT = %08x\n", lpParms->dwReturn); + break; + case MCI_DGV_GETDEVCAPS_HAS_STILL: + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); + TRACE("MCI_DGV_GETDEVCAPS_HAS_STILL = %08x\n", lpParms->dwReturn); + break; + case MCI_DGV_GETDEVCAPS_CAN_TEST: + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); /* FIXME */ + TRACE("MCI_DGV_GETDEVCAPS_CAN_TEST = %08x\n", lpParms->dwReturn); + break; + case MCI_DGV_GETDEVCAPS_MAX_WINDOWS: + lpParms->dwReturn = 1; + TRACE("MCI_DGV_GETDEVCAPS_MAX_WINDOWS = %u\n", lpParms->dwReturn); + return 0; default: - ERR("Unknown capability %08x\n", lpParms->dwItem); - return MCIERR_UNRECOGNIZED_COMMAND; + WARN("Unknown capability %08x\n", lpParms->dwItem); + /* Fall through */ + case MCI_DGV_GETDEVCAPS_MAXIMUM_RATE: /* unknown to w2k */ + case MCI_DGV_GETDEVCAPS_MINIMUM_RATE: /* unknown to w2k */ + return MCIERR_UNSUPPORTED_FUNCTION; } return MCI_RESOURCE_RETURNED; @@ -435,8 +469,25 @@ static DWORD MCIQTZ_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SET_PARMS lpPar } } - if (dwFlags & ~MCI_SET_TIME_FORMAT) - FIXME("Flags not supported yet %08lX\n", dwFlags & ~MCI_SET_TIME_FORMAT); + if (dwFlags & MCI_SET_DOOR_OPEN) + FIXME("MCI_SET_DOOR_OPEN not implemented yet\n"); + if (dwFlags & MCI_SET_DOOR_CLOSED) + FIXME("MCI_SET_DOOR_CLOSED not implemented yet\n"); + if (dwFlags & MCI_SET_AUDIO) + FIXME("MCI_SET_AUDIO not implemented yet\n"); + if (dwFlags & MCI_SET_VIDEO) + FIXME("MCI_SET_VIDEO not implemented yet\n"); + if (dwFlags & MCI_SET_ON) + FIXME("MCI_SET_ON not implemented yet\n"); + if (dwFlags & MCI_SET_OFF) + FIXME("MCI_SET_OFF not implemented yet\n"); + if (dwFlags & MCI_SET_AUDIO_LEFT) + FIXME("MCI_SET_AUDIO_LEFT not implemented yet\n"); + if (dwFlags & MCI_SET_AUDIO_RIGHT) + FIXME("MCI_SET_AUDIO_RIGHT not implemented yet\n"); + + if (dwFlags & ~0x7f03 /* All MCI_SET flags mask */) + ERR("Unknown flags %08x\n", dwFlags & ~0x7f03); return 0; } @@ -603,6 +654,27 @@ static DWORD MCIQTZ_mciWhere(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lp return 0; } +/*************************************************************************** + * MCIQTZ_mciSetAudio [internal] + */ +static DWORD MCIQTZ_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_PARMSW lpParms) +{ + WINE_MCIQTZ *wma; + + FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); + + if (!lpParms) + return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIQTZ_mciGetOpenDev(wDevID); + if (!wma) + return MCIERR_INVALID_DEVICE_ID; + + MCIQTZ_mciStop(wDevID, MCI_WAIT, NULL); + + return 0; +} + /*======================================================================* * MCI QTZ entry points * *======================================================================*/ @@ -643,6 +715,8 @@ LRESULT CALLBACK MCIQTZ_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, case MCI_SET: return MCIQTZ_mciSet (dwDevID, dwParam1, (LPMCI_DGV_SET_PARMS) dwParam2); case MCI_STATUS: return MCIQTZ_mciStatus (dwDevID, dwParam1, (LPMCI_DGV_STATUS_PARMSW) dwParam2); case MCI_WHERE: return MCIQTZ_mciWhere (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS) dwParam2); + /* Digital Video specific */ + case MCI_SETAUDIO: return MCIQTZ_mciSetAudio (dwDevID, dwParam1, (LPMCI_DGV_SETAUDIO_PARMSW) dwParam2); case MCI_RECORD: case MCI_PAUSE: case MCI_RESUME: @@ -665,7 +739,6 @@ LRESULT CALLBACK MCIQTZ_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, case MCI_CAPTURE: case MCI_MONITOR: case MCI_RESERVE: - case MCI_SETAUDIO: case MCI_SIGNAL: case MCI_SETVIDEO: case MCI_QUALITY: diff --git a/reactos/dll/win32/mciseq/mcimidi.c b/reactos/dll/win32/mciseq/mcimidi.c index 47cb792362c..301428d517d 100644 --- a/reactos/dll/win32/mciseq/mcimidi.c +++ b/reactos/dll/win32/mciseq/mcimidi.c @@ -113,9 +113,6 @@ static DWORD CALLBACK MCI_SCAStarter(LPVOID arg) TRACE("In thread after async command (%08x,%u,%08lx,%08lx)\n", sca->wDevID, sca->wMsg, sca->dwParam1, sca->dwParam2); HeapFree(GetProcessHeap(), 0, sca); - ExitThread(ret); - WARN("Should not happen ? what's wrong\n"); - /* should not go after this point */ return ret; } @@ -147,7 +144,7 @@ static DWORD MCI_SendCommandAsync(UINT wDevID, UINT wMsg, DWORD_PTR dwParam1, if ((handle = CreateThread(NULL, 0, MCI_SCAStarter, sca, 0, NULL)) == 0) { WARN("Couldn't allocate thread for async command handling, sending synchronously\n"); - return MCI_SCAStarter(&sca); + return MCI_SCAStarter(sca); } SetThreadPriority(handle, THREAD_PRIORITY_TIME_CRITICAL); CloseHandle(handle); @@ -412,7 +409,7 @@ static DWORD MIDI_mciReadMTrk(WINE_MCIMIDI* wmm, MCI_MIDITRACK* mmt) } else { len = MultiByteToWideChar( CP_ACP, 0, buf, -1, NULL, 0 ); wmm->lpstrCopyright = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); - len = MultiByteToWideChar( CP_ACP, 0, buf, -1, wmm->lpstrCopyright, len ); + MultiByteToWideChar( CP_ACP, 0, buf, -1, wmm->lpstrCopyright, len ); } break; case 0x03: @@ -421,7 +418,7 @@ static DWORD MIDI_mciReadMTrk(WINE_MCIMIDI* wmm, MCI_MIDITRACK* mmt) } else { len = MultiByteToWideChar( CP_ACP, 0, buf, -1, NULL, 0 ); wmm->lpstrName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); - len = MultiByteToWideChar( CP_ACP, 0, buf, -1, wmm->lpstrName, len ); + MultiByteToWideChar( CP_ACP, 0, buf, -1, wmm->lpstrName, len ); } break; } diff --git a/reactos/dll/win32/mlang/mlang.c b/reactos/dll/win32/mlang/mlang.c index c28e695962d..47b1745215a 100644 --- a/reactos/dll/win32/mlang/mlang.c +++ b/reactos/dll/win32/mlang/mlang.c @@ -2501,7 +2501,7 @@ static HRESULT EnumRfc1766_create(LANGID LangId, IEnumRfc1766 **ppEnum) if (!data.info) { HeapFree(GetProcessHeap(), 0, rfc); - return S_FALSE; + return E_OUTOFMEMORY; } TlsSetValue(MLANG_tls_index, &data); @@ -2514,7 +2514,7 @@ static HRESULT EnumRfc1766_create(LANGID LangId, IEnumRfc1766 **ppEnum) { HeapFree(GetProcessHeap(), 0, data.info); HeapFree(GetProcessHeap(), 0, rfc); - return FALSE; + return E_FAIL; } rfc->info = data.info; @@ -3007,9 +3007,6 @@ exit: return hr; } -/* - * TODO: handle dwFlag and lpFallBack -*/ static HRESULT WINAPI fnIMultiLanguage2_ConvertStringToUnicodeEx( IMultiLanguage3* iface, DWORD* pdwMode, @@ -3021,7 +3018,10 @@ static HRESULT WINAPI fnIMultiLanguage2_ConvertStringToUnicodeEx( DWORD dwFlag, WCHAR* lpFallBack) { - FIXME("\n"); + if (dwFlag || lpFallBack) + FIXME("Ignoring dwFlag (0x%x/%d) and lpFallBack (%p)\n", + dwFlag, dwFlag, lpFallBack); + return ConvertINetMultiByteToUnicode(pdwMode, dwEncoding, pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize); } From 1511347fdc1d5fa83e74eab4a6db6b16c9f236bd Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Wed, 10 Mar 2010 17:03:25 +0000 Subject: [PATCH 24/64] Sync mscms, msg711.acm, msgm32.acm, msimtf. msnet32, msrle32, mssip32, msvcrt20, msvfw32, msvidc32 and nddeapi to Wine 1.1.40 Even more will come. svn path=/trunk/; revision=46063 --- reactos/dll/win32/mscms/profile.c | 5 +- reactos/dll/win32/msg711.acm/msg711.c | 18 +- reactos/dll/win32/msgsm32.acm/msgsm32.c | 2 +- reactos/dll/win32/msimtf/activeimmapp.c | 8 +- reactos/dll/win32/msimtf/main.c | 1 - reactos/dll/win32/msnet32/msnet_main.c | 5 + reactos/dll/win32/msrle32/msrle_Bg.rc | 2 + reactos/dll/win32/msrle32/msrle_Cs.rc | 2 + reactos/dll/win32/msrle32/msrle_Da.rc | 2 + reactos/dll/win32/msrle32/msrle_De.rc | 8 +- reactos/dll/win32/msrle32/msrle_En.rc | 8 +- reactos/dll/win32/msrle32/msrle_Es.rc | 2 + reactos/dll/win32/msrle32/msrle_Fr.rc | 11 +- reactos/dll/win32/msrle32/msrle_Hu.rc | 2 + reactos/dll/win32/msrle32/msrle_It.rc | 2 + reactos/dll/win32/msrle32/msrle_Ja.rc | 4 +- reactos/dll/win32/msrle32/msrle_Ko.rc | 2 + reactos/dll/win32/msrle32/msrle_Lt.rc | 33 +++ reactos/dll/win32/msrle32/msrle_Nl.rc | 2 + reactos/dll/win32/msrle32/msrle_No.rc | 2 + reactos/dll/win32/msrle32/msrle_Pl.rc | 2 + reactos/dll/win32/msrle32/msrle_Pt.rc | 2 + reactos/dll/win32/msrle32/msrle_Ro.rc | 4 +- reactos/dll/win32/msrle32/msrle_Ru.rc | 9 +- reactos/dll/win32/msrle32/msrle_Si.rc | 4 +- reactos/dll/win32/msrle32/msrle_Sv.rc | 2 + reactos/dll/win32/msrle32/msrle_Tr.rc | 2 + reactos/dll/win32/msrle32/msrle_Uk.rc | 34 +++ reactos/dll/win32/msrle32/rsrc.rc | 16 +- reactos/dll/win32/mssip32/main.c | 18 ++ reactos/dll/win32/mssip32/mssip32.spec | 4 +- reactos/dll/win32/msvcrt20/msvcrt20.spec | 6 +- reactos/dll/win32/msvfw32/drawdib.c | 2 +- reactos/dll/win32/msvfw32/msvfw32_Da.rc | 2 + reactos/dll/win32/msvfw32/msvfw32_De.rc | 16 +- reactos/dll/win32/msvfw32/msvfw32_En.rc | 2 + reactos/dll/win32/msvfw32/msvfw32_Es.rc | 4 + reactos/dll/win32/msvfw32/msvfw32_Fr.rc | 39 ++-- reactos/dll/win32/msvfw32/msvfw32_Hu.rc | 2 + reactos/dll/win32/msvfw32/msvfw32_It.rc | 56 +++++ reactos/dll/win32/msvfw32/msvfw32_Ko.rc | 2 + reactos/dll/win32/msvfw32/msvfw32_Lt.rc | 56 +++++ reactos/dll/win32/msvfw32/msvfw32_Nl.rc | 2 + reactos/dll/win32/msvfw32/msvfw32_No.rc | 2 + reactos/dll/win32/msvfw32/msvfw32_Pl.rc | 2 + reactos/dll/win32/msvfw32/msvfw32_Pt.rc | 2 + reactos/dll/win32/msvfw32/msvfw32_Ru.rc | 27 ++- reactos/dll/win32/msvfw32/msvfw32_Si.rc | 4 +- reactos/dll/win32/msvfw32/msvfw32_Sv.rc | 2 + reactos/dll/win32/msvfw32/msvfw32_Tr.rc | 2 + reactos/dll/win32/msvfw32/msvfw32_Uk.rc | 57 +++++ reactos/dll/win32/msvfw32/msvfw32_Zh.rc | 4 +- reactos/dll/win32/msvfw32/msvideo_main.c | 220 ++++++++---------- reactos/dll/win32/msvfw32/msvideo_private.h | 18 +- reactos/dll/win32/msvfw32/rsrc.rc | 15 +- reactos/dll/win32/msvidc32/msvidc32_Da.rc | 2 + reactos/dll/win32/msvidc32/msvidc32_De.rc | 4 + reactos/dll/win32/msvidc32/msvidc32_En.rc | 2 + reactos/dll/win32/msvidc32/msvidc32_Fr.rc | 7 +- reactos/dll/win32/msvidc32/msvidc32_Hu.rc | 2 + reactos/dll/win32/msvidc32/msvidc32_Ja.rc | 30 +++ reactos/dll/win32/msvidc32/msvidc32_Ko.rc | 2 + reactos/dll/win32/msvidc32/msvidc32_Lt.rc | 30 +++ reactos/dll/win32/msvidc32/msvidc32_Nl.rc | 2 + reactos/dll/win32/msvidc32/msvidc32_No.rc | 2 + reactos/dll/win32/msvidc32/msvidc32_Pl.rc | 2 + reactos/dll/win32/msvidc32/msvidc32_Pt.rc | 2 + reactos/dll/win32/msvidc32/msvidc32_Ro.rc | 4 + reactos/dll/win32/msvidc32/msvidc32_Ru.rc | 7 +- reactos/dll/win32/msvidc32/msvidc32_Si.rc | 4 +- reactos/dll/win32/msvidc32/msvidc32_Sv.rc | 2 + reactos/dll/win32/msvidc32/msvidc32_Tr.rc | 2 + reactos/dll/win32/msvidc32/msvidc32_Uk.rc | 31 +++ reactos/dll/win32/msvidc32/msvidc32_private.h | 2 + reactos/dll/win32/msvidc32/msvideo1.c | 8 +- reactos/dll/win32/msvidc32/rsrc.rc | 13 +- reactos/dll/win32/nddeapi/nddeapi.spec | 56 ++--- reactos/include/psdk/vfw.h | 2 +- 78 files changed, 714 insertions(+), 266 deletions(-) create mode 100644 reactos/dll/win32/msrle32/msrle_Lt.rc create mode 100644 reactos/dll/win32/msrle32/msrle_Uk.rc create mode 100644 reactos/dll/win32/msvfw32/msvfw32_It.rc create mode 100644 reactos/dll/win32/msvfw32/msvfw32_Lt.rc create mode 100644 reactos/dll/win32/msvfw32/msvfw32_Uk.rc create mode 100644 reactos/dll/win32/msvidc32/msvidc32_Ja.rc create mode 100644 reactos/dll/win32/msvidc32/msvidc32_Lt.rc create mode 100644 reactos/dll/win32/msvidc32/msvidc32_Uk.rc diff --git a/reactos/dll/win32/mscms/profile.c b/reactos/dll/win32/mscms/profile.c index 1c6811e0689..c9a5b42b6bd 100644 --- a/reactos/dll/win32/mscms/profile.c +++ b/reactos/dll/win32/mscms/profile.c @@ -660,8 +660,9 @@ BOOL WINAPI GetStandardColorSpaceProfileW( PCWSTR machine, DWORD id, PWSTR profi GetColorDirectoryW( machine, rgbprofile, &len ); switch (id) - { - case SPACE_RGB: /* 'RGB ' */ + case LCS_sRGB: + case LCS_WINDOWS_COLOR_SPACE: /* FIXME */ + { lstrcatW( rgbprofile, rgbprofilefile ); len = lstrlenW( rgbprofile ) * sizeof(WCHAR); diff --git a/reactos/dll/win32/msg711.acm/msg711.c b/reactos/dll/win32/msg711.acm/msg711.c index 203942ddcb1..d527e91788c 100644 --- a/reactos/dll/win32/msg711.acm/msg711.c +++ b/reactos/dll/win32/msg711.acm/msg711.c @@ -832,16 +832,16 @@ static LRESULT G711_FormatSuggest(PACMDRVFORMATSUGGEST adfs) switch (adfs->pwfxDst->wFormatTag) { case WAVE_FORMAT_PCM: - adfs->pwfxDst->nBlockAlign = adfs->pwfxDst->nChannels; + adfs->pwfxDst->nBlockAlign = adfs->pwfxDst->nChannels * 2; adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxDst->nBlockAlign; break; case WAVE_FORMAT_ALAW: - adfs->pwfxDst->nBlockAlign = adfs->pwfxDst->nChannels * 2; - adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxSrc->nChannels * 2; + adfs->pwfxDst->nBlockAlign = adfs->pwfxDst->nChannels; + adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxSrc->nChannels; break; case WAVE_FORMAT_MULAW: - adfs->pwfxDst->nBlockAlign = adfs->pwfxDst->nChannels * 2; - adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxSrc->nChannels * 2; + adfs->pwfxDst->nBlockAlign = adfs->pwfxDst->nChannels; + adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxSrc->nChannels; break; default: FIXME("\n"); @@ -993,13 +993,13 @@ static LRESULT G711_StreamSize(const ACMDRVSTREAMINSTANCE *adsi, PACMDRVSTREAMSI (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ALAW || adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MULAW)) { - adss->cbSrcLength = adss->cbDstLength / 2; + adss->cbSrcLength = adss->cbDstLength * 2; } else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW || adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW) && adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) { - adss->cbSrcLength = adss->cbDstLength * 2; + adss->cbSrcLength = adss->cbDstLength / 2; } else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW || adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW) && @@ -1019,13 +1019,13 @@ static LRESULT G711_StreamSize(const ACMDRVSTREAMINSTANCE *adsi, PACMDRVSTREAMSI (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ALAW || adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MULAW)) { - adss->cbDstLength = adss->cbSrcLength * 2; + adss->cbDstLength = adss->cbSrcLength / 2; } else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW || adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW) && adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) { - adss->cbDstLength = adss->cbSrcLength / 2; + adss->cbDstLength = adss->cbSrcLength * 2; } else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW || adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW) && diff --git a/reactos/dll/win32/msgsm32.acm/msgsm32.c b/reactos/dll/win32/msgsm32.acm/msgsm32.c index ad86bc1c438..e760ac3a0ed 100644 --- a/reactos/dll/win32/msgsm32.acm/msgsm32.c +++ b/reactos/dll/win32/msgsm32.acm/msgsm32.c @@ -381,7 +381,7 @@ static LRESULT GSM_StreamOpen(PACMDRVSTREAMINSTANCE adsi) return MMSYSERR_NOMEM; if (pgsm_option(r, GSM_OPT_WAV49, &used) < 0) { - FIXME("Your libgsm library is doesn't support GSM_OPT_WAV49\n"); + FIXME("Your libgsm library doesn't support GSM_OPT_WAV49\n"); FIXME("Please recompile libgsm with WAV49 support\n"); pgsm_destroy(r); return MMSYSERR_NOTSUPPORTED; diff --git a/reactos/dll/win32/msimtf/activeimmapp.c b/reactos/dll/win32/msimtf/activeimmapp.c index bdff2608730..73ce0758c70 100644 --- a/reactos/dll/win32/msimtf/activeimmapp.c +++ b/reactos/dll/win32/msimtf/activeimmapp.c @@ -642,27 +642,27 @@ static HRESULT WINAPI ActiveIMMApp_UnregisterWordW(IActiveIMMApp* This, static HRESULT WINAPI ActiveIMMApp_Activate(IActiveIMMApp* This, BOOL fRestoreLayout) { - //FIXME("Stub\n"); + FIXME("Stub\n"); return S_OK; } static HRESULT WINAPI ActiveIMMApp_Deactivate(IActiveIMMApp* This) { - //FIXME("Stub\n"); + FIXME("Stub\n"); return S_OK; } static HRESULT WINAPI ActiveIMMApp_OnDefWindowProc(IActiveIMMApp* This, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) { - //FIXME("Stub (%p %x %lx %lx)\n",hWnd,Msg,wParam,lParam); + FIXME("Stub (%p %x %lx %lx)\n",hWnd,Msg,wParam,lParam); return E_FAIL; } static HRESULT WINAPI ActiveIMMApp_FilterClientWindows(IActiveIMMApp* This, ATOM *aaClassList, UINT uSize) { - //FIXME("Stub\n"); + FIXME("Stub\n"); return S_OK; } diff --git a/reactos/dll/win32/msimtf/main.c b/reactos/dll/win32/msimtf/main.c index 8e24a4c4837..6b8957ba391 100644 --- a/reactos/dll/win32/msimtf/main.c +++ b/reactos/dll/win32/msimtf/main.c @@ -151,7 +151,6 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) */ HRESULT WINAPI DllCanUnloadNow(void) { - FIXME("()\n"); return S_FALSE; } diff --git a/reactos/dll/win32/msnet32/msnet_main.c b/reactos/dll/win32/msnet32/msnet_main.c index 7c759002dfe..1ffef5097b4 100644 --- a/reactos/dll/win32/msnet32/msnet_main.c +++ b/reactos/dll/win32/msnet32/msnet_main.c @@ -1,4 +1,9 @@ /* + * Microsoft Network API implementation + * + * Copyright 2003 Rein Klazes + * Copyright 2006 Alexandre Julliard + * * 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 diff --git a/reactos/dll/win32/msrle32/msrle_Bg.rc b/reactos/dll/win32/msrle32/msrle_Bg.rc index 7c0d4488a57..5073f0bf375 100644 --- a/reactos/dll/win32/msrle32/msrle_Bg.rc +++ b/reactos/dll/win32/msrle32/msrle_Bg.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msrle32/msrle_Cs.rc b/reactos/dll/win32/msrle32/msrle_Cs.rc index 51fb1dfbef8..a4a6c2f6e49 100644 --- a/reactos/dll/win32/msrle32/msrle_Cs.rc +++ b/reactos/dll/win32/msrle32/msrle_Cs.rc @@ -20,6 +20,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_CZECH, SUBLANG_DEFAULT /* Czech strings in CP1250 */ diff --git a/reactos/dll/win32/msrle32/msrle_Da.rc b/reactos/dll/win32/msrle32/msrle_Da.rc index c3ea57b4f11..4ab40e3b048 100644 --- a/reactos/dll/win32/msrle32/msrle_Da.rc +++ b/reactos/dll/win32/msrle32/msrle_Da.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_DANISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msrle32/msrle_De.rc b/reactos/dll/win32/msrle32/msrle_De.rc index c5f4954e2ef..0480cfbd104 100644 --- a/reactos/dll/win32/msrle32/msrle_De.rc +++ b/reactos/dll/win32/msrle32/msrle_De.rc @@ -1,7 +1,7 @@ /* * German resource file for MS-RLE * - * Copyright 2002 Michael Günnewig + * Copyright 2002 Michael Günnewig * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,11 +18,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + +#pragma code_page(65001) + LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE { IDS_NAME "WINE-MS-RLE" IDS_DESCRIPTION "Wine MS-RLE Videodekoder" - IDS_ABOUT "Wine MS-RLE Videodekoder\nCopyright 2002 by Michael Günnewig" + IDS_ABOUT "Wine MS-RLE Videodekoder\nCopyright 2002 by Michael Günnewig" } diff --git a/reactos/dll/win32/msrle32/msrle_En.rc b/reactos/dll/win32/msrle32/msrle_En.rc index 030a98a3aa5..e95f395a70e 100644 --- a/reactos/dll/win32/msrle32/msrle_En.rc +++ b/reactos/dll/win32/msrle32/msrle_En.rc @@ -1,7 +1,7 @@ /* * English resource file for MS-RLE * - * Copyright 2002 Michael Günnewig + * Copyright 2002 Michael Günnewig * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,11 +18,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + +#pragma code_page(65001) + LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { IDS_NAME "WINE-MS-RLE" IDS_DESCRIPTION "Wine MS-RLE video codec" - IDS_ABOUT "Wine MS-RLE video codec\nCopyright 2002 by Michael Günnewig" + IDS_ABOUT "Wine MS-RLE video codec\nCopyright 2002 by Michael Günnewig" } diff --git a/reactos/dll/win32/msrle32/msrle_Es.rc b/reactos/dll/win32/msrle32/msrle_Es.rc index ca418cb7594..edb62148113 100644 --- a/reactos/dll/win32/msrle32/msrle_Es.rc +++ b/reactos/dll/win32/msrle32/msrle_Es.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msrle32/msrle_Fr.rc b/reactos/dll/win32/msrle32/msrle_Fr.rc index e6eb31423f2..f45892c7d55 100644 --- a/reactos/dll/win32/msrle32/msrle_Fr.rc +++ b/reactos/dll/win32/msrle32/msrle_Fr.rc @@ -1,7 +1,7 @@ /* * French resource file for MS-RLE * - * Copyright 2002 Michael Günnewig + * Copyright 2002 Michael Günnewig * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,11 +18,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE { IDS_NAME "WINE-MS-RLE" - IDS_DESCRIPTION "Wine: décodeur/encodeur vidéo MS-RLE" - IDS_ABOUT "Wine: décodeur/encodeur vidéo MS-RLE\nCopyright 2002 par Michael Günnewig" + IDS_DESCRIPTION "Wine : codec vidéo MS-RLE" + IDS_ABOUT "Wine : codec vidéo MS-RLE\nCopyright 2002 par Michael Günnewig" } diff --git a/reactos/dll/win32/msrle32/msrle_Hu.rc b/reactos/dll/win32/msrle32/msrle_Hu.rc index 95016acb4d2..3f4b581f4cf 100644 --- a/reactos/dll/win32/msrle32/msrle_Hu.rc +++ b/reactos/dll/win32/msrle32/msrle_Hu.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msrle32/msrle_It.rc b/reactos/dll/win32/msrle32/msrle_It.rc index 695a78285f8..0b21705355c 100644 --- a/reactos/dll/win32/msrle32/msrle_It.rc +++ b/reactos/dll/win32/msrle32/msrle_It.rc @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msrle32/msrle_Ja.rc b/reactos/dll/win32/msrle32/msrle_Ja.rc index c2866a155c1..e1ec7bb2b10 100644 --- a/reactos/dll/win32/msrle32/msrle_Ja.rc +++ b/reactos/dll/win32/msrle32/msrle_Ja.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + /* UTF-8 */ #pragma code_page(65001) @@ -29,5 +31,3 @@ STRINGTABLE DISCARDABLE IDS_DESCRIPTION "Wine MS-RLE ビデオコーデック" IDS_ABOUT "Wine MS-RLE ビデオコーデック\nCopyright 2002 by Michael Günewig" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/msrle32/msrle_Ko.rc b/reactos/dll/win32/msrle32/msrle_Ko.rc index 3f9d137b009..f6c38b37a96 100644 --- a/reactos/dll/win32/msrle32/msrle_Ko.rc +++ b/reactos/dll/win32/msrle32/msrle_Ko.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msrle32/msrle_Lt.rc b/reactos/dll/win32/msrle32/msrle_Lt.rc new file mode 100644 index 00000000000..f399f544060 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Lt.rc @@ -0,0 +1,33 @@ +/* + * Lithuanian resource file for MS-RLE + * + * Copyright 2009 Aurimas FiÅ¡eras + * + * 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 "msrle_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE vaizdo kodekas" + IDS_ABOUT "Wine MS-RLE vaizdo kodekas\nAutoriaus teisÄ—s Michael Günnewig, 2002" +} diff --git a/reactos/dll/win32/msrle32/msrle_Nl.rc b/reactos/dll/win32/msrle32/msrle_Nl.rc index f98f5fd9835..ba0419c48dd 100644 --- a/reactos/dll/win32/msrle32/msrle_Nl.rc +++ b/reactos/dll/win32/msrle32/msrle_Nl.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msrle32/msrle_No.rc b/reactos/dll/win32/msrle32/msrle_No.rc index 411e4590447..6b079f9ed47 100644 --- a/reactos/dll/win32/msrle32/msrle_No.rc +++ b/reactos/dll/win32/msrle32/msrle_No.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msrle32/msrle_Pl.rc b/reactos/dll/win32/msrle32/msrle_Pl.rc index 013fea5a0ed..9394da1aab2 100644 --- a/reactos/dll/win32/msrle32/msrle_Pl.rc +++ b/reactos/dll/win32/msrle32/msrle_Pl.rc @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_POLISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msrle32/msrle_Pt.rc b/reactos/dll/win32/msrle32/msrle_Pt.rc index cc74b38e981..33a646205ec 100644 --- a/reactos/dll/win32/msrle32/msrle_Pt.rc +++ b/reactos/dll/win32/msrle32/msrle_Pt.rc @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msrle32/msrle_Ro.rc b/reactos/dll/win32/msrle32/msrle_Ro.rc index 64366c36a91..16aa0e9f985 100644 --- a/reactos/dll/win32/msrle32/msrle_Ro.rc +++ b/reactos/dll/win32/msrle32/msrle_Ro.rc @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL #pragma code_page(65001) @@ -27,5 +29,3 @@ STRINGTABLE DISCARDABLE IDS_DESCRIPTION "Codecul video Wine MS-RLE" IDS_ABOUT "Codecul video Wine MS-RLE\nCopyright 2002 by Michael Günnewig" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/msrle32/msrle_Ru.rc b/reactos/dll/win32/msrle32/msrle_Ru.rc index 4f8bd56b158..3b73391ef6c 100644 --- a/reactos/dll/win32/msrle32/msrle_Ru.rc +++ b/reactos/dll/win32/msrle32/msrle_Ru.rc @@ -18,11 +18,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { IDS_NAME "WINE-MS-RLE" - IDS_DESCRIPTION "Âèäåî êîäåê Wine MS-RLE" - IDS_ABOUT "Âèäåî êîäåê Wine MS-RLE\nCopyright 2002 by Michael Günnewig" + IDS_DESCRIPTION "Видео кодек Wine MS-RLE" + IDS_ABOUT "Видео кодек Wine MS-RLE\nCopyright 2002 by Michael GÑŒnnewig" } diff --git a/reactos/dll/win32/msrle32/msrle_Si.rc b/reactos/dll/win32/msrle32/msrle_Si.rc index eeb23739f7d..346569bf5fd 100644 --- a/reactos/dll/win32/msrle32/msrle_Si.rc +++ b/reactos/dll/win32/msrle32/msrle_Si.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + #pragma code_page(65001) LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT @@ -28,5 +30,3 @@ STRINGTABLE DISCARDABLE IDS_DESCRIPTION "Wine MS-RLE video kodek" IDS_ABOUT "Wine MS-RLE video kodek\nCopyright 2002 by Michael Günnewig" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/msrle32/msrle_Sv.rc b/reactos/dll/win32/msrle32/msrle_Sv.rc index fba656a33d0..4570e609ad5 100644 --- a/reactos/dll/win32/msrle32/msrle_Sv.rc +++ b/reactos/dll/win32/msrle32/msrle_Sv.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msrle32/msrle_Tr.rc b/reactos/dll/win32/msrle32/msrle_Tr.rc index 36cee7531f1..8decf375762 100644 --- a/reactos/dll/win32/msrle32/msrle_Tr.rc +++ b/reactos/dll/win32/msrle32/msrle_Tr.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msrle_private.h" + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msrle32/msrle_Uk.rc b/reactos/dll/win32/msrle32/msrle_Uk.rc new file mode 100644 index 00000000000..19c4d663c8e --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Uk.rc @@ -0,0 +1,34 @@ +/* + * Ukrainian resource file for MS-RLE + * + * Copyright 2002 Michael GГјnnewig + * Copyright 2010 Igor Paliychuk + * + * 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 "msrle_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Відео кодек Wine MS-RLE" + IDS_ABOUT "Відео кодек Wine MS-RLE\nCopyright 2002 by Michael GГјnnewig" +} diff --git a/reactos/dll/win32/msrle32/rsrc.rc b/reactos/dll/win32/msrle32/rsrc.rc index 6d3ff958153..fc404a110c0 100644 --- a/reactos/dll/win32/msrle32/rsrc.rc +++ b/reactos/dll/win32/msrle32/rsrc.rc @@ -34,20 +34,24 @@ #include "msrle_Bg.rc" #include "msrle_Cs.rc" #include "msrle_Da.rc" -#include "msrle_De.rc" -#include "msrle_En.rc" #include "msrle_Es.rc" -#include "msrle_Fr.rc" #include "msrle_Hu.rc" #include "msrle_It.rc" -#include "msrle_Ja.rc" #include "msrle_Ko.rc" #include "msrle_Nl.rc" #include "msrle_No.rc" #include "msrle_Pl.rc" #include "msrle_Pt.rc" +#include "msrle_Sv.rc" +#include "msrle_Tr.rc" + +/* UTF-8 */ +#include "msrle_De.rc" +#include "msrle_En.rc" +#include "msrle_Fr.rc" +#include "msrle_Ja.rc" +#include "msrle_Lt.rc" #include "msrle_Ro.rc" #include "msrle_Ru.rc" #include "msrle_Si.rc" -#include "msrle_Sv.rc" -#include "msrle_Tr.rc" +#include "msrle_Uk.rc" diff --git a/reactos/dll/win32/mssip32/main.c b/reactos/dll/win32/mssip32/main.c index 91ec17f9303..7d137018114 100644 --- a/reactos/dll/win32/mssip32/main.c +++ b/reactos/dll/win32/mssip32/main.c @@ -44,3 +44,21 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) } return TRUE; } + +/***************************************************** + * DllRegisterServer (MSSIP32.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + FIXME("Not implemented.\n"); + return E_UNEXPECTED; +} + +/***************************************************** + * DllUnregisterServer (MSSIP32.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + FIXME("Not implemented.\n"); + return E_UNEXPECTED; +} diff --git a/reactos/dll/win32/mssip32/mssip32.spec b/reactos/dll/win32/mssip32/mssip32.spec index 0c09bfbdbe2..b7fd8690214 100644 --- a/reactos/dll/win32/mssip32/mssip32.spec +++ b/reactos/dll/win32/mssip32/mssip32.spec @@ -5,5 +5,5 @@ @ stub CryptSIPPutSignedDataMsg @ stub CryptSIPRemoveSignedDataMsg @ stub CryptSIPVerifyIndirectData -@ stub DllRegisterServer -@ stub DllUnregisterServer +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/reactos/dll/win32/msvcrt20/msvcrt20.spec b/reactos/dll/win32/msvcrt20/msvcrt20.spec index bc0a3217090..91e633c3338 100644 --- a/reactos/dll/win32/msvcrt20/msvcrt20.spec +++ b/reactos/dll/win32/msvcrt20/msvcrt20.spec @@ -225,7 +225,7 @@ @ stub ??_Gstrstream@@UAEPAXI@Z # @ stub ??_Gstrstreambuf@@UAEPAXI@Z # @ cdecl ?_query_new_handler@@YAP6AHI@ZXZ() msvcrt.?_query_new_handler@@YAP6AHI@ZXZ -@ cdecl ?_query_new_mode@@YAHXZ() msvcrt.?_query_new_mode@@YAHXZ +@ cdecl ?_query_new_mode@@YAHXZ() msvcrt.?_query_new_mode@@YAHXZ @ cdecl ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z(ptr) msvcrt.?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z @ cdecl ?_set_new_mode@@YAHH@Z(long) msvcrt.?_set_new_mode@@YAHH@Z @ cdecl ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z(ptr) msvcrt.?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z @@ -436,7 +436,7 @@ @ stub ?xalloc@ios@@SAHXZ # @ stub ?xsgetn@streambuf@@UAEHPADH@Z # @ stub ?xsputn@streambuf@@UAEHPBDH@Z # -@ stub $I10_OUTPUT # +@ cdecl $I10_OUTPUT() msvcrt.$I10_OUTPUT @ cdecl -arch=i386 _CIacos() msvcrt._CIacos @ cdecl -arch=i386 _CIasin() msvcrt._CIasin @ cdecl -arch=i386 _CIatan() msvcrt._CIatan @@ -464,7 +464,7 @@ @ cdecl __dllonexit(ptr ptr ptr) msvcrt.__dllonexit @ cdecl __doserrno() msvcrt.__doserrno @ cdecl __fpecode() msvcrt.__fpecode -@ cdecl __getmainargs(ptr ptr ptr long ptr) MSVCRT20__getmainargs +@ cdecl __getmainargs(ptr ptr ptr long long) MSVCRT20__getmainargs @ extern __initenv msvcrt.__initenv @ cdecl __isascii(long) msvcrt.__isascii @ cdecl __iscsym(long) msvcrt.__iscsym diff --git a/reactos/dll/win32/msvfw32/drawdib.c b/reactos/dll/win32/msvfw32/drawdib.c index 902f0ca0664..9877e628bc7 100644 --- a/reactos/dll/win32/msvfw32/drawdib.c +++ b/reactos/dll/win32/msvfw32/drawdib.c @@ -72,7 +72,7 @@ static WINE_HDD* MSVIDEO_GetHddPtr(HDRAWDIB hd) return hdd; } -static DWORD HDD_HandleRef = 1; +static UINT_PTR HDD_HandleRef = 1; /*********************************************************************** * DrawDibOpen [MSVFW32.@] diff --git a/reactos/dll/win32/msvfw32/msvfw32_Da.rc b/reactos/dll/win32/msvfw32/msvfw32_Da.rc index 32b54892a75..20d60e23455 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Da.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Da.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + LANGUAGE LANG_DANISH, SUBLANG_DEFAULT ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 diff --git a/reactos/dll/win32/msvfw32/msvfw32_De.rc b/reactos/dll/win32/msvfw32/msvfw32_De.rc index 29b5f4b7187..b697eb1aa14 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_De.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_De.rc @@ -17,6 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + +#pragma code_page(65001) + LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 @@ -30,16 +34,16 @@ FONT 8, "MS Shell Dlg" LTEXT "&Komprimierer:",-1,9,6,105,8 COMBOBOX 880,9,16,111,67,CBS_DROPDOWNLIST|WS_VSCROLL|WS_TABSTOP - PUSHBUTTON "Kon&figurieren...",882,129,36,49,14 - PUSHBUTTON "&Über...",883,129,52,49,14 + PUSHBUTTON "Kon&figurieren",882,129,36,49,14 + PUSHBUTTON "&Über...",883,129,52,49,14 SCROLLBAR 884,9,44,111,9,WS_TABSTOP - LTEXT "Komprimierungsqualität:",886,9,34,80,8 + LTEXT "Komprimierungsqualität:",886,9,34,80,8 - CONTROL "&Key Frame aller",887,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,66,12 + CONTROL "&Key Frame alle",887,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,66,12 EDITTEXT 888,78,60,22,12 - LTEXT "frames",889,103,62,26,10 + LTEXT "Frames",889,103,62,26,10 CONTROL "&Datenrate",894,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,76,66,12 EDITTEXT 895,78,76,22,12 @@ -48,5 +52,5 @@ FONT 8, "MS Shell Dlg" STRINGTABLE DISCARDABLE { - IDS_FULLFRAMES "Vollständige Frames (Unkomprimiert)" + IDS_FULLFRAMES "Vollständige Frames (Unkomprimiert)" } diff --git a/reactos/dll/win32/msvfw32/msvfw32_En.rc b/reactos/dll/win32/msvfw32/msvfw32_En.rc index 1a563dd9780..f3ee7357196 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_En.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_En.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 diff --git a/reactos/dll/win32/msvfw32/msvfw32_Es.rc b/reactos/dll/win32/msvfw32/msvfw32_Es.rc index aa4d3f0159b..c5eb635cb8f 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Es.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Es.rc @@ -17,6 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + +#pragma code_page(65001) + LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 diff --git a/reactos/dll/win32/msvfw32/msvfw32_Fr.rc b/reactos/dll/win32/msvfw32/msvfw32_Fr.rc index 9318ee4b760..87d61cc0088 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Fr.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Fr.rc @@ -16,36 +16,41 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL -ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 +ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 208, 95 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Compression vidéo" +CAPTION "Compression vidéo" FONT 8, "MS Shell Dlg" { - DEFPUSHBUTTON "OK",IDOK,129,2,49,14 - PUSHBUTTON "Annuler",IDCANCEL,129,18,49,14 + DEFPUSHBUTTON "OK",IDOK,150,2,49,14 + PUSHBUTTON "Annuler",IDCANCEL,150,18,49,14 - LTEXT "&Compresseur :",-1,9,6,105,8 - COMBOBOX 880,9,16,111,67,CBS_DROPDOWNLIST|WS_VSCROLL|WS_TABSTOP + LTEXT "&Compresseur :",-1,9,6,131,8 + COMBOBOX 880,9,16,135,15,CBS_DROPDOWNLIST|WS_VSCROLL|WS_TABSTOP - PUSHBUTTON "Con&figurer...",882,129,36,49,14 - PUSHBUTTON "À &propos",883,129,52,49,14 + PUSHBUTTON "Con&figurer...",882,150,36,49,14 + PUSHBUTTON "À &propos",883,150,52,49,14 - SCROLLBAR 884,9,44,111,9,WS_TABSTOP + SCROLLBAR 884,9,44,133,9,WS_TABSTOP - LTEXT "&Qualité de compression :",886,9,34,80,8 + LTEXT "&Qualité de compression :",886,9,34,131,8 - CONTROL "Image &clé toutes les",887,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,66,12 - EDITTEXT 888,78,60,22,12 - LTEXT "images",889,103,62,26,10 + CONTROL "Image &clé toutes les",887,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,77,12 + EDITTEXT 888,89,60,22,12 + LTEXT "images",889,115,63,26,10 - CONTROL "&Débit de données",894,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,76,66,12 - EDITTEXT 895,78,76,22,12 - LTEXT "Kio/sec",896,102,78,26,10 + CONTROL "&Débit de données",894,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,76,77,12 + EDITTEXT 895,89,76,22,12 + LTEXT "Kio/sec",896,115,78,26,10 } STRINGTABLE DISCARDABLE { - IDS_FULLFRAMES "Images complètes (non compressées)" + IDS_FULLFRAMES "Images complètes (non compressées)" } diff --git a/reactos/dll/win32/msvfw32/msvfw32_Hu.rc b/reactos/dll/win32/msvfw32/msvfw32_Hu.rc index aa0eefcfc1c..e77b67fd543 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Hu.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Hu.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 diff --git a/reactos/dll/win32/msvfw32/msvfw32_It.rc b/reactos/dll/win32/msvfw32/msvfw32_It.rc new file mode 100644 index 00000000000..6f8ee4e4513 --- /dev/null +++ b/reactos/dll/win32/msvfw32/msvfw32_It.rc @@ -0,0 +1,56 @@ +/* + * Copyright 2010 Luca Bennati + * + * 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 "msvideo_private.h" + +/*UTF-8*/ +#pragma code_page(65001) + +LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL + +ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Compressione video" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK",IDOK,129,2,49,14 + PUSHBUTTON "Annulla",IDCANCEL,129,18,49,14 + + LTEXT "&Compressore:",-1,9,6,105,8 + COMBOBOX 880,9,16,111,67,CBS_DROPDOWNLIST|WS_VSCROLL|WS_TABSTOP + + PUSHBUTTON "Con&figura...",882,129,36,49,14 + PUSHBUTTON "&Informazioni...",883,129,52,49,14 + + SCROLLBAR 884,9,44,111,9,WS_TABSTOP + + LTEXT "&Qualità della compressione:",886,9,34,80,8 + + CONTROL "&Key Frame Every",887,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,66,12 + EDITTEXT 888,78,60,22,12 + LTEXT "frames",889,103,62,26,10 + + CONTROL "&Data Rate",894,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,76,66,12 + EDITTEXT 895,78,76,22,12 + LTEXT "KB/sec",896,102,78,26,10 +} + +STRINGTABLE DISCARDABLE +{ + IDS_FULLFRAMES "Frames completi (non compresso)" +} diff --git a/reactos/dll/win32/msvfw32/msvfw32_Ko.rc b/reactos/dll/win32/msvfw32/msvfw32_Ko.rc index 4d6527e93a2..72e999d96f4 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Ko.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Ko.rc @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 diff --git a/reactos/dll/win32/msvfw32/msvfw32_Lt.rc b/reactos/dll/win32/msvfw32/msvfw32_Lt.rc new file mode 100644 index 00000000000..c7432d3518f --- /dev/null +++ b/reactos/dll/win32/msvfw32/msvfw32_Lt.rc @@ -0,0 +1,56 @@ +/* + * Copyright 2009 Aurimas FiÅ¡eras + * + * 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 "msvideo_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL + +ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 192, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Vaizdų glaudinimas" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "Gerai",IDOK,129,2,54,14 + PUSHBUTTON "Atsisakyti",IDCANCEL,129,18,54,14 + + LTEXT "&Metodas:",-1,9,6,105,8 + COMBOBOX 880,9,16,111,67,CBS_DROPDOWNLIST|WS_VSCROLL|WS_TABSTOP + + PUSHBUTTON "Kon&figÅ«ruoti...",882,129,36,54,14 + PUSHBUTTON "&Apie...",883,129,52,54,14 + + SCROLLBAR 884,9,44,111,9,WS_TABSTOP + + LTEXT "Glaudinimo &kokybÄ—:",886,9,34,80,8 + + CONTROL "&Rakt. kadras kas",887,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,66,12 + EDITTEXT 888,78,60,22,12 + LTEXT "kadrų",889,103,62,26,10 + + CONTROL "&Duomenų sparta",894,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,76,66,12 + EDITTEXT 895,78,76,22,12 + LTEXT "KB/sek",896,102,78,26,10 +} + +STRINGTABLE DISCARDABLE +{ + IDS_FULLFRAMES "Pilni kadrai (neglaudinti)" +} diff --git a/reactos/dll/win32/msvfw32/msvfw32_Nl.rc b/reactos/dll/win32/msvfw32/msvfw32_Nl.rc index e1236f7c2c9..d82f860c400 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Nl.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Nl.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 diff --git a/reactos/dll/win32/msvfw32/msvfw32_No.rc b/reactos/dll/win32/msvfw32/msvfw32_No.rc index 41a24e393db..eb07aed3efb 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_No.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_No.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 diff --git a/reactos/dll/win32/msvfw32/msvfw32_Pl.rc b/reactos/dll/win32/msvfw32/msvfw32_Pl.rc index 53ee33cf28e..cb5a9eb6cb7 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Pl.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Pl.rc @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + LANGUAGE LANG_POLISH, SUBLANG_DEFAULT ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 207, 95 diff --git a/reactos/dll/win32/msvfw32/msvfw32_Pt.rc b/reactos/dll/win32/msvfw32/msvfw32_Pt.rc index 0640870f3c3..efd31191ad8 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Pt.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Pt.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 diff --git a/reactos/dll/win32/msvfw32/msvfw32_Ru.rc b/reactos/dll/win32/msvfw32/msvfw32_Ru.rc index 96c8a814d64..7acdb8ccc94 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Ru.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Ru.rc @@ -16,36 +16,41 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Ñæàòèå âèäåî" +CAPTION "Сжатие видео" FONT 8, "MS Shell Dlg" { DEFPUSHBUTTON "OK",IDOK,129,2,49,14 - PUSHBUTTON "Îòìåíà",IDCANCEL,129,18,49,14 + PUSHBUTTON "Отмена",IDCANCEL,129,18,49,14 - LTEXT "&Àëãîðèòì ñæàòèÿ:",-1,9,6,105,8 + LTEXT "&Ðлгоритм ÑжатиÑ:",-1,9,6,105,8 COMBOBOX 880,9,16,111,67,CBS_DROPDOWNLIST|WS_VSCROLL|WS_TABSTOP - PUSHBUTTON "&Íàñòðîéêè...",882,129,36,49,14 - PUSHBUTTON "&Èíôîðìàöèÿ...",883,129,52,49,14 + PUSHBUTTON "&ÐаÑтройки...",882,129,36,49,14 + PUSHBUTTON "&ИнформациÑ...",883,129,52,49,14 SCROLLBAR 884,9,44,111,9,WS_TABSTOP - LTEXT "&Êà÷åñòâî ñæàòèÿ:",886,9,34,80,8 + LTEXT "&КачеÑтво ÑжатиÑ:",886,9,34,80,8 - CONTROL "Êë&þ÷åâîé êàäð êàæäûå",887,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,66,12 + CONTROL "Кл&ючевой кадр каждые",887,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,66,12 EDITTEXT 888,78,60,22,12 - LTEXT "êàäðîâ",889,103,62,26,10 + LTEXT "кадров",889,103,62,26,10 - CONTROL "&Ïîòîê äàííûõ",894,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,76,66,12 + CONTROL "&Поток данных",894,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,76,66,12 EDITTEXT 895,78,76,22,12 - LTEXT "ÊÁ/ñåê",896,102,78,26,10 + LTEXT "КБ/Ñек",896,102,78,26,10 } STRINGTABLE DISCARDABLE { - IDS_FULLFRAMES "Êàäðû öåëèêîì (Áåç êîìïðåññèè)" + IDS_FULLFRAMES "Кадры целиком (Без компреÑÑии)" } diff --git a/reactos/dll/win32/msvfw32/msvfw32_Si.rc b/reactos/dll/win32/msvfw32/msvfw32_Si.rc index 05d1ba588ef..93fb1757082 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Si.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Si.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + #pragma code_page(65001) LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT @@ -51,5 +53,3 @@ STRINGTABLE DISCARDABLE { IDS_FULLFRAMES "Polne slike (nestisnjeno)" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/msvfw32/msvfw32_Sv.rc b/reactos/dll/win32/msvfw32/msvfw32_Sv.rc index 68f51677212..2461fce601e 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Sv.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Sv.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 diff --git a/reactos/dll/win32/msvfw32/msvfw32_Tr.rc b/reactos/dll/win32/msvfw32/msvfw32_Tr.rc index b9da7c20f0b..09635095b5b 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Tr.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Tr.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 diff --git a/reactos/dll/win32/msvfw32/msvfw32_Uk.rc b/reactos/dll/win32/msvfw32/msvfw32_Uk.rc new file mode 100644 index 00000000000..c9b1b67cf0f --- /dev/null +++ b/reactos/dll/win32/msvfw32/msvfw32_Uk.rc @@ -0,0 +1,57 @@ +/* + * Copyright 2005 Dmitry Timoshkov + * Copyright 2010 Igor Paliychuk + * + * 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 "msvideo_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT + +ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "СтиÑÐ½ÐµÐ½Ð½Ñ Ð’Ñ–Ð´ÐµÐ¾" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK",IDOK,129,2,49,14 + PUSHBUTTON "СкаÑувати",IDCANCEL,129,18,49,14 + + LTEXT "&Ðлгоритм ÑтиÑненнÑ:",-1,9,6,105,8 + COMBOBOX 880,9,16,111,67,CBS_DROPDOWNLIST|WS_VSCROLL|WS_TABSTOP + + PUSHBUTTON "Ðалаштува&ти...",882,129,36,49,14 + PUSHBUTTON "&ІнформаціÑ...",883,129,52,49,14 + + SCROLLBAR 884,9,44,111,9,WS_TABSTOP + + LTEXT "&ЯкіÑть СтиÑненнÑ:",886,9,34,80,8 + + CONTROL "&Ключовий кадр кожні",887,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,66,12 + EDITTEXT 888,78,60,22,12 + LTEXT "кадрів",889,103,62,26,10 + + CONTROL "&Потік даних",894,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,76,66,12 + EDITTEXT 895,78,76,22,12 + LTEXT "KB/sec",896,102,78,26,10 +} + +STRINGTABLE DISCARDABLE +{ + IDS_FULLFRAMES "Кадри повніÑтю (Без ÑтиÑненнÑ)" +} diff --git a/reactos/dll/win32/msvfw32/msvfw32_Zh.rc b/reactos/dll/win32/msvfw32/msvfw32_Zh.rc index 334fd6947f5..3ff0fc047f7 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Zh.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Zh.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvideo_private.h" + /* Chinese text is encoded in UTF-8 */ #pragma code_page(65001) @@ -88,5 +90,3 @@ STRINGTABLE DISCARDABLE { IDS_FULLFRAMES "全幀(未壓縮)" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/msvfw32/msvideo_main.c b/reactos/dll/win32/msvfw32/msvideo_main.c index 74832183eea..ae8d6d2f809 100644 --- a/reactos/dll/win32/msvfw32/msvideo_main.c +++ b/reactos/dll/win32/msvfw32/msvideo_main.c @@ -53,8 +53,6 @@ static inline const char *wine_dbgstr_fcc( DWORD fcc ) LOBYTE(HIWORD(fcc)), HIBYTE(HIWORD(fcc))); } -LRESULT (CALLBACK *pFnCallTo16)(HDRVR, HIC, UINT, LPARAM, LPARAM) = NULL; - static WINE_HIC* MSVIDEO_FirstHic /* = NULL */; typedef struct _reg_driver reg_driver; @@ -93,6 +91,92 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) return TRUE; } +/****************************************************************** + * MSVIDEO_SendMessage + * + * + */ +static LRESULT MSVIDEO_SendMessage(WINE_HIC* whic, UINT msg, DWORD_PTR lParam1, DWORD_PTR lParam2) +{ + LRESULT ret; + +#define XX(x) case x: TRACE("(%p,"#x",0x%08lx,0x%08lx)\n",whic,lParam1,lParam2); break + + switch (msg) { + /* DRV_* */ + XX(DRV_LOAD); + XX(DRV_ENABLE); + XX(DRV_OPEN); + XX(DRV_CLOSE); + XX(DRV_DISABLE); + XX(DRV_FREE); + /* ICM_RESERVED+X */ + XX(ICM_ABOUT); + XX(ICM_CONFIGURE); + XX(ICM_GET); + XX(ICM_GETINFO); + XX(ICM_GETDEFAULTQUALITY); + XX(ICM_GETQUALITY); + XX(ICM_GETSTATE); + XX(ICM_SETQUALITY); + XX(ICM_SET); + XX(ICM_SETSTATE); + /* ICM_USER+X */ + XX(ICM_COMPRESS_FRAMES_INFO); + XX(ICM_COMPRESS_GET_FORMAT); + XX(ICM_COMPRESS_GET_SIZE); + XX(ICM_COMPRESS_QUERY); + XX(ICM_COMPRESS_BEGIN); + XX(ICM_COMPRESS); + XX(ICM_COMPRESS_END); + XX(ICM_DECOMPRESS_GET_FORMAT); + XX(ICM_DECOMPRESS_QUERY); + XX(ICM_DECOMPRESS_BEGIN); + XX(ICM_DECOMPRESS); + XX(ICM_DECOMPRESS_END); + XX(ICM_DECOMPRESS_SET_PALETTE); + XX(ICM_DECOMPRESS_GET_PALETTE); + XX(ICM_DRAW_QUERY); + XX(ICM_DRAW_BEGIN); + XX(ICM_DRAW_GET_PALETTE); + XX(ICM_DRAW_START); + XX(ICM_DRAW_STOP); + XX(ICM_DRAW_END); + XX(ICM_DRAW_GETTIME); + XX(ICM_DRAW); + XX(ICM_DRAW_WINDOW); + XX(ICM_DRAW_SETTIME); + XX(ICM_DRAW_REALIZE); + XX(ICM_DRAW_FLUSH); + XX(ICM_DRAW_RENDERBUFFER); + XX(ICM_DRAW_START_PLAY); + XX(ICM_DRAW_STOP_PLAY); + XX(ICM_DRAW_SUGGESTFORMAT); + XX(ICM_DRAW_CHANGEPALETTE); + XX(ICM_GETBUFFERSWANTED); + XX(ICM_GETDEFAULTKEYFRAMERATE); + XX(ICM_DECOMPRESSEX_BEGIN); + XX(ICM_DECOMPRESSEX_QUERY); + XX(ICM_DECOMPRESSEX); + XX(ICM_DECOMPRESSEX_END); + XX(ICM_SET_STATUS_PROC); + default: + FIXME("(%p,0x%08x,0x%08lx,0x%08lx) unknown message\n",whic,msg,lParam1,lParam2); + } + +#undef XX + + if (whic->driverproc) { + /* dwDriverId parameter is the value returned by the DRV_OPEN */ + ret = whic->driverproc(whic->driverId, whic->hdrv, msg, lParam1, lParam2); + } else { + ret = SendDriverMessage(whic->hdrv, msg, lParam1, lParam2); + } + + TRACE(" -> 0x%08lx\n", ret); + return ret; +} + static int compare_fourcc(DWORD fcc1, DWORD fcc2) { char fcc_str1[4]; @@ -154,7 +238,7 @@ static BOOL enum_drivers(DWORD fccType, enum_handler_t handler, void* param) * * */ -WINE_HIC* MSVIDEO_GetHicPtr(HIC hic) +static WINE_HIC* MSVIDEO_GetHicPtr(HIC hic) { WINE_HIC* whic; @@ -310,7 +394,6 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) ICOPEN icopen; HDRVR hdrv; WINE_HIC* whic; - BOOL bIs16; static const WCHAR drv32W[] = {'d','r','i','v','e','r','s','3','2','\0'}; reg_driver* driver; @@ -327,7 +410,7 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) if (driver && driver->proc) /* The driver has been registered at runtime with its driverproc */ - return MSVIDEO_OpenFunction(fccType, fccHandler, wMode, driver->proc, 0); + return ICOpenFunction(fccType, fccHandler, wMode, driver->proc); /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the * same layout as ICOPEN @@ -358,13 +441,7 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) if (!hdrv) return 0; } - bIs16 = GetDriverFlags(hdrv) & 0x10000000; /* undocumented flag: WINE_GDF_16BIT */ - if (bIs16 && !pFnCallTo16) - { - FIXME("Got a 16 bit driver, but no 16 bit support in msvfw\n"); - return 0; - } whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC)); if (!whic) { @@ -372,13 +449,11 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) return FALSE; } whic->hdrv = hdrv; - /* FIXME: is the signature the real one ? */ - whic->driverproc = bIs16 ? (DRIVERPROC)pFnCallTo16 : NULL; - whic->driverproc16 = 0; + whic->driverproc = NULL; whic->type = fccType; whic->handler = fccHandler; - while (MSVIDEO_GetHicPtr(HIC_32(IC_HandleRef)) != NULL) IC_HandleRef++; - whic->hic = HIC_32(IC_HandleRef++); + while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++; + whic->hic = (HIC)(ULONG_PTR)IC_HandleRef++; whic->next = MSVIDEO_FirstHic; MSVIDEO_FirstHic = whic; @@ -387,16 +462,15 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) } /*********************************************************************** - * MSVIDEO_OpenFunction + * ICOpenFunction [MSVFW32.@] */ -HIC MSVIDEO_OpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, - DRIVERPROC lpfnHandler, DWORD lpfnHandler16) +HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, DRIVERPROC lpfnHandler) { ICOPEN icopen; WINE_HIC* whic; - TRACE("(%s,%s,%d,%p,%08x)\n", - wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode, lpfnHandler, lpfnHandler16); + TRACE("(%s,%s,%d,%p)\n", + wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode, lpfnHandler); icopen.dwSize = sizeof(ICOPEN); icopen.fccType = fccType; @@ -412,9 +486,8 @@ HIC MSVIDEO_OpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, if (!whic) return 0; whic->driverproc = lpfnHandler; - whic->driverproc16 = lpfnHandler16; - while (MSVIDEO_GetHicPtr(HIC_32(IC_HandleRef)) != NULL) IC_HandleRef++; - whic->hic = HIC_32(IC_HandleRef++); + while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++; + whic->hic = (HIC)(ULONG_PTR)IC_HandleRef++; whic->next = MSVIDEO_FirstHic; MSVIDEO_FirstHic = whic; @@ -447,14 +520,6 @@ HIC MSVIDEO_OpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, return whic->hic; } -/*********************************************************************** - * ICOpenFunction [MSVFW32.@] - */ -HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler) -{ - return MSVIDEO_OpenFunction(fccType, fccHandler, wMode, (DRIVERPROC)lpfnHandler, 0); -} - /*********************************************************************** * ICGetInfo [MSVFW32.@] */ @@ -680,8 +745,6 @@ DWORD VFWAPIV ICDecompress(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat, TRACE("(%p,%d,%p,%p,%p,%p)\n",hic,dwFlags,lpbiFormat,lpData,lpbi,lpBits); - TRACE("lpBits[0] == %x\n",((LPDWORD)lpBits)[0]); - icd.dwFlags = dwFlags; icd.lpbiInput = lpbiFormat; icd.lpInput = lpData; @@ -691,8 +754,6 @@ DWORD VFWAPIV ICDecompress(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat, icd.ckid = 0; ret = ICSendMessage(hic,ICM_DECOMPRESS,(DWORD_PTR)&icd,sizeof(ICDECOMPRESS)); - TRACE("lpBits[0] == %x\n",((LPDWORD)lpBits)[0]); - TRACE("-> %d\n",ret); return ret; @@ -1017,93 +1078,6 @@ void VFWAPI ICCompressorFree(PCOMPVARS pc) } } - -/****************************************************************** - * MSVIDEO_SendMessage - * - * - */ -LRESULT MSVIDEO_SendMessage(WINE_HIC* whic, UINT msg, DWORD_PTR lParam1, DWORD_PTR lParam2) -{ - LRESULT ret; - -#define XX(x) case x: TRACE("(%p,"#x",0x%08lx,0x%08lx)\n",whic,lParam1,lParam2); break - - switch (msg) { - /* DRV_* */ - XX(DRV_LOAD); - XX(DRV_ENABLE); - XX(DRV_OPEN); - XX(DRV_CLOSE); - XX(DRV_DISABLE); - XX(DRV_FREE); - /* ICM_RESERVED+X */ - XX(ICM_ABOUT); - XX(ICM_CONFIGURE); - XX(ICM_GET); - XX(ICM_GETINFO); - XX(ICM_GETDEFAULTQUALITY); - XX(ICM_GETQUALITY); - XX(ICM_GETSTATE); - XX(ICM_SETQUALITY); - XX(ICM_SET); - XX(ICM_SETSTATE); - /* ICM_USER+X */ - XX(ICM_COMPRESS_FRAMES_INFO); - XX(ICM_COMPRESS_GET_FORMAT); - XX(ICM_COMPRESS_GET_SIZE); - XX(ICM_COMPRESS_QUERY); - XX(ICM_COMPRESS_BEGIN); - XX(ICM_COMPRESS); - XX(ICM_COMPRESS_END); - XX(ICM_DECOMPRESS_GET_FORMAT); - XX(ICM_DECOMPRESS_QUERY); - XX(ICM_DECOMPRESS_BEGIN); - XX(ICM_DECOMPRESS); - XX(ICM_DECOMPRESS_END); - XX(ICM_DECOMPRESS_SET_PALETTE); - XX(ICM_DECOMPRESS_GET_PALETTE); - XX(ICM_DRAW_QUERY); - XX(ICM_DRAW_BEGIN); - XX(ICM_DRAW_GET_PALETTE); - XX(ICM_DRAW_START); - XX(ICM_DRAW_STOP); - XX(ICM_DRAW_END); - XX(ICM_DRAW_GETTIME); - XX(ICM_DRAW); - XX(ICM_DRAW_WINDOW); - XX(ICM_DRAW_SETTIME); - XX(ICM_DRAW_REALIZE); - XX(ICM_DRAW_FLUSH); - XX(ICM_DRAW_RENDERBUFFER); - XX(ICM_DRAW_START_PLAY); - XX(ICM_DRAW_STOP_PLAY); - XX(ICM_DRAW_SUGGESTFORMAT); - XX(ICM_DRAW_CHANGEPALETTE); - XX(ICM_GETBUFFERSWANTED); - XX(ICM_GETDEFAULTKEYFRAMERATE); - XX(ICM_DECOMPRESSEX_BEGIN); - XX(ICM_DECOMPRESSEX_QUERY); - XX(ICM_DECOMPRESSEX); - XX(ICM_DECOMPRESSEX_END); - XX(ICM_SET_STATUS_PROC); - default: - FIXME("(%p,0x%08x,0x%08lx,0x%08lx) unknown message\n",whic,msg,lParam1,lParam2); - } - -#undef XX - - if (whic->driverproc) { - /* dwDriverId parameter is the value returned by the DRV_OPEN */ - ret = whic->driverproc(whic->driverId, whic->hdrv, msg, lParam1, lParam2); - } else { - ret = SendDriverMessage(whic->hdrv, msg, lParam1, lParam2); - } - - TRACE(" -> 0x%08lx\n", ret); - return ret; -} - /*********************************************************************** * ICSendMessage [MSVFW32.@] */ diff --git a/reactos/dll/win32/msvfw32/msvideo_private.h b/reactos/dll/win32/msvfw32/msvideo_private.h index 6bd8e936463..ea0566bb54c 100644 --- a/reactos/dll/win32/msvfw32/msvideo_private.h +++ b/reactos/dll/win32/msvfw32/msvideo_private.h @@ -19,6 +19,9 @@ #ifndef __WINE_MSVIDEO_PRIVATE_H #define __WINE_MSVIDEO_PRIVATE_H +#include +#include + #define ICM_CHOOSE_COMPRESSOR 1 #define IDC_COMP_LIST 880 #define IDS_FULLFRAMES 901 @@ -36,26 +39,11 @@ typedef struct tagWINE_HIC { WORD x2; /* 20: */ DWORD x3; /* 22: */ /* 26: */ - DWORD driverproc16; /* Wine specific flags */ HIC hic; DWORD driverId; struct tagWINE_HIC* next; } WINE_HIC; -HIC MSVIDEO_OpenFunction(DWORD, DWORD, UINT, DRIVERPROC, DWORD); -LRESULT MSVIDEO_SendMessage(WINE_HIC*, UINT, DWORD_PTR, DWORD_PTR); -WINE_HIC* MSVIDEO_GetHicPtr(HIC); - -extern LRESULT (CALLBACK *pFnCallTo16)(HDRVR, HIC, UINT, LPARAM, LPARAM); - -/* handle16 --> handle conversions */ -#define HDRAWDIB_32(h16) ((HDRAWDIB)(ULONG_PTR)(h16)) -#define HIC_32(h16) ((HIC)(ULONG_PTR)(h16)) - -/* handle --> handle16 conversions */ -#define HDRVR_16(h32) (LOWORD(h32)) -#define HDRAWDIB_16(h32) (LOWORD(h32)) -#define HIC_16(h32) (LOWORD(h32)) #define IDC_CONFIGURE 882 #define IDC_ABOUT 883 diff --git a/reactos/dll/win32/msvfw32/rsrc.rc b/reactos/dll/win32/msvfw32/rsrc.rc index 512f341d6ca..ff8741ce0ce 100644 --- a/reactos/dll/win32/msvfw32/rsrc.rc +++ b/reactos/dll/win32/msvfw32/rsrc.rc @@ -21,18 +21,23 @@ #include "msvideo_private.h" #include "msvfw32_Da.rc" -#include "msvfw32_De.rc" #include "msvfw32_En.rc" -#include "msvfw32_Es.rc" -#include "msvfw32_Fr.rc" #include "msvfw32_Hu.rc" #include "msvfw32_Ko.rc" #include "msvfw32_Nl.rc" #include "msvfw32_No.rc" #include "msvfw32_Pl.rc" #include "msvfw32_Pt.rc" -#include "msvfw32_Ru.rc" -#include "msvfw32_Si.rc" #include "msvfw32_Sv.rc" #include "msvfw32_Tr.rc" + +/* UTF-8 */ +#include "msvfw32_De.rc" +#include "msvfw32_Es.rc" +#include "msvfw32_Fr.rc" +#include "msvfw32_It.rc" +#include "msvfw32_Lt.rc" +#include "msvfw32_Ru.rc" +#include "msvfw32_Si.rc" +#include "msvfw32_Uk.rc" #include "msvfw32_Zh.rc" diff --git a/reactos/dll/win32/msvidc32/msvidc32_Da.rc b/reactos/dll/win32/msvidc32/msvidc32_Da.rc index 50ae3f6f5a0..0b286069358 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_Da.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_Da.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + LANGUAGE LANG_DANISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msvidc32/msvidc32_De.rc b/reactos/dll/win32/msvidc32/msvidc32_De.rc index 1d0de70d0db..1dc777b8497 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_De.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_De.rc @@ -17,6 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + +#pragma code_page(65001) + LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msvidc32/msvidc32_En.rc b/reactos/dll/win32/msvidc32/msvidc32_En.rc index 93c8518ec9d..8ac6b59373f 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_En.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_En.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msvidc32/msvidc32_Fr.rc b/reactos/dll/win32/msvidc32/msvidc32_Fr.rc index 3592f31331c..8843e0d6b10 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_Fr.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_Fr.rc @@ -16,10 +16,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE { IDS_NAME "MS-CRAM" - IDS_DESCRIPTION "codec vidéo Wine Video 1" + IDS_DESCRIPTION "Codec vidéo Wine Video 1" } diff --git a/reactos/dll/win32/msvidc32/msvidc32_Hu.rc b/reactos/dll/win32/msvidc32/msvidc32_Hu.rc index c031963f495..2949bae96d1 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_Hu.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_Hu.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msvidc32/msvidc32_Ja.rc b/reactos/dll/win32/msvidc32/msvidc32_Ja.rc new file mode 100644 index 00000000000..3d09c760b2f --- /dev/null +++ b/reactos/dll/win32/msvidc32/msvidc32_Ja.rc @@ -0,0 +1,30 @@ +/* + * Copyright 2009 Aric Stewart, 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 "msvidc32_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "MS-CRAM" + IDS_DESCRIPTION "Wine ビデオ 1 ビデオコーデック" +} diff --git a/reactos/dll/win32/msvidc32/msvidc32_Ko.rc b/reactos/dll/win32/msvidc32/msvidc32_Ko.rc index 11c18c1134f..e95cc9405e2 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_Ko.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_Ko.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msvidc32/msvidc32_Lt.rc b/reactos/dll/win32/msvidc32/msvidc32_Lt.rc new file mode 100644 index 00000000000..ee75ead8bcc --- /dev/null +++ b/reactos/dll/win32/msvidc32/msvidc32_Lt.rc @@ -0,0 +1,30 @@ +/* + * Copyright 2009 Aurimas FiÅ¡eras + * + * 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 "msvidc32_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "MS-CRAM" + IDS_DESCRIPTION "Wine Video 1 vaizdo kodekas" +} diff --git a/reactos/dll/win32/msvidc32/msvidc32_Nl.rc b/reactos/dll/win32/msvidc32/msvidc32_Nl.rc index b68d3eff7a0..c11ca47e30d 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_Nl.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_Nl.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msvidc32/msvidc32_No.rc b/reactos/dll/win32/msvidc32/msvidc32_No.rc index 6d27778dfcc..fa2a96f5760 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_No.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_No.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msvidc32/msvidc32_Pl.rc b/reactos/dll/win32/msvidc32/msvidc32_Pl.rc index af39271d3b1..221c41eb812 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_Pl.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_Pl.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + LANGUAGE LANG_POLISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msvidc32/msvidc32_Pt.rc b/reactos/dll/win32/msvidc32/msvidc32_Pt.rc index 8dcda922a39..ee0eed48b8b 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_Pt.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_Pt.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msvidc32/msvidc32_Ro.rc b/reactos/dll/win32/msvidc32/msvidc32_Ro.rc index fa7584a7dfd..c001dd4f2c0 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_Ro.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_Ro.rc @@ -17,6 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + +#pragma code_page(65001) + LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msvidc32/msvidc32_Ru.rc b/reactos/dll/win32/msvidc32/msvidc32_Ru.rc index 2c84bff4da4..ae2c8cc6bf9 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_Ru.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_Ru.rc @@ -16,10 +16,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { IDS_NAME "MS-CRAM" - IDS_DESCRIPTION "Âèäåî êîäåð Wine Video 1" + IDS_DESCRIPTION "Видео кодер Wine Video 1" } diff --git a/reactos/dll/win32/msvidc32/msvidc32_Si.rc b/reactos/dll/win32/msvidc32/msvidc32_Si.rc index 060ad082142..19d392fccd3 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_Si.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_Si.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + #pragma code_page(65001) LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT @@ -25,5 +27,3 @@ STRINGTABLE DISCARDABLE IDS_NAME "MS-CRAM" IDS_DESCRIPTION "Wine Video 1 video kodek" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/msvidc32/msvidc32_Sv.rc b/reactos/dll/win32/msvidc32/msvidc32_Sv.rc index 1f4770d7a80..7c9b0bc0535 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_Sv.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_Sv.rc @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msvidc32/msvidc32_Tr.rc b/reactos/dll/win32/msvidc32/msvidc32_Tr.rc index 2353b0c542e..d4b882bf715 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_Tr.rc +++ b/reactos/dll/win32/msvidc32/msvidc32_Tr.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "msvidc32_private.h" + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msvidc32/msvidc32_Uk.rc b/reactos/dll/win32/msvidc32/msvidc32_Uk.rc new file mode 100644 index 00000000000..4a4ea72fc3c --- /dev/null +++ b/reactos/dll/win32/msvidc32/msvidc32_Uk.rc @@ -0,0 +1,31 @@ +/* + * Copyright 2005 Dmitry Timoshkov + * Copyright 2010 Igor Paliychuk + * + * 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 "msvidc32_private.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "MS-CRAM" + IDS_DESCRIPTION "Відео кодек Wine Video 1" +} diff --git a/reactos/dll/win32/msvidc32/msvidc32_private.h b/reactos/dll/win32/msvidc32/msvidc32_private.h index b47c6e6f556..590600e232b 100644 --- a/reactos/dll/win32/msvidc32/msvidc32_private.h +++ b/reactos/dll/win32/msvidc32/msvidc32_private.h @@ -19,6 +19,8 @@ #ifndef __MSVIDC32_PRIVATE_H #define __MSVIDC32_PRIVATE_H +#include + #define IDS_NAME 100 #define IDS_DESCRIPTION 101 diff --git a/reactos/dll/win32/msvidc32/msvideo1.c b/reactos/dll/win32/msvidc32/msvideo1.c index ab51e4cbbe0..19784eb888e 100644 --- a/reactos/dll/win32/msvidc32/msvideo1.c +++ b/reactos/dll/win32/msvidc32/msvideo1.c @@ -132,7 +132,7 @@ msvideo1_decode_8bit( int width, int height, const unsigned char *buf, int buf_s for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1) { -#if ORIGINAL +#ifdef ORIGINAL pixels[pixel_ptr++] = colors[(flags & 0x1) ^ 1]; #else pixels[width*(height-(pixel_ptr/width)-1) + @@ -154,7 +154,7 @@ msvideo1_decode_8bit( int width, int height, const unsigned char *buf, int buf_s for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1) { -#if ORIGINAL +#ifdef ORIGINAL pixels[pixel_ptr++] = colors[((pixel_y & 0x2) << 1) + (pixel_x & 0x2) + ((flags & 0x1) ^ 1)]; @@ -175,7 +175,7 @@ msvideo1_decode_8bit( int width, int height, const unsigned char *buf, int buf_s for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++) { -#if ORIGINAL +#ifdef ORIGINAL pixels[pixel_ptr++] = colors[0]; #else pixels[width*(height-(pixel_ptr/width)-1) + @@ -508,7 +508,7 @@ LRESULT WINAPI CRAM_DriverProc( DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, info = HeapAlloc( GetProcessHeap(), 0, sizeof (Msvideo1Context) ); if( info ) { - memset( info, 0, sizeof info ); + memset( info, 0, sizeof *info ); info->dwMagic = CRAM_MAGIC; } r = (LRESULT) info; diff --git a/reactos/dll/win32/msvidc32/rsrc.rc b/reactos/dll/win32/msvidc32/rsrc.rc index f7f7630c9a9..c6c01790392 100644 --- a/reactos/dll/win32/msvidc32/rsrc.rc +++ b/reactos/dll/win32/msvidc32/rsrc.rc @@ -20,8 +20,6 @@ #include "msvidc32_private.h" #include "msvidc32_Da.rc" -#include "msvidc32_De.rc" -#include "msvidc32_Fr.rc" #include "msvidc32_En.rc" #include "msvidc32_Hu.rc" #include "msvidc32_Ko.rc" @@ -29,8 +27,15 @@ #include "msvidc32_No.rc" #include "msvidc32_Pl.rc" #include "msvidc32_Pt.rc" +#include "msvidc32_Sv.rc" +#include "msvidc32_Tr.rc" + +/* UTF-8 */ +#include "msvidc32_De.rc" +#include "msvidc32_Fr.rc" +#include "msvidc32_Ja.rc" +#include "msvidc32_Lt.rc" #include "msvidc32_Ro.rc" #include "msvidc32_Ru.rc" #include "msvidc32_Si.rc" -#include "msvidc32_Sv.rc" -#include "msvidc32_Tr.rc" +#include "msvidc32_Uk.rc" diff --git a/reactos/dll/win32/nddeapi/nddeapi.spec b/reactos/dll/win32/nddeapi/nddeapi.spec index 033ebfbc945..f839a55acd0 100644 --- a/reactos/dll/win32/nddeapi/nddeapi.spec +++ b/reactos/dll/win32/nddeapi/nddeapi.spec @@ -1,28 +1,28 @@ -505 stdcall NDdeGetErrorStringA(long str long) -605 stdcall NDdeGetErrorStringW(long wstr long) -509 stub NDdeGetShareSecurityA -609 stub NDdeGetShareSecurityW -511 stub NDdeGetTrustedShareA -611 stub NDdeGetTrustedShareW -507 stub NDdeIsValidAppTopicListA -607 stub NDdeIsValidAppTopicListW -506 stub NDdeIsValidShareNameA -606 stub NDdeIsValidShareNameW -510 stub NDdeSetShareSecurityA -610 stub NDdeSetShareSecurityW -512 stub NDdeSetTrustedShareA -612 stub NDdeSetTrustedShareW -500 stub NDdeShareAddA -600 stub NDdeShareAddW -501 stub NDdeShareDelA -601 stub NDdeShareDelW -502 stub NDdeShareEnumA -602 stub NDdeShareEnumW -503 stub NDdeShareGetInfoA -603 stub NDdeShareGetInfoW -504 stub NDdeShareSetInfoA -604 stub NDdeShareSetInfoW -508 stub NDdeSpecialCommandA -608 stub NDdeSpecialCommandW -513 stub NDdeTrustedShareEnumA -613 stub NDdeTrustedShareEnumW +@ stdcall NDdeGetErrorStringA(long str long) +@ stdcall NDdeGetErrorStringW(long wstr long) +@ stub NDdeGetShareSecurityA +@ stub NDdeGetShareSecurityW +@ stub NDdeGetTrustedShareA +@ stub NDdeGetTrustedShareW +@ stub NDdeIsValidAppTopicListA +@ stub NDdeIsValidAppTopicListW +@ stub NDdeIsValidShareNameA +@ stub NDdeIsValidShareNameW +@ stub NDdeSetShareSecurityA +@ stub NDdeSetShareSecurityW +@ stub NDdeSetTrustedShareA +@ stub NDdeSetTrustedShareW +@ stub NDdeShareAddA +@ stub NDdeShareAddW +@ stub NDdeShareDelA +@ stub NDdeShareDelW +@ stub NDdeShareEnumA +@ stub NDdeShareEnumW +@ stub NDdeShareGetInfoA +@ stub NDdeShareGetInfoW +@ stub NDdeShareSetInfoA +@ stub NDdeShareSetInfoW +@ stub NDdeSpecialCommandA +@ stub NDdeSpecialCommandW +@ stub NDdeTrustedShareEnumA +@ stub NDdeTrustedShareEnumW diff --git a/reactos/include/psdk/vfw.h b/reactos/include/psdk/vfw.h index ed62545eb42..83d6dbad12d 100644 --- a/reactos/include/psdk/vfw.h +++ b/reactos/include/psdk/vfw.h @@ -499,7 +499,7 @@ BOOL VFWAPI ICInstall(DWORD fccType, DWORD fccHandler, LPARAM lParam, LPSTR BOOL VFWAPI ICRemove(DWORD fccType, DWORD fccHandler, UINT wFlags); LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo, DWORD cb); HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode); -HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler); +HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, DRIVERPROC lpfnHandler); LRESULT VFWAPI ICClose(HIC hic); HIC VFWAPI ICLocate(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, WORD wFlags); From 30cee65672248f696f065a0080bda023b0b56250 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Wed, 10 Mar 2010 18:28:03 +0000 Subject: [PATCH 25/64] [DDK]: Add MEMORY_BARRIER missing from ioaccess.h. svn path=/trunk/; revision=46067 --- reactos/include/ddk/ioaccess.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/include/ddk/ioaccess.h b/reactos/include/ddk/ioaccess.h index f9776bfdc36..0f1877f6c19 100755 --- a/reactos/include/ddk/ioaccess.h +++ b/reactos/include/ddk/ioaccess.h @@ -41,6 +41,8 @@ extern "C" { #define WRITE_PORT_USHORT(p, v) __outword (H2I(p), (v)) #define WRITE_PORT_ULONG(p, v) __outdword (H2I(p), (v)) +#define MEMORY_BARRIER() + #elif defined(_PPC_) || defined(_MIPS_) || defined(_ARM_) #define READ_REGISTER_UCHAR(r) (*(volatile UCHAR * const)(r)) From c240396ad5041ff7c181f2d2cc7cdf01451148a7 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Wed, 10 Mar 2010 18:28:45 +0000 Subject: [PATCH 26/64] [SCM]: Fix SCM shutdown. Now all services are stopped (in my working copy with the CSRSS shutdown code). svn path=/trunk/; revision=46068 --- reactos/base/system/services/services.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/base/system/services/services.c b/reactos/base/system/services/services.c index 44ee8f396af..2d97ce44f4f 100644 --- a/reactos/base/system/services/services.c +++ b/reactos/base/system/services/services.c @@ -279,7 +279,7 @@ ShutdownHandlerRoutine(DWORD dwCtrlType) { DPRINT1("ShutdownHandlerRoutine() called\n"); - if (dwCtrlType == CTRL_SHUTDOWN_EVENT) + if (dwCtrlType & (CTRL_SHUTDOWN_EVENT | CTRL_LOGOFF_EVENT)) { DPRINT1("Shutdown event received!\n"); ScmShutdown = TRUE; From c7dbb1670a92d14a330110cad31c2a868f27a40e Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Wed, 10 Mar 2010 18:29:10 +0000 Subject: [PATCH 27/64] [NTOS]: List still-running processes at kernel shutdown. Useful for debugging shutdown code later. svn path=/trunk/; revision=46069 --- reactos/ntoskrnl/po/poshtdwn.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/reactos/ntoskrnl/po/poshtdwn.c b/reactos/ntoskrnl/po/poshtdwn.c index 25ee2e3ddf4..dd5113e1bb3 100644 --- a/reactos/ntoskrnl/po/poshtdwn.c +++ b/reactos/ntoskrnl/po/poshtdwn.c @@ -118,6 +118,23 @@ VOID NTAPI PopGracefulShutdown(IN PVOID Context) { + PEPROCESS Process = NULL; + + /* Loop every process */ + Process = PsGetNextProcess(Process); + while (Process) + { + /* Make sure this isn't the idle or initial process */ + if ((Process != PsInitialSystemProcess) && (Process != PsIdleProcess)) + { + /* Print it */ + DPRINT1("%15s is still RUNNING (%lx)\n", Process->ImageFileName, Process->UniqueProcessId); + } + + /* Get the next process */ + Process = PsGetNextProcess(Process); + } + /* First, the HAL handles any "end of boot" special functionality */ DPRINT1("HAL shutting down\n"); HalEndOfBoot(); From da63b1ca50953a02f45e931eace75700d9169d83 Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Wed, 10 Mar 2010 20:44:19 +0000 Subject: [PATCH 28/64] Sync sccbase, slbcsp, usp10, wldap32, wuapi and xinput1_3 to Wine 1.1.40 Theres more, like: comctl32, comdlg32, oleaut32, riched20, sti, version, winemp3.acm, wininet and winhttp which is above my skills or looks strange, like its not really synched (winemp3.acm!!) Feel free to play with them. svn path=/trunk/; revision=46072 --- reactos/dll/win32/sccbase/main.c | 18 ++ reactos/dll/win32/sccbase/sccbase.spec | 4 +- reactos/dll/win32/slbcsp/main.c | 18 ++ reactos/dll/win32/slbcsp/slbcsp.spec | 4 +- reactos/dll/win32/usp10/usp10.c | 4 +- reactos/dll/win32/wldap32/wldap32.rc | 10 +- reactos/dll/win32/wldap32/wldap32_Da.rc | 2 + reactos/dll/win32/wldap32/wldap32_De.rc | 42 ++--- reactos/dll/win32/wldap32/wldap32_En.rc | 2 + reactos/dll/win32/wldap32/wldap32_Es.rc | 2 + reactos/dll/win32/wldap32/wldap32_Fr.rc | 86 +++++----- reactos/dll/win32/wldap32/wldap32_Ko.rc | 2 + reactos/dll/win32/wldap32/wldap32_Lt.rc | 128 +++++++++++++++ reactos/dll/win32/wldap32/wldap32_Nl.rc | 2 + reactos/dll/win32/wldap32/wldap32_No.rc | 2 + reactos/dll/win32/wldap32/wldap32_Pl.rc | 2 + reactos/dll/win32/wldap32/wldap32_Pt.rc | 2 + reactos/dll/win32/wldap32/wldap32_Ru.rc | 125 +++++++------- reactos/dll/win32/wldap32/wldap32_Sv.rc | 2 + reactos/dll/win32/wldap32/wldap32_Tr.rc | 2 + reactos/dll/win32/wldap32/wldap32_Uk.rc | 130 +++++++++++++++ reactos/dll/win32/wuapi/main.c | 1 - reactos/dll/win32/wuapi/regsvr.c | 4 +- reactos/dll/win32/xinput1_3/xinput1_3_main.c | 2 +- reactos/media/doc/README.WINE | 163 +++++++++---------- 25 files changed, 544 insertions(+), 215 deletions(-) create mode 100644 reactos/dll/win32/wldap32/wldap32_Lt.rc create mode 100644 reactos/dll/win32/wldap32/wldap32_Uk.rc diff --git a/reactos/dll/win32/sccbase/main.c b/reactos/dll/win32/sccbase/main.c index 37abe5f2c85..7a012f5606c 100644 --- a/reactos/dll/win32/sccbase/main.c +++ b/reactos/dll/win32/sccbase/main.c @@ -44,3 +44,21 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) } return TRUE; } + +/***************************************************** + * DllRegisterServer (SCCBASE.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + FIXME("Not implemented.\n"); + return E_UNEXPECTED; +} + +/***************************************************** + * DllUnregisterServer (SCCBASE.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + FIXME("Not implemented.\n"); + return E_UNEXPECTED; +} diff --git a/reactos/dll/win32/sccbase/sccbase.spec b/reactos/dll/win32/sccbase/sccbase.spec index c63d06bb548..ffc2111635f 100644 --- a/reactos/dll/win32/sccbase/sccbase.spec +++ b/reactos/dll/win32/sccbase/sccbase.spec @@ -22,5 +22,5 @@ @ stub CPSetProvParam @ stub CPSignHash @ stub CPVerifySignature -@ stub DllRegisterServer -@ stub DllUnregisterServer +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/reactos/dll/win32/slbcsp/main.c b/reactos/dll/win32/slbcsp/main.c index 594f811ceab..a6aece1b09d 100644 --- a/reactos/dll/win32/slbcsp/main.c +++ b/reactos/dll/win32/slbcsp/main.c @@ -44,3 +44,21 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) } return TRUE; } + +/***************************************************** + * DllRegisterServer (SLBCSP.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + FIXME("Not implemented.\n"); + return E_UNEXPECTED; +} + +/***************************************************** + * DllUnregisterServer (SLBCSP.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + FIXME("Not implemented.\n"); + return E_UNEXPECTED; +} diff --git a/reactos/dll/win32/slbcsp/slbcsp.spec b/reactos/dll/win32/slbcsp/slbcsp.spec index d3462fa119c..7ce1733bf4c 100644 --- a/reactos/dll/win32/slbcsp/slbcsp.spec +++ b/reactos/dll/win32/slbcsp/slbcsp.spec @@ -23,5 +23,5 @@ @ stub CPReleaseContext @ stub CPSignHash @ stub CPVerifySignature -@ stub DllRegisterServer -@ stub DllUnregisterServer +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/reactos/dll/win32/usp10/usp10.c b/reactos/dll/win32/usp10/usp10.c index 6a78356969d..1a68ae0201a 100644 --- a/reactos/dll/win32/usp10/usp10.c +++ b/reactos/dll/win32/usp10/usp10.c @@ -592,8 +592,6 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem pItems[index].a.s.uBidiLevel = 1; pItems[index].a.eScript = New_Script; - if (New_Script == Script_Arabic) - pItems[index].a.s.uBidiLevel = 1; TRACE("index=%d cnt=%d iCharPos=%d\n", index, cnt, pItems[index].iCharPos); } @@ -604,7 +602,7 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem * checks the n+1 structure */ memset(&pItems[index+1].a, 0, sizeof(SCRIPT_ANALYSIS)); - TRACE("index=%d cnt=%d iCharPos=%d\n", index+1, cnt, pItems[index+1].iCharPos = cnt); + TRACE("index=%d cnt=%d iCharPos=%d\n", index+1, cnt, pItems[index+1].iCharPos); /* Set one SCRIPT_STATE item being returned */ if (pcItems) *pcItems = index + 1; diff --git a/reactos/dll/win32/wldap32/wldap32.rc b/reactos/dll/win32/wldap32/wldap32.rc index 50f9562ca53..379e2b205ab 100644 --- a/reactos/dll/win32/wldap32/wldap32.rc +++ b/reactos/dll/win32/wldap32/wldap32.rc @@ -23,15 +23,19 @@ #include "winuser.h" #include "wldap32_Da.rc" -#include "wldap32_De.rc" #include "wldap32_En.rc" #include "wldap32_Es.rc" -#include "wldap32_Fr.rc" #include "wldap32_Ko.rc" #include "wldap32_Nl.rc" #include "wldap32_No.rc" #include "wldap32_Pl.rc" #include "wldap32_Pt.rc" -#include "wldap32_Ru.rc" #include "wldap32_Sv.rc" #include "wldap32_Tr.rc" + +/* UTF-8 */ +#include "wldap32_De.rc" +#include "wldap32_Fr.rc" +#include "wldap32_Lt.rc" +#include "wldap32_Ru.rc" +#include "wldap32_Uk.rc" diff --git a/reactos/dll/win32/wldap32/wldap32_Da.rc b/reactos/dll/win32/wldap32/wldap32_Da.rc index 2a48498feea..286a8e47624 100644 --- a/reactos/dll/win32/wldap32/wldap32_Da.rc +++ b/reactos/dll/win32/wldap32/wldap32_Da.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "windef.h" + LANGUAGE LANG_DANISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/wldap32/wldap32_De.rc b/reactos/dll/win32/wldap32/wldap32_De.rc index 86d0263a8e2..2886330cc56 100644 --- a/reactos/dll/win32/wldap32/wldap32_De.rc +++ b/reactos/dll/win32/wldap32/wldap32_De.rc @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "windef.h" + +#pragma code_page(65001) + LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE @@ -25,25 +29,25 @@ STRINGTABLE DISCARDABLE 0 "Erfolgreich" 1 "Operationsfehler" 2 "Protokollfehler" - 3 "Zeitlimit überschritten" - 4 "Größenlimit überschritten" + 3 "Zeitlimit überschritten" + 4 "Größenlimit überschritten" 5 "Vergleich falsch" 6 "Vergleich wahr" - 7 "Authentifizierungsmethode nicht unterstützt" + 7 "Authentifizierungsmethode nicht unterstützt" 8 "Starke Authentifizierung erforderlich" 9 "Weiterleitung (v2)" 10 "Weiterleitung" - 11 "Verwaltungslimit überschritten" - 12 "Kritische Erweiterung nicht verfügbar" + 11 "Verwaltungslimit überschritten" + 12 "Kritische Erweiterung nicht verfügbar" 13 "Vertraulichkeit erforderlich" 14 "" 15 "" 16 "Attribut nicht vorhanden" 17 "Nicht definierter Typ" - 18 "Unzulässiger Vergleich" + 18 "Unzulässiger Vergleich" 19 "Restriktionsverletzung" 20 "Attribut oder Wert vorhanden" - 21 "Ungültige Syntax" + 21 "Ungültige Syntax" 22 "" 23 "" 24 "" @@ -56,7 +60,7 @@ STRINGTABLE DISCARDABLE 31 "" 32 "Objekt nicht vorhanden" 33 "Aliasproblem" - 34 "Ungültige DN Syntax" + 34 "Ungültige DN Syntax" 35 "Endknoten" 36 "Alias Dereferenzierungsproblem" 37 "" @@ -73,9 +77,9 @@ STRINGTABLE DISCARDABLE 48 "Fehlerhafte Authentifizierung" 49 "Anmeldeinformationen fehlerhaft" 50 "Nicht ausreichende Rechte" - 51 "Beschäftigt" - 52 "Nicht verfügbar" - 53 "Ausführung verweigert" + 51 "Beschäftigt" + 52 "Nicht verfügbar" + 53 "Ausführung verweigert" 54 "Schleife erkannt" 55 "" 56 "" @@ -88,11 +92,11 @@ STRINGTABLE DISCARDABLE 63 "" 64 "Bennenungsverletzung" 65 "Objektklasse verletzt" - 66 "Nicht erlaubt für Nicht-Endknoten" - 67 "Nicht erlaubt für RDN" + 66 "Nicht erlaubt für Nicht-Endknoten" + 67 "Nicht erlaubt für RDN" 68 "Bereits vorhanden" 69 "Keine Objektklassenmodifikationen" - 70 "Ergebnisse zu groß" + 70 "Ergebnisse zu groß" 71 "Mehrere DSAs betroffen" 72 "" 73 "" @@ -107,17 +111,17 @@ STRINGTABLE DISCARDABLE 82 "Lokaler Fehler" 83 "Kodierungsfehler" 84 "Dekodierungsfehler" - 85 "Zeitüberschreitung" + 85 "Zeitüberschreitung" 86 "Unbekannte Authentifizierung" 87 "Filterfehler" 88 "Benutzerabbruch" 89 "Parameterfehler" - 90 "Nicht genügend Speicher" + 90 "Nicht genügend Speicher" 91 "Kann nicht zum LDAP Server verbinden" - 92 "Die Operation wird durch dieses LDAP Protokoll nicht unterstützt" + 92 "Die Operation wird durch dieses LDAP Protokoll nicht unterstützt" 93 "Angegebenes Steuerobjekt wurde in der Meldung nicht gefunden" 94 "Keine Ergebnisse in der Meldung vorhanden" 95 "Weitere Ergebnisse gefunden" - 96 "Schleife während der Abarbeitung von Weiterleitungen" - 97 "Überschreitung der maximalen Anzahl von Weiterleitungen" + 96 "Schleife während der Abarbeitung von Weiterleitungen" + 97 "Überschreitung der maximalen Anzahl von Weiterleitungen" } diff --git a/reactos/dll/win32/wldap32/wldap32_En.rc b/reactos/dll/win32/wldap32/wldap32_En.rc index 4d213642aa8..1c2ca0fd520 100644 --- a/reactos/dll/win32/wldap32/wldap32_En.rc +++ b/reactos/dll/win32/wldap32/wldap32_En.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "windef.h" + LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/wldap32/wldap32_Es.rc b/reactos/dll/win32/wldap32/wldap32_Es.rc index d0935b1f8e6..959dd11157e 100644 --- a/reactos/dll/win32/wldap32/wldap32_Es.rc +++ b/reactos/dll/win32/wldap32/wldap32_Es.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "windef.h" + LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/wldap32/wldap32_Fr.rc b/reactos/dll/win32/wldap32/wldap32_Fr.rc index 8ea8d1c8bdd..fa3d4f807ff 100644 --- a/reactos/dll/win32/wldap32/wldap32_Fr.rc +++ b/reactos/dll/win32/wldap32/wldap32_Fr.rc @@ -2,6 +2,7 @@ * French resources for WLDAP32 * * Copyright 2005 Jonathan Ernst + * Copyright 2009 Frédéric Delanoy * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,31 +19,36 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "windef.h" + +/* UTF-8 */ +#pragma code_page(65001) + LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE { - 0 "Succès" - 1 "Erreur d'opération" + 0 "Succès" + 1 "Erreur d'opération" 2 "Erreur de protocole" - 3 "Limite de temps dépassée" - 4 "Limite de taille dépassée" - 5 "Comparaison Fausse" - 6 "Comparaison Vraie" - 7 "Méthode d'authentification non supportée" + 3 "Limite de temps dépassée" + 4 "Limite de taille dépassée" + 5 "Comparaison fausse" + 6 "Comparaison vraie" + 7 "Méthode d'authentification non prise en charge" 8 "Authentification forte requise" - 9 "Référant (v2)" - 10 "Référant" - 11 "Limite administrative dépassée" + 9 "Référant (v2)" + 10 "Référant" + 11 "Limite administrative dépassée" 12 "Extension critique indisponible" - 13 "Confidentialité requise" + 13 "Confidentialité requise" 14 "" 15 "" 16 "Attribut inconnu" - 17 "Type indéfini" - 18 "Inappropriate Matching" + 17 "Type non défini" + 18 "Correspondance inappropriée" 19 "Violation de contrainte" - 20 "Attribut ou valeur existant" + 20 "Attribut ou valeur préexistant(e)" 21 "Syntaxe invalide" 22 "" 23 "" @@ -55,10 +61,10 @@ STRINGTABLE DISCARDABLE 30 "" 31 "" 32 "Objet inconnu" - 33 "Problème d'alias" + 33 "Problème d'alias" 34 "Syntaxe DN invalide" 35 "Est une feuille" - 36 "Problème de déréférencement d'alias" + 36 "Problème de déréférencement d'alias" 37 "" 38 "" 39 "" @@ -70,30 +76,30 @@ STRINGTABLE DISCARDABLE 45 "" 46 "" 47 "" - 48 "Authentification inappropriée" - 49 "Droits invalides" + 48 "Authentification inappropriée" + 49 "Autorisations invalides" 50 "Droits insuffisants" - 51 "Occupé" + 51 "Occupé" 52 "Indisponible" - 53 "Ne souhaite pas s'exécuter" - 54 "Boucle détectée" + 53 "Pas disposé à s'exécuter" + 54 "Boucle détectée" 55 "" 56 "" 57 "" 58 "" 59 "" - 60 "Contrôle de tri manquant" - 61 "Erreur d'intervalle d'index" + 60 "Contrôle de tri manquant" + 61 "Erreur de plage d'index" 62 "" 63 "" 64 "Violation de nomenclature" 65 "Violation de classe d'objet" 66 "Interdit sur des non-feuilles" 67 "Interdit sur RDN" - 68 "Existe déjà" - 69 "Pas de Mods de classe d'objet" - 70 "Résultat trop grand" - 71 "Affecte de multiple DSAs" + 68 "Existe déjà" + 69 "Pas de modification de classe d'objet" + 70 "Résultats trop grands" + 71 "Affecte de multiples DSA" 72 "" 73 "" 74 "" @@ -106,18 +112,18 @@ STRINGTABLE DISCARDABLE 81 "Serveur indisponible" 82 "Erreur locale" 83 "Erreur d'encodage" - 84 "Erreur de décodage" - 85 "Délai d'attente dépassé" - 86 "Auth inconnue" - 87 "Erreur de filtre" - 88 "Annulation de l'utilisateur" - 89 "Erreur de paramètre" - 90 "Pas de mémoire" + 84 "Erreur de décodage" + 85 "Délai d'attente dépassé" + 86 "Méthode d'authentification inconnue" + 87 "Erreur de filtrage" + 88 "Annulation par l'utilisateur" + 89 "Erreur de paramètre" + 90 "Mémoire insuffisante" 91 "Impossible de se connecter au serveur LDAP" - 92 "Opération non supportée par cette version du protocole LDAP" - 93 "Le contrôle spécifié n'a pas été trouvé dans le message" - 94 "Pas de résultat dans le message" - 95 "Plus de résultats retournés" - 96 "Boucle lors du traitement des référants" - 97 "Limite du nombre de référents dépassée" + 92 "Opération non supportée par cette version du protocole LDAP" + 93 "Le contrôle spécifié n'a pas été trouvé dans le message" + 94 "Aucun résultat dans le message" + 95 "Plus de résultats reçus" + 96 "Boucle lors du traitement des référants" + 97 "Limite du nombre de référants dépassée" } diff --git a/reactos/dll/win32/wldap32/wldap32_Ko.rc b/reactos/dll/win32/wldap32/wldap32_Ko.rc index a5f01373322..9b9c9ce79b0 100644 --- a/reactos/dll/win32/wldap32/wldap32_Ko.rc +++ b/reactos/dll/win32/wldap32/wldap32_Ko.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "windef.h" + LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/wldap32/wldap32_Lt.rc b/reactos/dll/win32/wldap32/wldap32_Lt.rc new file mode 100644 index 00000000000..41a8f599f56 --- /dev/null +++ b/reactos/dll/win32/wldap32/wldap32_Lt.rc @@ -0,0 +1,128 @@ +/* + * Lithuanian resources for WLDAP32 + * + * Copyright 2009 Aurimas FiÅ¡eras + * + * 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 "windef.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + 0 "SÄ—kmÄ—" + 1 "Operacijų klaida" + 2 "Protokolo klaida" + 3 "VirÅ¡ytas skirtas laikas" + 4 "VirÅ¡yta dydžio riba" + 5 "Nelygu" + 6 "Lygu" + 7 "Tapatumo nustatymo metodas nerealizuotas" + 8 "Reikalingas stiprus tapatumo nustatymas" + 9 "Perdavimas (v2)" + 10 "Perdavimas" + 11 "VirÅ¡yta administravimo riba" + 12 "Nepasiekiamas kritinis plÄ—tinys" + 13 "Reikalingas slaptumas" + 14 "" + 15 "" + 16 "NÄ—ra tokio atributo" + 17 "Neapibrėžtas tipas" + 18 "Netinkamas atitikimas" + 19 "Ribojimų pažeidimas" + 20 "Atributas ar reikÅ¡mÄ— egzistuoja" + 21 "Neteisinga sintaksÄ—" + 22 "" + 23 "" + 24 "" + 25 "" + 26 "" + 27 "" + 28 "" + 29 "" + 30 "" + 31 "" + 32 "NÄ—ra tokio objekto" + 33 "Alternatyviojo vardo problema" + 34 "Neteisinga DN sintaksÄ—" + 35 "Objektas yra lapas" + 36 "Alternatyviojo vardo reikÅ¡mÄ—s nustatymo problema" + 37 "" + 38 "" + 39 "" + 40 "" + 41 "" + 42 "" + 43 "" + 44 "" + 45 "" + 46 "" + 47 "" + 48 "Netinkamas tapatumo nustatymas" + 49 "Neteisingi kredencialai" + 50 "Nepakanka teisių" + 51 "Užimtas" + 52 "Nepasiekiamas" + 53 "NelinkÄ™s aptarnauti" + 54 "Aptiktas ciklas" + 55 "" + 56 "" + 57 "" + 58 "" + 59 "" + 60 "TrÅ«ksta rikiavimo valdiklio" + 61 "Indekso rėžių klaida" + 62 "" + 63 "" + 64 "Ä®vardijimo pažeidimas" + 65 "Objekto klasÄ—s pažeidimas" + 66 "Leistina tik su lapu" + 67 "Neleistina su RDN" + 68 "Jau yra" + 69 "Negalimas objektų klasÄ—s modifikavimas" + 70 "Rezultatai per dideli" + 71 "Ä®takoja daugelį DSA" + 72 "" + 73 "" + 74 "" + 75 "" + 76 "" + 77 "" + 78 "" + 79 "" + 80 "Kita" + 81 "Serveris nepasiekiamas" + 82 "VietinÄ— klaida" + 83 "Kodavimo klaida" + 84 "Dekodavimo klaida" + 85 "BaigÄ—si laikas" + 86 "Nežinomas tapatumo nustatymas" + 87 "Filtro klaida" + 88 "Nutraukta naudotojo" + 89 "Parametro klaida" + 90 "TrÅ«ksta atminties" + 91 "Nepavyko prisijungti prie LDAP serverio" + 92 "Operacija nepalaikoma Å¡ioje LDAP protokolo versijoje" + 93 "Nurodytas valdiklis nerastas praneÅ¡ime" + 94 "PraneÅ¡ime nÄ—ra rezultato" + 95 "Grąžinta daugiau rezultatų" + 96 "Aptiktas ciklas apdorojant perdavimus" + 97 "VirÅ¡yta perdavimo Å¡uolių riba" +} diff --git a/reactos/dll/win32/wldap32/wldap32_Nl.rc b/reactos/dll/win32/wldap32/wldap32_Nl.rc index 3146f1733ea..58ac2efc531 100644 --- a/reactos/dll/win32/wldap32/wldap32_Nl.rc +++ b/reactos/dll/win32/wldap32/wldap32_Nl.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "windef.h" + LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/wldap32/wldap32_No.rc b/reactos/dll/win32/wldap32/wldap32_No.rc index de0a5935750..dc174f75406 100644 --- a/reactos/dll/win32/wldap32/wldap32_No.rc +++ b/reactos/dll/win32/wldap32/wldap32_No.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "windef.h" + LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/wldap32/wldap32_Pl.rc b/reactos/dll/win32/wldap32/wldap32_Pl.rc index 2e80b884058..41d0e31f57f 100644 --- a/reactos/dll/win32/wldap32/wldap32_Pl.rc +++ b/reactos/dll/win32/wldap32/wldap32_Pl.rc @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "windef.h" + LANGUAGE LANG_POLISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/wldap32/wldap32_Pt.rc b/reactos/dll/win32/wldap32/wldap32_Pt.rc index 172234c8722..386c7a5b11f 100644 --- a/reactos/dll/win32/wldap32/wldap32_Pt.rc +++ b/reactos/dll/win32/wldap32/wldap32_Pt.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "windef.h" + LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/wldap32/wldap32_Ru.rc b/reactos/dll/win32/wldap32/wldap32_Ru.rc index 7e6a5604a12..9029b8afa8d 100644 --- a/reactos/dll/win32/wldap32/wldap32_Ru.rc +++ b/reactos/dll/win32/wldap32/wldap32_Ru.rc @@ -18,32 +18,37 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "windef.h" + +/* UTF-8 */ +#pragma code_page(65001) + LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { - 0 "Óñïåõ" - 1 "Îøèáêà îïåðàöèè" - 2 "Îøèáêà ïðîòîêîëà" - 3 "Ïðåâûøåíî îãðàíè÷åíèå ïî âðåìåíè" - 4 "Ïðåâûøåíî îãðàíè÷åíèå ïî ðàçìåðó" - 5 "Ñðàâíåíèå íåâåðíî" - 6 "Ñðàâíåíèå âåðíî" - 7 "Ìåòîä àâòîðèçàöèè íå ïîääåðæèâàåòñÿ" - 8 "Òðåáóåòñÿ ñòðîãàÿ àâòîðèçàöèÿ" - 9 "Ññûëêà (v2)" - 10 "Ññûëêà" - 11 "Ïðåâûøåíî îãðàíè÷åíèå àäìèíèñòðèðîâàíèÿ" - 12 "Êðèòè÷åñêîå ðàñøèðåíèå íåäîñòóïíî" - 13 "Òðåáóåòñÿ êîíôèäåíöèàëüíîñòü" + 0 "УÑпех" + 1 "Ошибка операции" + 2 "Ошибка протокола" + 3 "Превышено ограничение по времени" + 4 "Превышено ограничение по размеру" + 5 "Сравнение неверно" + 6 "Сравнение верно" + 7 "Метод авторизации не поддерживаетÑÑ" + 8 "ТребуетÑÑ ÑÑ‚Ñ€Ð¾Ð³Ð°Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ" + 9 "СÑылка (v2)" + 10 "СÑылка" + 11 "Превышено ограничение админиÑтрированиÑ" + 12 "КритичеÑкое раÑширение недоÑтупно" + 13 "ТребуетÑÑ ÐºÐ¾Ð½Ñ„Ð¸Ð´ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð¾Ñть" 14 "" 15 "" - 16 "Íåò òàêîãî àòðèáóòà" - 17 "Íåîïðåäåëåííûé òèï" - 18 "Íåïîäõîäÿùåå ñîîòâåòñòâèå" - 19 "Íàðóøåíèå îãðàíè÷åíèÿ" - 20 "Àòðèáóò èëè çíà÷åíèå ñóùåñòâóåò" - 21 "Íåâåðíûé ñèíòàêñèñ" + 16 "Ðет такого атрибута" + 17 "Ðеопределенный тип" + 18 "ÐеподходÑщее ÑоответÑтвие" + 19 "Ðарушение ограничениÑ" + 20 "Ðтрибут или значение ÑущеÑтвует" + 21 "Ðеверный ÑинтакÑиÑ" 22 "" 23 "" 24 "" @@ -54,11 +59,11 @@ STRINGTABLE DISCARDABLE 29 "" 30 "" 31 "" - 32 "Íåò òàêîãî îáúåêòà" - 33 "Ïðîáëåìà ñ ïñåâäîíèìîì" - 34 "Íåâåðíûé DN ñèíòàêñèñ" - 35 "Ýòî ëèñò äåðåâà" - 36 "Ïðîáëåìà îáðàùåíèÿ ïî ïñåâäîíèìó" + 32 "Ðет такого объекта" + 33 "Проблема Ñ Ð¿Ñевдонимом" + 34 "Ðеверный DN ÑинтакÑиÑ" + 35 "Это лиÑÑ‚ дерева" + 36 "Проблема Ð¾Ð±Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ð¿Ð¾ пÑевдониму" 37 "" 38 "" 39 "" @@ -70,30 +75,30 @@ STRINGTABLE DISCARDABLE 45 "" 46 "" 47 "" - 48 "Íåïîäõîäÿùàÿ àâòîðèçàöèÿ" - 49 "Íåâåðíîå óäîñòîâåðåíèå ëè÷íîñòè" - 50 "Íåäîñòàòî÷íî ïðàâ" - 51 "Çàíÿòî" - 52 "Íåäîñòóïíî" - 53 "Íå æåëàåò âûïîëíèòü" - 54 "Îáíàðóæåíî çàöèêëèâàíèå" + 48 "ÐеподходÑÑ‰Ð°Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ" + 49 "Ðеверное удоÑтоверение личноÑти" + 50 "ÐедоÑтаточно прав" + 51 "ЗанÑто" + 52 "ÐедоÑтупно" + 53 "Ðе желает выполнить" + 54 "Обнаружено зацикливание" 55 "" 56 "" 57 "" 58 "" 59 "" - 60 "Îòñóòñòâóåò óïðàâëåíèå ñîðòèðîâêîé" - 61 "Îøèáêà äèàïàçîíà èíäåêñà" + 60 "ОтÑутÑтвует управление Ñортировкой" + 61 "Ошибка диапазона индекÑа" 62 "" 63 "" - 64 "Íàðóøåíèå ïðàâèë íàèìåíîâàíèÿ" - 65 "Íàðóøåíèå êëàññà îáúåêòà" - 66 "Íå ðàçðåøåíî íå íà ëèñòå äåðåâà" - 67 "Íå ðàçðåøåíî íà RDN" - 68 "Óæå ñóùåñòâóåò" - 69 "Íåò ðåæèìîâ êëàññà îáúåêòà" - 70 "Ðåçóëüòàòû ñëèøêîì âåëèêè" - 71 "Âëèÿåò íà íåñêîëüêî DSA" + 64 "Ðарушение правил наименованиÑ" + 65 "Ðарушение клаÑÑа объекта" + 66 "Ðе разрешено не на лиÑте дерева" + 67 "Ðе разрешено на RDN" + 68 "Уже ÑущеÑтвует" + 69 "Ðет режимов клаÑÑа объекта" + 70 "Результаты Ñлишком велики" + 71 "ВлиÑет на неÑколько DSA" 72 "" 73 "" 74 "" @@ -102,22 +107,22 @@ STRINGTABLE DISCARDABLE 77 "" 78 "" 79 "" - 80 "Äðóãîé" - 81 "Ñåðâåð íåäîñòóïåí" - 82 "Ëîêàëüíàÿ îøèáêà" - 83 "Îøèáêà êîäèðîâàíèÿ" - 84 "Îøèáêà äåêîäèðîâàíèÿ" - 85 "Òàéì-àóò" - 86 "Íåèçâåñòíàÿ àâòîðèçàöèÿ" - 87 "Îøèáêà ôèëüòðà" - 88 "Îòìåíåíî ïîëüçîâàòåëåì" - 89 "Îøèáêà ïàðàìåòðà" - 90 "Íåò ïàìÿòè" - 91 "Íåâîçìîæíî ïîäêëþ÷èòüñÿ ê LDAP ñåðâåðó" - 92 "Îïåðàöèÿ íå ïîääåðæèâàåòñÿ ýòîé âåðñèåé ïðîòîêîëà LDAP" - 93 "Óêàçàííûé óïðàâëÿþùèé ýëåìåíò íå íàéäåí â ñîîáùåíèè" - 94 "Ðåçóëüòàòà íåò â ñîîáùåíèè" - 95 "Åùå åñòü ðåçóëüòàòû" - 96 "Çàöèêëèâàíèå ïðè îáðàáîòêå ññûëîê" - 97 "Ïðåäåë ÷èñëà ïåðåñûëêè ññûëîê ïðåâûøåí" + 80 "Другой" + 81 "Сервер недоÑтупен" + 82 "Ð›Ð¾ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°" + 83 "Ошибка кодированиÑ" + 84 "Ошибка декодированиÑ" + 85 "Тайм-аут" + 86 "ÐеизвеÑÑ‚Ð½Ð°Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ" + 87 "Ошибка фильтра" + 88 "Отменено пользователем" + 89 "Ошибка параметра" + 90 "Ðет памÑти" + 91 "Ðевозможно подключитьÑÑ Ðº LDAP Ñерверу" + 92 "ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð½Ðµ поддерживаетÑÑ Ñтой верÑией протокола LDAP" + 93 "Указанный управлÑющий Ñлемент не найден в Ñообщении" + 94 "Результата нет в Ñообщении" + 95 "Еще еÑть результаты" + 96 "Зацикливание при обработке ÑÑылок" + 97 "Предел чиÑла переÑылки ÑÑылок превышен" } diff --git a/reactos/dll/win32/wldap32/wldap32_Sv.rc b/reactos/dll/win32/wldap32/wldap32_Sv.rc index 69137406d8b..f308ade3bd3 100644 --- a/reactos/dll/win32/wldap32/wldap32_Sv.rc +++ b/reactos/dll/win32/wldap32/wldap32_Sv.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "windef.h" + LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/wldap32/wldap32_Tr.rc b/reactos/dll/win32/wldap32/wldap32_Tr.rc index 3f089e768f8..7f49abc1bb0 100644 --- a/reactos/dll/win32/wldap32/wldap32_Tr.rc +++ b/reactos/dll/win32/wldap32/wldap32_Tr.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "windef.h" + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/wldap32/wldap32_Uk.rc b/reactos/dll/win32/wldap32/wldap32_Uk.rc new file mode 100644 index 00000000000..54fe9431f72 --- /dev/null +++ b/reactos/dll/win32/wldap32/wldap32_Uk.rc @@ -0,0 +1,130 @@ +/* + * Ukrainian resources for WLDAP32 + * + * Copyright 2005 Hans Leidekker + * + * Copyright 2010 Igor Paliychuk + * + * 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 "windef.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + 0 "УÑпіх" + 1 "Помилка операції" + 2 "Помилка протоколу" + 3 "Перевищено Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð² чаÑÑ–" + 4 "Перевищено Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð² розмірі" + 5 "ПорівнÑÐ½Ð½Ñ Ð½ÐµÐ²Ñ–Ñ€Ð½Ðµ" + 6 "ПорівнÑÐ½Ð½Ñ Ð²Ñ–Ñ€Ð½Ðµ" + 7 "Метод авторизації не підтримуєтьÑÑ" + 8 "Потрібна тверда авторизаціÑ" + 9 "Referral (v2)" + 10 "Referral" + 11 "Перевищено Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð°Ð´Ð¼Ñ–Ð½Ñ–ÑтруваннÑ" + 12 "Unavailable Critical Extension" + 13 "Потрібна конфіденційніÑть" + 14 "" + 15 "" + 16 "Ðемає такої влаÑтивоÑті" + 17 "Ðевизначений тип" + 18 "Inappropriate Matching" + 19 "Constraint Violation" + 20 "Ð’ÑаÑтивіÑть або Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ–Ñнує" + 21 "Ðеправильний ÑинтакÑ" + 22 "" + 23 "" + 24 "" + 25 "" + 26 "" + 27 "" + 28 "" + 29 "" + 30 "" + 31 "" + 32 "Ðемає такого об'єкту" + 33 "Проблема з пÑевдонімом" + 34 "Ðевірний DN ÑинтакÑиÑ" + 35 "Це лиÑÑ‚ дерева" + 36 "Проблема Ð·Ð²ÐµÑ€Ð½ÐµÐ½Ð½Ñ Ð´Ð¾ пÑевдоніму" + 37 "" + 38 "" + 39 "" + 40 "" + 41 "" + 42 "" + 43 "" + 44 "" + 45 "" + 46 "" + 47 "" + 48 "Inappropriate Authentication" + 49 "Ðевірні облікові дані" + 50 "ÐедоÑтатньо прав" + 51 "ЗайнÑто" + 52 "ÐедоÑтупно" + 53 "Unwilling To Perform" + 54 "ВиÑвлено зациклюваннÑ" + 55 "" + 56 "" + 57 "" + 58 "" + 59 "" + 60 "ВідÑутнє ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ ÑортуваннÑм" + 61 "Помилка діапазону індекÑу" + 62 "" + 63 "" + 64 "ÐŸÐ¾Ñ€ÑƒÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ð² найменуваннÑ" + 65 "ÐŸÐ¾Ñ€ÑƒÑˆÐµÐ½Ð½Ñ ÐºÐ»Ð°Ñу об'єкту" + 66 "Ðе дозволено не налиÑті дерева" + 67 "Ðе дозволено на RDN" + 68 "Вже Ñ–Ñнує" + 69 "Ðемає режимів клаÑу об'єкту" + 70 "Результати завеликі" + 71 "Впливає на декілька DSA" + 72 "" + 73 "" + 74 "" + 75 "" + 76 "" + 77 "" + 78 "" + 79 "" + 80 "Інший" + 81 "Сервер недоÑтупний" + 82 "Локальна помилка" + 83 "Помилка кодуваннÑ" + 84 "Помилка декодуваннÑ" + 85 "Timeout" + 86 "Auth Unknown" + 87 "Помилка фільтру" + 88 "Відмінено кориÑтувачем" + 89 "Помилка параметра" + 90 "Ðемає пам'Ñті" + 91 "Ðеможливо підключитиÑÑŒ до LDAP Ñервера" + 92 "ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ðµ підтримуєтьÑÑ Ñ†Ñ–Ñ”ÑŽ верÑією протоколу LDAP" + 93 "Вказаний елемент ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ знайдено в повідомленні" + 94 "Ð’ повідомленні немає результату" + 95 "More results returned" + 96 "Loop while handling referrals" + 97 "Referral hop limit exceeded" +} diff --git a/reactos/dll/win32/wuapi/main.c b/reactos/dll/win32/wuapi/main.c index d8d6fcb062c..d46ad38c99f 100644 --- a/reactos/dll/win32/wuapi/main.c +++ b/reactos/dll/win32/wuapi/main.c @@ -149,6 +149,5 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) HRESULT WINAPI DllCanUnloadNow( void ) { - FIXME("\n"); return S_FALSE; } diff --git a/reactos/dll/win32/wuapi/regsvr.c b/reactos/dll/win32/wuapi/regsvr.c index 10d3974d508..167368c6db7 100644 --- a/reactos/dll/win32/wuapi/regsvr.c +++ b/reactos/dll/win32/wuapi/regsvr.c @@ -400,7 +400,7 @@ static struct regsvr_interface const interface_list[] = { }; /*********************************************************************** - * DllRegisterServer (INETCOMM.@) + * DllRegisterServer (WUAPI.@) */ HRESULT WINAPI DllRegisterServer(void) { @@ -415,7 +415,7 @@ HRESULT WINAPI DllRegisterServer(void) } /*********************************************************************** - * DllUnregisterServer (INETCOMM.@) + * DllUnregisterServer (WUAPI.@) */ HRESULT WINAPI DllUnregisterServer(void) { diff --git a/reactos/dll/win32/xinput1_3/xinput1_3_main.c b/reactos/dll/win32/xinput1_3/xinput1_3_main.c index f4386b891f8..fc55cef37b7 100644 --- a/reactos/dll/win32/xinput1_3/xinput1_3_main.c +++ b/reactos/dll/win32/xinput1_3/xinput1_3_main.c @@ -105,7 +105,7 @@ DWORD WINAPI XInputGetCapabilities(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPA DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD dwUserIndex, GUID* pDSoundRenderGuid, GUID* pDSoundCaptureGuid) { - FIXME("(%d %s %s) Stub!\n", dwUserIndex, debugstr_guid(pDSoundRenderGuid), debugstr_guid(pDSoundCaptureGuid)); + FIXME("(%d %p %p) Stub!\n", dwUserIndex, pDSoundRenderGuid, pDSoundCaptureGuid); if (dwUserIndex < XUSER_MAX_COUNT) { diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 6bbe28d21b2..d8eb71f78f1 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -37,24 +37,24 @@ reactos/dll/directx/dmusic # Synced to Wine-1_1_23 reactos/dll/directx/dplay # Synced to Wine-0_9_5 reactos/dll/directx/dplayx # Synced to Wine-0_9_5 reactos/dll/directx/dxdiagn # Synced to Wine-0_9_5 -reactos/dll/directx/msdmo # Autosync* +reactos/dll/directx/msdmo # Autosync reactos/dll/directx/qedit # Autosync reactos/dll/directx/quartz # Autosync -reactos/dll/win32/advpack # Autosync* +reactos/dll/win32/advpack # Autosync reactos/dll/win32/atl # Autosync -reactos/dll/win32/avifil32 # Autosync* -reactos/dll/win32/bcrypt # Autosync* +reactos/dll/win32/avifil32 # Autosync +reactos/dll/win32/bcrypt # Autosync reactos/dll/win32/browseui # Out of sync -reactos/dll/win32/cabinet # Autosync* +reactos/dll/win32/cabinet # Autosync reactos/dll/win32/clusapi # Autosync -reactos/dll/win32/comcat # Autosync* -reactos/dll/win32/comctl32 # Autosync* -reactos/dll/win32/comdlg32 # Autosync* -reactos/dll/win32/compstui # Autosync* +reactos/dll/win32/comcat # Autosync +reactos/dll/win32/comctl32 # Autosync ?? +reactos/dll/win32/comdlg32 # Autosync ?? +reactos/dll/win32/compstui # Autosync reactos/dll/win32/credui # Autosync reactos/dll/win32/crypt32 # Synced to Wine-1_1_40 reactos/dll/win32/cryptdlg # Autosync -reactos/dll/win32/cryptdll # Autosync* +reactos/dll/win32/cryptdll # Autosync reactos/dll/win32/cryptnet # Autosync reactos/dll/win32/cryptui # Autosync reactos/dll/win32/dbghelp # Synced to Wine-20080802 @@ -64,124 +64,123 @@ reactos/dll/win32/fusion # Autosync reactos/dll/win32/gdiplus # Autosync reactos/dll/win32/hhctrl.ocx # Autosync reactos/dll/win32/hlink # Autosync -reactos/dll/win32/hnetcfg # Autosync* -reactos/dll/win32/httpapi # Autosync* +reactos/dll/win32/hnetcfg # Autosync +reactos/dll/win32/httpapi # Autosync reactos/dll/win32/iccvid # Autosync reactos/dll/win32/icmp # Synced to Wine-0_9_10 -reactos/dll/win32/imaadp32.acm # Autosync* +reactos/dll/win32/imaadp32.acm # Autosync reactos/dll/win32/imm32 # Autosync reactos/dll/win32/imagehlp # Patches for BindImage need review and submission to winehq. reactos/dll/win32/inetcomm # Autosync reactos/dll/win32/inetmib1 # Autosync -reactos/dll/win32/initpki # Autosync* -reactos/dll/win32/inseng # Autosync* +reactos/dll/win32/initpki # Autosync +reactos/dll/win32/inseng # Autosync reactos/dll/win32/iphlpapi # Out of sync reactos/dll/win32/itircl # Autosync reactos/dll/win32/itss # Autosync reactos/dll/win32/jscript # Autosync -reactos/dll/win32/localspl # Autosync* -reactos/dll/win32/localui # Autosync* -reactos/dll/win32/lz32 # Autosync* +reactos/dll/win32/localspl # Autosync +reactos/dll/win32/localui # Autosync +reactos/dll/win32/lz32 # Autosync reactos/dll/win32/mapi32 # Autosync -reactos/dll/win32/mciavi32 # Autosync* -reactos/dll/win32/mcicda # Autosync* -reactos/dll/win32/mciqtz32 # Autosync* -reactos/dll/win32/mciseq # Autosync* +reactos/dll/win32/mciavi32 # Autosync +reactos/dll/win32/mcicda # Autosync +reactos/dll/win32/mciqtz32 # Autosync +reactos/dll/win32/mciseq # Autosync reactos/dll/win32/mciwave # Autosync -reactos/dll/win32/mlang # Autosync* +reactos/dll/win32/mlang # Autosync reactos/dll/win32/mpr # Autosync reactos/dll/win32/msacm32 # Out of sync -reactos/dll/win32/msadp32.acm # Autosync* -reactos/dll/win32/mscat32 # Autosync* -reactos/dll/win32/mscms # Autosync* +reactos/dll/win32/msadp32.acm # Autosync +reactos/dll/win32/mscat32 # Autosync +reactos/dll/win32/mscms # Autosync reactos/dll/win32/mscoree # Autosync reactos/dll/win32/msctf # Autosync -reactos/dll/win32/msftedit # Autosync* -reactos/dll/win32/msg711.acm # Autosync* -reactos/dll/win32/msgsm32.acm # Autosync* +reactos/dll/win32/msftedit # Autosync +reactos/dll/win32/msg711.acm # Autosync +reactos/dll/win32/msgsm32.acm # Autosync reactos/dll/win32/mshtml # Autosync -reactos/dll/win32/msimg32 # Autosync* +reactos/dll/win32/msimg32 # Autosync reactos/dll/win32/msi # Autosync -reactos/dll/win32/msimtf # Autosync* -reactos/dll/win32/msisip # Autosync* -reactos/dll/win32/msisys.ocx # Autosync* -reactos/dll/win32/msnet32 # Autosync* -reactos/dll/win32/msrle32 # Autosync* -reactos/dll/win32/mssign32 # Autosync* -reactos/dll/win32/mssip32 # Autosync* -reactos/dll/win32/mstask # Autosync* -reactos/dll/win32/msvcrt20 # Autosync* -reactos/dll/win32/msvfw32 # Autosync* -reactos/dll/win32/msvidc32 # Autosync* +reactos/dll/win32/msimtf # Autosync +reactos/dll/win32/msisip # Autosync +reactos/dll/win32/msisys.ocx # Autosync +reactos/dll/win32/msnet32 # Autosync +reactos/dll/win32/msrle32 # Autosync +reactos/dll/win32/mssign32 # Autosync +reactos/dll/win32/mssip32 # Autosync +reactos/dll/win32/mstask # Autosync +reactos/dll/win32/msvcrt20 # Autosync +reactos/dll/win32/msvfw32 # Autosync +reactos/dll/win32/msvidc32 # Autosync reactos/dll/win32/msxml3 # Synced to Wine-1_1_40 -reactos/dll/win32/nddeapi # Autosync* +reactos/dll/win32/nddeapi # Autosync reactos/dll/win32/netapi32 # Autosync -reactos/dll/win32/ntdsapi # Autosync* -reactos/dll/win32/ntprint # Autosync* +reactos/dll/win32/ntdsapi # Autosync +reactos/dll/win32/ntprint # Autosync reactos/dll/win32/objsel # Autosync reactos/dll/win32/odbc32 # Out of sync. Depends on port of Linux ODBC. -reactos/dll/win32/odbccp32 # Autosync* +reactos/dll/win32/odbccp32 # Autosync reactos/dll/win32/ole32 # Autosync reactos/dll/win32/oleacc # Autosync -reactos/dll/win32/oleaut32 # Autosync* -reactos/dll/win32/olecli32 # Autosync* +reactos/dll/win32/oleaut32 # Autosync ?? +reactos/dll/win32/olecli32 # Autosync reactos/dll/win32/oledlg # Autosync reactos/dll/win32/olepro32 # Autosync -reactos/dll/win32/olesvr32 # Autosync* -reactos/dll/win32/olethk32 # Autosync* +reactos/dll/win32/olesvr32 # Autosync +reactos/dll/win32/olethk32 # Autosync reactos/dll/win32/pdh # Autosync -reactos/dll/win32/pidgen # Autosync* +reactos/dll/win32/pidgen # Autosync reactos/dll/win32/powrprof # Forked at Wine-1.0rc5 -reactos/dll/win32/printui # Autosync* +reactos/dll/win32/printui # Autosync reactos/dll/win32/pstorec # Autosync reactos/dll/win32/query # Autosync -reactos/dll/win32/rasapi32 # Autosync* -reactos/dll/win32/resutils # Autosync* -reactos/dll/win32/riched20 # Autosync* -reactos/dll/win32/riched32 # Autosync* +reactos/dll/win32/rasapi32 # Autosync +reactos/dll/win32/resutils # Autosync +reactos/dll/win32/riched20 # Autosync ?? +reactos/dll/win32/riched32 # Autosync reactos/dll/win32/rpcrt4 # Synced to Wine-0_9_55 -reactos/dll/win32/rsabase # Autosync* +reactos/dll/win32/rsabase # Autosync reactos/dll/win32/rsaenh # Autosync -reactos/dll/win32/sccbase # Autosync* -reactos/dll/win32/schannel # Autosync* -reactos/dll/win32/sensapi # Autosync* +reactos/dll/win32/sccbase # Autosync +reactos/dll/win32/schannel # Autosync ?? +reactos/dll/win32/sensapi # Autosync reactos/dll/win32/setupapi # Forked at Wine-20050524 reactos/dll/win32/shell32 # Forked at Wine-20071011 reactos/dll/win32/shdocvw # Synced to Wine-1_1_40 -reactos/dll/win32/shfolder # Autosync* +reactos/dll/win32/shfolder # Autosync reactos/dll/win32/shlwapi # Autosync -reactos/dll/win32/slbcsp # Autosync* -reactos/dll/win32/softpub # Autosync* -reactos/dll/win32/spoolss # Autosync* -reactos/dll/win32/stdole2.tlb # Autosync* -reactos/dll/win32/sti # Autosync* -reactos/dll/win32/sxs # Autosync* +reactos/dll/win32/slbcsp # Autosync +reactos/dll/win32/softpub # Autosync +reactos/dll/win32/spoolss # Autosync +reactos/dll/win32/stdole2.tlb # Autosync +reactos/dll/win32/sti # Autosync ?? +reactos/dll/win32/sxs # Autosync reactos/dll/win32/tapi32 # Autosync -reactos/dll/win32/traffic # Autosync* +reactos/dll/win32/traffic # Autosync reactos/dll/win32/twain_32 # Out of sync -reactos/dll/win32/updspapi # Autosync* -reactos/dll/win32/url # Autosync* +reactos/dll/win32/updspapi # Autosync +reactos/dll/win32/url # Autosync reactos/dll/win32/urlmon # Autosync -reactos/dll/win32/usp10 # Autosync* +reactos/dll/win32/usp10 # Autosync reactos/dll/win32/uxtheme # Autosync -reactos/dll/win32/version # Autosync* +reactos/dll/win32/version # Autosync ?? reactos/dll/win32/windowscodecs # Autosync -reactos/dll/win32/winemp3.acm # Autosync* -reactos/dll/win32/wininet # Autosync* -reactos/dll/win32/winhttp # Autosync* +reactos/dll/win32/winemp3.acm # Autosync ?? +reactos/dll/win32/wininet # Autosync ?? +reactos/dll/win32/winhttp # Autosync ?? reactos/dll/win32/winmm # Forked at Wine-20050628 reactos/dll/win32/winmm/midimap # Forked at Wine-20050628 reactos/dll/win32/winmm/wavemap # Forked at Wine-20050628 -reactos/dll/win32/wintab32 # Autosync* reactos/dll/win32/wintrust # Autosync -reactos/dll/win32/wldap32 # Autosync* -reactos/dll/win32/wmi # Autosync* +reactos/dll/win32/wldap32 # Autosync +reactos/dll/win32/wmi # Autosync reactos/dll/win32/wtsapi32 # Forked -reactos/dll/win32/wuapi # Autosync* -reactos/dll/win32/xinput1_1 # Autosync* -reactos/dll/win32/xinput1_2 # Autosync* -reactos/dll/win32/xinput1_3 # Autosync* -reactos/dll/win32/xinput9_1_0 # Autosync* +reactos/dll/win32/wuapi # Autosync +reactos/dll/win32/xinput1_1 # Autosync +reactos/dll/win32/xinput1_2 # Autosync +reactos/dll/win32/xinput1_3 # Autosync +reactos/dll/win32/xinput9_1_0 # Autosync reactos/dll/win32/xmllite # Autosync ReactOS shares the following programs with Winehq. From ae6e63592d458442bf7a09a6985e136460032169 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 10 Mar 2010 21:11:23 +0000 Subject: [PATCH 29/64] - Quit building a useless IO_RESOURCE_REQUIREMENTS_LIST (and leaking memory) in response to IRP_MN_QUERY_RESOURCES - Actually store the IO_RESOURCE_REQUIREMENTS_LIST in Irp->IoStatus.Information in response to IRP_MN_QUERY_RESOURCE_REQUIREMENTS so the PnP manager can use it (and fixes another memory leak) svn path=/trunk/; revision=46073 --- reactos/drivers/bus/acpi/buspdo.c | 50 ++----------------------------- 1 file changed, 2 insertions(+), 48 deletions(-) diff --git a/reactos/drivers/bus/acpi/buspdo.c b/reactos/drivers/bus/acpi/buspdo.c index 92bc18b4544..25fbe324f4f 100644 --- a/reactos/drivers/bus/acpi/buspdo.c +++ b/reactos/drivers/bus/acpi/buspdo.c @@ -595,10 +595,6 @@ Bus_PDO_QueryResources( ULONG ResourceListSize; ULONG i; - ULONG RequirementsListSize; - PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; - PIO_RESOURCE_DESCRIPTOR RequirementDescriptor; - /* Get current resources */ Buffer.Length = 0; @@ -672,24 +668,6 @@ Bus_PDO_QueryResources( ResourceList->List[0].PartialResourceList.Count = NumberOfResources; ResourceDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors; - RequirementsListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST) + sizeof(IO_RESOURCE_DESCRIPTOR) * (NumberOfResources - 1); - RequirementsList = (PIO_RESOURCE_REQUIREMENTS_LIST)ExAllocatePool(PagedPool, RequirementsListSize); - - if (!RequirementsList) - { - ExFreePool(ResourceList); - return STATUS_SUCCESS; - } - RequirementsList->ListSize = RequirementsListSize; - RequirementsList->InterfaceType = Internal; - RequirementsList->BusNumber = 0; - RequirementsList->SlotNumber = 0; /* Not used by WDM drivers */ - RequirementsList->AlternativeLists = 1; - RequirementsList->List[0].Version = 1; - RequirementsList->List[0].Revision = 1; - RequirementsList->List[0].Count = NumberOfResources; - RequirementDescriptor = RequirementsList->List[0].Descriptors; - /* Fill resources list structure */ Done = FALSE; while (!Done) @@ -711,15 +689,7 @@ Bus_PDO_QueryResources( ResourceDescriptor->u.Interrupt.Vector = 0; ResourceDescriptor->u.Interrupt.Affinity = (KAFFINITY)(-1); - RequirementDescriptor->Option = 0; /* Required */ - RequirementDescriptor->Type = ResourceDescriptor->Type; - RequirementDescriptor->ShareDisposition = ResourceDescriptor->ShareDisposition; - RequirementDescriptor->Flags = ResourceDescriptor->Flags; - RequirementDescriptor->u.Interrupt.MinimumVector = RequirementDescriptor->u.Interrupt.MaximumVector - = irq_data->Interrupts[i]; - ResourceDescriptor++; - RequirementDescriptor++; } break; } @@ -746,15 +716,7 @@ Bus_PDO_QueryResources( } ResourceDescriptor->u.Dma.Channel = dma_data->Channels[i]; - RequirementDescriptor->Option = 0; /* Required */ - RequirementDescriptor->Type = ResourceDescriptor->Type; - RequirementDescriptor->ShareDisposition = ResourceDescriptor->ShareDisposition; - RequirementDescriptor->Flags = ResourceDescriptor->Flags; - RequirementDescriptor->u.Dma.MinimumChannel = RequirementDescriptor->u.Dma.MaximumChannel - = ResourceDescriptor->u.Dma.Channel; - ResourceDescriptor++; - RequirementDescriptor++; } break; } @@ -772,17 +734,7 @@ Bus_PDO_QueryResources( ResourceDescriptor->u.Port.Start.u.LowPart = io_data->Minimum; ResourceDescriptor->u.Port.Length = io_data->AddressLength; - RequirementDescriptor->Option = 0; /* Required */ - RequirementDescriptor->Type = ResourceDescriptor->Type; - RequirementDescriptor->ShareDisposition = ResourceDescriptor->ShareDisposition; - RequirementDescriptor->Flags = ResourceDescriptor->Flags; - RequirementDescriptor->u.Port.Length = ResourceDescriptor->u.Port.Length; - RequirementDescriptor->u.Port.Alignment = 1; /* Start address is specified, so it doesn't matter */ - RequirementDescriptor->u.Port.MinimumAddress = RequirementDescriptor->u.Port.MaximumAddress - = ResourceDescriptor->u.Port.Start; - ResourceDescriptor++; - RequirementDescriptor++; break; } case ACPI_RESOURCE_TYPE_END_TAG: @@ -983,6 +935,8 @@ Bus_PDO_QueryResourceRequirements( } ExFreePool(Buffer.Pointer); + Irp->IoStatus.Information = (ULONG_PTR)RequirementsList; + return STATUS_SUCCESS; } From cd65ed5bdbcb312151313e4d6a6c0877e278cb15 Mon Sep 17 00:00:00 2001 From: Sylvain Petreolle Date: Wed, 10 Mar 2010 21:49:42 +0000 Subject: [PATCH 30/64] [ACPI] Fix implicit declaration warnings svn path=/trunk/; revision=46075 --- reactos/drivers/bus/acpi/include/acpi_bus.h | 4 ++++ reactos/drivers/bus/acpi/include/acpisys.h | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/reactos/drivers/bus/acpi/include/acpi_bus.h b/reactos/drivers/bus/acpi/include/acpi_bus.h index fa264a19c27..d5fe9efccc6 100644 --- a/reactos/drivers/bus/acpi/include/acpi_bus.h +++ b/reactos/drivers/bus/acpi/include/acpi_bus.h @@ -318,6 +318,7 @@ int acpi_bus_set_power(ACPI_HANDLE handle, int state); BOOLEAN acpi_bus_power_manageable(ACPI_HANDLE handle); BOOLEAN acpi_bus_can_wakeup(ACPI_HANDLE handle); int acpi_bus_generate_proc_event(struct acpi_device *device, UINT8 type, int data); +int acpi_bus_generate_event(struct acpi_device *device, UINT8 type, int data); int acpi_bus_receive_event(struct acpi_bus_event *event); int acpi_bus_register_driver(struct acpi_driver *driver); void acpi_bus_unregister_driver(struct acpi_driver *driver); @@ -328,6 +329,9 @@ int acpi_bus_start(struct acpi_device *device); ACPI_STATUS acpi_bus_get_ejd(ACPI_HANDLE handle, ACPI_HANDLE * ejd); int acpi_match_device_ids(struct acpi_device *device, const struct acpi_device_id *ids); +int acpi_bus_get_device(ACPI_HANDLE handle, struct acpi_device **device); +int acpi_init(void); +ACPI_STATUS acpi_suspend (UINT32 state); /* * Bind physical devices with ACPI devices diff --git a/reactos/drivers/bus/acpi/include/acpisys.h b/reactos/drivers/bus/acpi/include/acpisys.h index 4779d2233f8..368ac97c83f 100644 --- a/reactos/drivers/bus/acpi/include/acpisys.h +++ b/reactos/drivers/bus/acpi/include/acpisys.h @@ -86,9 +86,9 @@ typedef struct _FDO_DEVICE_DATA /* acpienum.c */ -//NTSTATUS -//ACPIEnumerateDevices( -// PFDO_DEVICE_EXTENSION DeviceExtension); +NTSTATUS +ACPIEnumerateDevices( + PFDO_DEVICE_DATA DeviceExtension); NTSTATUS NTAPI From f0a96d12a1fa81f97700e5a413f1099ef484903b Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Wed, 10 Mar 2010 21:52:00 +0000 Subject: [PATCH 31/64] [PSDK] add extern GUID_NULL svn path=/trunk/; revision=46076 --- reactos/include/psdk/guiddef.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/include/psdk/guiddef.h b/reactos/include/psdk/guiddef.h index b02e57e4972..e96e9e9f566 100644 --- a/reactos/include/psdk/guiddef.h +++ b/reactos/include/psdk/guiddef.h @@ -140,4 +140,6 @@ inline bool operator!=(const GUID& guidOne, const GUID& guidOther) #endif #endif +extern const IID GUID_NULL; + #endif /* _GUIDDEF_H_ */ From 418f2cc0e16d0bbb6960cf94e559046cfbe48c46 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Wed, 10 Mar 2010 21:52:40 +0000 Subject: [PATCH 32/64] [OLE32_WINETEST] sync OLE32_WINETEST with wine 1.1.40 svn path=/trunk/; revision=46077 --- rostests/winetests/ole32/clipboard.c | 65 +- rostests/winetests/ole32/compobj.c | 209 ++- rostests/winetests/ole32/hglobalstream.c | 151 ++ rostests/winetests/ole32/marshal.c | 71 +- rostests/winetests/ole32/moniker.c | 89 +- rostests/winetests/ole32/ole2.c | 40 + rostests/winetests/ole32/stg_prop.c | 6 + rostests/winetests/ole32/storage32.c | 1791 ++++++++++++++++++++-- rostests/winetests/ole32/usrmarshal.c | 328 +++- 9 files changed, 2508 insertions(+), 242 deletions(-) diff --git a/rostests/winetests/ole32/clipboard.c b/rostests/winetests/ole32/clipboard.c index f06a4823ac0..626d244c073 100644 --- a/rostests/winetests/ole32/clipboard.c +++ b/rostests/winetests/ole32/clipboard.c @@ -477,8 +477,6 @@ static void test_get_clipboard(void) hr = IDataObject_QueryGetData(data_obj, &fmtetc); ok(hr == DV_E_FORMATETC || broken(hr == S_OK), "IDataObject_QueryGetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr); - if (hr == S_OK) - ReleaseStgMedium(&stgmedium); InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL); fmtetc.cfFormat = CF_RIFF; @@ -499,19 +497,19 @@ static void test_get_clipboard(void) InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL); hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium); ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr); - ReleaseStgMedium(&stgmedium); + if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium); InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL); fmtetc.dwAspect = 0xdeadbeef; hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium); ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr); - ReleaseStgMedium(&stgmedium); + if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium); InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL); fmtetc.dwAspect = DVASPECT_THUMBNAIL; hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium); ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr); - ReleaseStgMedium(&stgmedium); + if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium); InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL); fmtetc.lindex = 256; @@ -528,11 +526,13 @@ static void test_get_clipboard(void) fmtetc.cfFormat = CF_RIFF; hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium); ok(hr == DV_E_FORMATETC, "IDataObject_GetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr); + if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium); InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL); fmtetc.tymed = TYMED_FILE; hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium); ok(hr == DV_E_TYMED, "IDataObject_GetData should have failed with DV_E_TYMED instead of 0x%08x\n", hr); + if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium); ok(DataObjectImpl_GetData_calls == 6, "DataObjectImpl_GetData should have been called 6 times instead of %d times\n", DataObjectImpl_GetData_calls); @@ -735,7 +735,7 @@ static void test_cf_dataobject(IDataObject *data) DVTARGETDEVICE *target; ok(fmt_ptr->fmt.ptd != NULL, "target device offset zero\n"); - target = (DVTARGETDEVICE*)((char*)priv + (DWORD)fmt_ptr->fmt.ptd); + target = (DVTARGETDEVICE*)((char*)priv + (DWORD_PTR)fmt_ptr->fmt.ptd); ok(!memcmp(target, fmt.ptd, fmt.ptd->tdSize), "target devices differ\n"); CoTaskMemFree(fmt.ptd); } @@ -967,7 +967,7 @@ static void test_consumer_refs(void) hr = IDataObject_GetData(get1, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(DataObjectImpl_GetData_calls == 0, "GetData called\n"); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); hr = OleGetClipboard(&get2); ok(hr == S_OK, "got %08x\n", hr); @@ -1004,7 +1004,7 @@ static void test_consumer_refs(void) hr = IDataObject_GetData(get1, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(DataObjectImpl_GetData_calls == 1, "GetData not called\n"); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); refs = count_refs(src); ok(refs == old_refs + 1, "%d %d\n", refs, old_refs); @@ -1014,7 +1014,7 @@ static void test_consumer_refs(void) hr = IDataObject_GetData(get1, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(DataObjectImpl_GetData_calls == 1, "GetData not called\n"); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); refs = count_refs(src); ok(refs == 2, "%d\n", refs); @@ -1047,7 +1047,7 @@ static void test_consumer_refs(void) hr = IDataObject_GetData(get1, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(DataObjectImpl_GetData_calls == 1, "GetData not called\n"); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); refs = count_refs(src); ok(refs == 1, "%d\n", refs); @@ -1096,23 +1096,24 @@ static void test_flushed_getdata(void) hr = IDataObject_GetData(get, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); InitFormatEtc(fmt, CF_TEXT, TYMED_ISTREAM); hr = IDataObject_GetData(get, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); InitFormatEtc(fmt, CF_TEXT, TYMED_ISTORAGE); hr = IDataObject_GetData(get, &fmt, &med); ok(hr == E_FAIL, "got %08x\n", hr); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); InitFormatEtc(fmt, CF_TEXT, 0xffff); hr = IDataObject_GetData(get, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); /* stream format -> global & stream */ @@ -1120,23 +1121,24 @@ static void test_flushed_getdata(void) hr = IDataObject_GetData(get, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); InitFormatEtc(fmt, cf_stream, TYMED_ISTORAGE); hr = IDataObject_GetData(get, &fmt, &med); ok(hr == E_FAIL, "got %08x\n", hr); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); InitFormatEtc(fmt, cf_stream, TYMED_HGLOBAL); hr = IDataObject_GetData(get, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); InitFormatEtc(fmt, cf_stream, 0xffff); hr = IDataObject_GetData(get, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); /* storage format -> global, stream & storage */ @@ -1144,34 +1146,36 @@ static void test_flushed_getdata(void) hr = IDataObject_GetData(get, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed); - hr = IStorage_Stat(med.u.pstg, &stat, STATFLAG_NONAME); - ok(hr == S_OK, "got %08x\n", hr); - ok(stat.grfMode == (STGM_SHARE_EXCLUSIVE | STGM_READWRITE), "got %08x\n", stat.grfMode); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) { + hr = IStorage_Stat(med.u.pstg, &stat, STATFLAG_NONAME); + ok(hr == S_OK, "got %08x\n", hr); + ok(stat.grfMode == (STGM_SHARE_EXCLUSIVE | STGM_READWRITE), "got %08x\n", stat.grfMode); + ReleaseStgMedium(&med); + } InitFormatEtc(fmt, cf_storage, TYMED_ISTREAM); hr = IDataObject_GetData(get, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); InitFormatEtc(fmt, cf_storage, TYMED_HGLOBAL); hr = IDataObject_GetData(get, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); InitFormatEtc(fmt, cf_storage, TYMED_HGLOBAL | TYMED_ISTREAM); hr = IDataObject_GetData(get, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); InitFormatEtc(fmt, cf_storage, 0xffff); hr = IDataObject_GetData(get, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); /* complex format with target device */ @@ -1180,7 +1184,7 @@ static void test_flushed_getdata(void) ok(hr == DV_E_FORMATETC || broken(hr == S_OK), /* win9x, winme & nt4 */ "got %08x\n", hr); - if(hr == S_OK) ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); InitFormatEtc(fmt, cf_another, 0xffff); memset(&dm, 0, sizeof(dm)); @@ -1199,7 +1203,7 @@ static void test_flushed_getdata(void) hr = IDataObject_GetData(get, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed); - ReleaseStgMedium(&med); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); HeapFree(GetProcessHeap(), 0, fmt.ptd); @@ -1235,6 +1239,8 @@ static void test_nonole_clipboard(void) FORMATETC fmt; HGLOBAL h, hblob, htext; HENHMETAFILE emf; + STGMEDIUM med; + DWORD obj_type; r = OpenClipboard(NULL); ok(r, "gle %d\n", GetLastError()); @@ -1349,6 +1355,13 @@ static void test_nonole_clipboard(void) ok(hr == S_FALSE, "got %08x\n", hr); IEnumFORMATETC_Release(enum_fmt); + InitFormatEtc(fmt, CF_ENHMETAFILE, TYMED_ENHMF); + hr = IDataObject_GetData(get, &fmt, &med); + ok(hr == S_OK, "got %08x\n", hr); + obj_type = GetObjectType(U(med).hEnhMetaFile); + ok(obj_type == OBJ_ENHMETAFILE, "got %d\n", obj_type); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); + IDataObject_Release(get); r = OpenClipboard(NULL); diff --git a/rostests/winetests/ole32/compobj.c b/rostests/winetests/ole32/compobj.c index 7363f30f735..9d469b4b174 100644 --- a/rostests/winetests/ole32/compobj.c +++ b/rostests/winetests/ole32/compobj.c @@ -25,11 +25,12 @@ #include "windef.h" #include "winbase.h" +#define USE_COM_CONTEXT_DEF +#include "initguid.h" #include "objbase.h" #include "shlguid.h" #include "urlmon.h" /* for CLSID_FileProtocol */ -#include "initguid.h" #include "ctxtcall.h" #include "wine/test.h" @@ -39,6 +40,7 @@ HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit); HRESULT (WINAPI * pCoGetObjectContext)(REFIID riid, LPVOID *ppv); HRESULT (WINAPI * pCoSwitchCallContext)(IUnknown *pObject, IUnknown **ppOldObject); HRESULT (WINAPI * pCoGetTreatAsClass)(REFCLSID clsidOld, LPCLSID pClsidNew); +HRESULT (WINAPI * pCoGetContextToken)(ULONG_PTR *token); #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr) #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks) @@ -201,6 +203,13 @@ static void test_StringFromGUID2(void) { WCHAR str[50]; int len; + + /* invalid pointer */ + SetLastError(0xdeadbeef); + len = StringFromGUID2(NULL,str,50); + ok(len == 0, "len: %d (expected 0)\n", len); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %x\n", GetLastError()); + /* Test corner cases for buffer size */ len = StringFromGUID2(&CLSID_StdFont,str,50); ok(len == 39, "len: %d (expected 39)\n", len); @@ -231,7 +240,7 @@ static DWORD CALLBACK ole_initialize_thread(LPVOID pv) hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED); SetEvent(info->wait); - WaitForSingleObject(info->stop, INFINITE); + WaitForSingleObject(info->stop, 10000); CoUninitialize(); return hr; @@ -252,7 +261,25 @@ static void test_CoCreateInstance(void) ok(pUnk == NULL, "CoCreateInstance should have changed the passed in pointer to NULL, instead of %p\n", pUnk); OleInitialize(NULL); + + /* test errors returned for non-registered clsids */ + hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk); + ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered inproc server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); + hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void **)&pUnk); + ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered inproc handler should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); + hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_LOCAL_SERVER, &IID_IUnknown, (void **)&pUnk); + ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered local server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); + hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_REMOTE_SERVER, &IID_IUnknown, (void **)&pUnk); + ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered remote server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); + hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk); + if(hr == REGDB_E_CLASSNOTREG) + { + skip("IE not installed so can't test CoCreateInstance\n"); + OleUninitialize(); + return; + } + ok_ole_success(hr, "CoCreateInstance"); if(pUnk) IUnknown_Release(pUnk); OleUninitialize(); @@ -272,7 +299,7 @@ static void test_CoCreateInstance(void) thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid); ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - WaitForSingleObject(info.wait, INFINITE); + ok( !WaitForSingleObject(info.wait, 10000 ), "wait timed out\n" ); pUnk = (IUnknown *)0xdeadbeef; hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk); @@ -280,7 +307,7 @@ static void test_CoCreateInstance(void) if (pUnk) IUnknown_Release(pUnk); SetEvent(info.stop); - WaitForSingleObject(thread, INFINITE); + ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); GetExitCodeThread(thread, &exitcode); hr = exitcode; @@ -321,15 +348,20 @@ static void test_CoGetClassObject(void) thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid); ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - WaitForSingleObject(info.wait, INFINITE); + ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" ); pUnk = (IUnknown *)0xdeadbeef; hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk); - ok(hr == S_OK, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr); - if (pUnk) IUnknown_Release(pUnk); + if(hr == REGDB_E_CLASSNOTREG) + skip("IE not installed so can't test CoGetClassObject\n"); + else + { + ok(hr == S_OK, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr); + if (pUnk) IUnknown_Release(pUnk); + } SetEvent(info.stop); - WaitForSingleObject(thread, INFINITE); + ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); GetExitCodeThread(thread, &exitcode); hr = exitcode; @@ -816,6 +848,14 @@ static void test_CoRegisterClassObject(void) hr = CoRevokeClassObject(cookie); ok_ole_success(hr, "CoRevokeClassObject"); + /* test whether an object that doesn't support IClassFactory can be + * registered for CLSCTX_LOCAL_SERVER */ + hr = CoRegisterClassObject(&CLSID_WineOOPTest, &Test_Unknown, + CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie); + ok_ole_success(hr, "CoRegisterClassObject"); + hr = CoRevokeClassObject(cookie); + ok_ole_success(hr, "CoRevokeClassObject"); + /* test whether registered class becomes invalid when apartment is destroyed */ hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory, CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie); @@ -935,7 +975,7 @@ static void test_registered_object_thread_affinity(void) thread = CreateThread(NULL, 0, get_class_object_thread, (LPVOID)CLSCTX_INPROC_SERVER, 0, &tid); ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - WaitForSingleObject(thread, INFINITE); + ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); GetExitCodeThread(thread, &exitcode); hr = exitcode; ok(hr == REGDB_E_CLASSNOTREG, "CoGetClassObject on inproc object " @@ -948,7 +988,7 @@ static void test_registered_object_thread_affinity(void) thread = CreateThread(NULL, 0, register_class_object_thread, NULL, 0, &tid); ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - WaitForSingleObject(thread, INFINITE); + ok ( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); GetExitCodeThread(thread, &exitcode); hr = exitcode; ok(hr == S_OK, "CoRegisterClassObject with same CLSID but in different thread should return S_OK instead of 0x%08x\n", hr); @@ -964,7 +1004,7 @@ static void test_registered_object_thread_affinity(void) thread = CreateThread(NULL, 0, get_class_object_proxy_thread, (LPVOID)CLSCTX_LOCAL_SERVER, 0, &tid); ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - while (MsgWaitForMultipleObjects(1, &thread, FALSE, INFINITE, QS_ALLINPUT) == WAIT_OBJECT_0 + 1) + while (MsgWaitForMultipleObjects(1, &thread, FALSE, 10000, QS_ALLINPUT) == WAIT_OBJECT_0 + 1) { MSG msg; while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) @@ -985,7 +1025,7 @@ static void test_registered_object_thread_affinity(void) thread = CreateThread(NULL, 0, revoke_class_object_thread, (LPVOID)(DWORD_PTR)cookie, 0, &tid); ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - WaitForSingleObject(thread, INFINITE); + ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); GetExitCodeThread(thread, &exitcode); hr = exitcode; ok(hr == RPC_E_WRONG_THREAD, "CoRevokeClassObject called from different " @@ -993,7 +1033,7 @@ static void test_registered_object_thread_affinity(void) thread = CreateThread(NULL, 0, register_class_object_thread, NULL, 0, &tid); ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - WaitForSingleObject(thread, INFINITE); + ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); GetExitCodeThread(thread, &exitcode); hr = exitcode; ok(hr == S_OK, "CoRegisterClassObject with same CLSID but in different " @@ -1030,7 +1070,7 @@ static void test_CoFreeUnusedLibraries(void) hr = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void **)&pUnk); if (hr == REGDB_E_CLASSNOTREG) { - trace("IE not installed so can't run CoFreeUnusedLibraries test\n"); + skip("IE not installed so can't run CoFreeUnusedLibraries test\n"); CoUninitialize(); return; } @@ -1047,7 +1087,7 @@ static void test_CoFreeUnusedLibraries(void) ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n"); thread = CreateThread(NULL, 0, free_libraries_thread, NULL, 0, &tid); - WaitForSingleObject(thread, INFINITE); + ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); CloseHandle(thread); ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n"); @@ -1065,8 +1105,12 @@ static void test_CoGetObjectContext(void) ULONG refs; IComThreadingInfo *pComThreadingInfo; IContextCallback *pContextCallback; + IObjContext *pObjContext; APTTYPE apttype; THDTYPE thdtype; + struct info info; + HANDLE thread; + DWORD tid, exitcode; if (!pCoGetObjectContext) { @@ -1078,6 +1122,36 @@ static void test_CoGetObjectContext(void) ok(hr == CO_E_NOTINITIALIZED, "CoGetObjectContext should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr); ok(pComThreadingInfo == NULL, "pComThreadingInfo should have been set to NULL\n"); + /* show that COM doesn't have to be initialized for multi-threaded apartments if another + thread has already done so */ + + info.wait = CreateEvent(NULL, TRUE, FALSE, NULL); + ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError()); + + info.stop = CreateEvent(NULL, TRUE, FALSE, NULL); + ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError()); + + thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid); + ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); + + ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" ); + + pComThreadingInfo = NULL; + hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo); + ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); + IComThreadingInfo_Release(pComThreadingInfo); + + SetEvent(info.stop); + ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); + + GetExitCodeThread(thread, &exitcode); + hr = exitcode; + ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr); + + CloseHandle(thread); + CloseHandle(info.wait); + CloseHandle(info.stop); + pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo); @@ -1130,6 +1204,12 @@ static void test_CoGetObjectContext(void) ok(refs == 0, "pContextCallback should have 0 refs instead of %d refs\n", refs); } + hr = pCoGetObjectContext(&IID_IObjContext, (void **)&pObjContext); + ok_ole_success(hr, "CoGetObjectContext"); + + refs = IObjContext_Release(pObjContext); + ok(refs == 0, "pObjContext should have 0 refs instead of %d refs\n", refs); + CoUninitialize(); } @@ -1233,6 +1313,101 @@ static void test_CoGetCallContext(void) CoUninitialize(); } +static void test_CoGetContextToken(void) +{ + HRESULT hr; + ULONG refs; + ULONG_PTR token; + IObjContext *ctx; + struct info info; + HANDLE thread; + DWORD tid, exitcode; + + if (!pCoGetContextToken) + { + win_skip("CoGetContextToken not present\n"); + return; + } + + token = 0xdeadbeef; + hr = pCoGetContextToken(&token); + ok(hr == CO_E_NOTINITIALIZED, "Expected CO_E_NOTINITIALIZED, got 0x%08x\n", hr); + ok(token == 0xdeadbeef, "Expected 0, got 0x%lx\n", token); + + /* show that COM doesn't have to be initialized for multi-threaded apartments if another + thread has already done so */ + + info.wait = CreateEvent(NULL, TRUE, FALSE, NULL); + ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError()); + + info.stop = CreateEvent(NULL, TRUE, FALSE, NULL); + ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError()); + + thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid); + ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); + + ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" ); + + token = 0; + hr = pCoGetContextToken(&token); + ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); + + SetEvent(info.stop); + ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); + + GetExitCodeThread(thread, &exitcode); + hr = exitcode; + ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr); + + CloseHandle(thread); + CloseHandle(info.wait); + CloseHandle(info.stop); + + CoInitialize(NULL); + + hr = pCoGetContextToken(NULL); + ok(hr == E_POINTER, "Expected E_POINTER, got 0x%08x\n", hr); + + token = 0; + hr = pCoGetContextToken(&token); + ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); + ok(token, "Expected token != 0\n"); + + refs = IUnknown_AddRef((IUnknown *)token); + todo_wine ok(refs == 1, "Expected 1, got %u\n", refs); + + hr = pCoGetObjectContext(&IID_IObjContext, (void **)&ctx); + ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); + todo_wine ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n"); + + refs = IUnknown_AddRef((IUnknown *)ctx); + todo_wine ok(refs == 3, "Expected 3, got %u\n", refs); + + refs = IUnknown_Release((IUnknown *)ctx); + todo_wine ok(refs == 2, "Expected 2, got %u\n", refs); + + refs = IUnknown_Release((IUnknown *)token); + ok(refs == 1, "Expected 1, got %u\n", refs); + + /* CoGetContextToken does not add a reference */ + token = 0; + hr = pCoGetContextToken(&token); + ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); + ok(token, "Expected token != 0\n"); + todo_wine ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n"); + + refs = IUnknown_AddRef((IUnknown *)ctx); + ok(refs == 2, "Expected 1, got %u\n", refs); + + refs = IUnknown_Release((IUnknown *)ctx); + ok(refs == 1, "Expected 0, got %u\n", refs); + + refs = IUnknown_Release((IUnknown *)ctx); + ok(refs == 0, "Expected 0, got %u\n", refs); + + CoUninitialize(); +} + static void test_CoGetTreatAsClass(void) { HRESULT hr; @@ -1259,7 +1434,7 @@ static void test_CoInitializeEx(void) /* Calling OleInitialize for the first time should yield S_OK even with * apartment already initialized by previous CoInitialize(Ex) calls. */ hr = OleInitialize(NULL); - todo_wine ok(hr == S_OK, "OleInitialize failed with error 0x%08x\n", hr); + ok(hr == S_OK, "OleInitialize failed with error 0x%08x\n", hr); /* Subsequent calls to OleInitialize should return S_FALSE */ hr = OleInitialize(NULL); @@ -1276,6 +1451,7 @@ START_TEST(compobj) pCoGetObjectContext = (void*)GetProcAddress(hOle32, "CoGetObjectContext"); pCoSwitchCallContext = (void*)GetProcAddress(hOle32, "CoSwitchCallContext"); pCoGetTreatAsClass = (void*)GetProcAddress(hOle32,"CoGetTreatAsClass"); + pCoGetContextToken = (void*)GetProcAddress(hOle32, "CoGetContextToken"); if (!(pCoInitializeEx = (void*)GetProcAddress(hOle32, "CoInitializeEx"))) { trace("You need DCOM95 installed to run this test\n"); @@ -1301,6 +1477,7 @@ START_TEST(compobj) test_CoFreeUnusedLibraries(); test_CoGetObjectContext(); test_CoGetCallContext(); + test_CoGetContextToken(); test_CoGetTreatAsClass(); test_CoInitializeEx(); } diff --git a/rostests/winetests/ole32/hglobalstream.c b/rostests/winetests/ole32/hglobalstream.c index cae13ed2ea9..5632b24ae44 100644 --- a/rostests/winetests/ole32/hglobalstream.c +++ b/rostests/winetests/ole32/hglobalstream.c @@ -75,6 +75,157 @@ static void test_streamonhglobal(IStream *pStream) hr = IStream_SetSize(pStream, ull); ok_ole_success(hr, "IStream_SetSize"); + /* IStream_Seek -- NULL position argument */ + ll.u.HighPart = 0; + ll.u.LowPart = 0; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, NULL); + ok_ole_success(hr, "IStream_Seek"); + + /* IStream_Seek -- valid position argument (seek from current position) */ + ull.u.HighPart = 0xCAFECAFE; + ull.u.LowPart = 0xCAFECAFE; + ll.u.HighPart = 0; + ll.u.LowPart = 0; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); + ok_ole_success(hr, "IStream_Seek"); + ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart); + ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); + + /* IStream_Seek -- invalid seek argument */ + ull.u.HighPart = 0xCAFECAFE; + ull.u.LowPart = 0xCAFECAFE; + ll.u.HighPart = 0; + ll.u.LowPart = 123; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_END+1, &ull); + ok(hr == STG_E_SEEKERROR, "IStream_Seek should have returned STG_E_SEEKERROR instead of 0x%08x\n", hr); + ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart); + ok(ull.u.HighPart == 0, "should not have changed HighPart, got %d\n", ull.u.HighPart); + + /* IStream_Seek -- valid position argument (seek to beginning) */ + ull.u.HighPart = 0xCAFECAFE; + ull.u.LowPart = 0xCAFECAFE; + ll.u.HighPart = 0; + ll.u.LowPart = 0; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); + ok_ole_success(hr, "IStream_Seek"); + ok(ull.u.LowPart == 0, "should have set LowPart to 0 instead of %d\n", ull.u.LowPart); + ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); + + /* IStream_Seek -- valid position argument (seek to end) */ + ull.u.HighPart = 0xCAFECAFE; + ull.u.LowPart = 0xCAFECAFE; + ll.u.HighPart = 0; + ll.u.LowPart = 0; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_END, &ull); + ok_ole_success(hr, "IStream_Seek"); + ok(ull.u.LowPart == 0, "should have set LowPart to 0 instead of %d\n", ull.u.LowPart); + ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); + + /* IStream_Seek -- ignore HighPart in the move value (seek from current position) */ + ll.u.HighPart = 0; + ll.u.LowPart = sizeof(data); + hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); + ok_ole_success(hr, "IStream_Seek"); + + ull.u.HighPart = 0xCAFECAFE; + ull.u.LowPart = 0xCAFECAFE; + ll.u.HighPart = -1; + ll.u.LowPart = 0; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); + ok_ole_success(hr, "IStream_Seek"); + ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart); + ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); + + /* IStream_Seek -- ignore HighPart in the move value (seek to beginning) */ + ll.u.HighPart = 0; + ll.u.LowPart = sizeof(data); + hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); + ok_ole_success(hr, "IStream_Seek"); + + ull.u.HighPart = 0xCAFECAFE; + ull.u.LowPart = 0xCAFECAFE; + ll.u.HighPart = -1; + ll.u.LowPart = 0; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); + ok_ole_success(hr, "IStream_Seek"); + ok(ull.u.LowPart == 0, "should have set LowPart to 0 instead of %d\n", ull.u.LowPart); + ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); + + /* IStream_Seek -- invalid LowPart value (seek from current position) */ + ll.u.HighPart = 0; + ll.u.LowPart = sizeof(data); + hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); + ok_ole_success(hr, "IStream_Seek"); + + ull.u.HighPart = 0xCAFECAFE; + ull.u.LowPart = 0xCAFECAFE; + ll.u.HighPart = 0; + ll.u.LowPart = 0x80000000; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); + ok(hr == STG_E_SEEKERROR, "IStream_Seek should have returned STG_E_SEEKERROR instead of 0x%08x\n", hr); + ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart); + ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); + + /* IStream_Seek -- invalid LowPart value (seek to beginning) */ + ll.u.HighPart = 0; + ll.u.LowPart = sizeof(data); + hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); + ok_ole_success(hr, "IStream_Seek"); + + ull.u.HighPart = 0xCAFECAFE; + ull.u.LowPart = 0xCAFECAFE; + ll.u.HighPart = 0; + ll.u.LowPart = 0x80000000; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); + ok(hr == STG_E_SEEKERROR, "IStream_Seek should have returned STG_E_SEEKERROR instead of 0x%08x\n", hr); + ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart); + ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); + + /* IStream_Seek -- valid LowPart value (seek to beginning) */ + ull.u.HighPart = 0xCAFECAFE; + ull.u.LowPart = 0xCAFECAFE; + ll.u.HighPart = 0; + ll.u.LowPart = 0x7FFFFFFF; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); + ok_ole_success(hr, "IStream_Seek"); + ok(ull.u.LowPart == 0x7FFFFFFF, "should have set LowPart to 0x7FFFFFFF instead of %08x\n", ull.u.LowPart); + ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); + + /* IStream_Seek -- valid LowPart value (seek from current position) */ + ll.u.HighPart = 0; + ll.u.LowPart = 0; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); + ok_ole_success(hr, "IStream_Seek"); + + ull.u.HighPart = 0xCAFECAFE; + ull.u.LowPart = 0xCAFECAFE; + ll.u.HighPart = 0; + ll.u.LowPart = 0x7FFFFFFF; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); + ok_ole_success(hr, "IStream_Seek"); + ok(ull.u.LowPart == 0x7FFFFFFF, "should have set LowPart to 0x7FFFFFFF instead of %08x\n", ull.u.LowPart); + ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); + + /* IStream_Seek -- second seek allows you to go past 0x7FFFFFFF size */ + ull.u.HighPart = 0xCAFECAFE; + ull.u.LowPart = 0xCAFECAFE; + ll.u.HighPart = 0; + ll.u.LowPart = 9; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); + ok_ole_success(hr, "IStream_Seek"); + ok(ull.u.LowPart == 0x80000008, "should have set LowPart to 0x80000008 instead of %08x\n", ull.u.LowPart); + ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); + + /* IStream_Seek -- seek wraps position/size on integer overflow */ + ull.u.HighPart = 0xCAFECAFE; + ull.u.LowPart = 0xCAFECAFE; + ll.u.HighPart = 0; + ll.u.LowPart = 0x7FFFFFFF; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); + ok_ole_success(hr, "IStream_Seek"); + ok(ull.u.LowPart == 0x00000007, "should have set LowPart to 0x00000007 instead of %08x\n", ull.u.LowPart); + ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); + hr = IStream_Commit(pStream, STGC_DEFAULT); ok_ole_success(hr, "IStream_Commit"); diff --git a/rostests/winetests/ole32/marshal.c b/rostests/winetests/ole32/marshal.c index 40824881b01..20b0d8ba8ef 100644 --- a/rostests/winetests/ole32/marshal.c +++ b/rostests/winetests/ole32/marshal.c @@ -27,11 +27,11 @@ #include "windef.h" #include "winbase.h" -#include "initguid.h" #include "objbase.h" #include "olectl.h" #include "shlguid.h" #include "shobjidl.h" +#include "initguid.h" #include "wine/test.h" @@ -276,7 +276,7 @@ static DWORD start_host_object2(IStream *stream, REFIID riid, IUnknown *object, *thread = CreateThread(NULL, 0, host_object_proc, data, 0, &tid); /* wait for marshaling to complete before returning */ - WaitForSingleObject(marshal_event, INFINITE); + ok( !WaitForSingleObject(marshal_event, 10000), "wait timed out\n" ); CloseHandle(marshal_event); return tid; @@ -293,7 +293,7 @@ static void release_host_object(DWORD tid) { HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL); PostThreadMessage(tid, RELEASEMARSHALDATA, 0, (LPARAM)event); - WaitForSingleObject(event, INFINITE); + ok( !WaitForSingleObject(event, 10000), "wait timed out\n" ); CloseHandle(event); } @@ -302,7 +302,7 @@ static void end_host_object(DWORD tid, HANDLE thread) BOOL ret = PostThreadMessage(tid, WM_QUIT, 0, 0); ok(ret, "PostThreadMessage failed with error %d\n", GetLastError()); /* be careful of races - don't return until hosting thread has terminated */ - WaitForSingleObject(thread, INFINITE); + ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); CloseHandle(thread); } @@ -843,7 +843,7 @@ static DWORD CALLBACK no_couninitialize_server_proc(LPVOID p) SetEvent(ncu_params->marshal_event); - WaitForSingleObject(ncu_params->unmarshal_event, INFINITE); + ok( !WaitForSingleObject(ncu_params->unmarshal_event, 10000), "wait timed out\n" ); /* die without calling CoUninitialize */ @@ -872,7 +872,7 @@ static void test_no_couninitialize_server(void) thread = CreateThread(NULL, 0, no_couninitialize_server_proc, &ncu_params, 0, &tid); - WaitForSingleObject(ncu_params.marshal_event, INFINITE); + ok( !WaitForSingleObject(ncu_params.marshal_event, 10000), "wait timed out\n" ); ok_more_than_one_lock(); IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL); @@ -883,7 +883,7 @@ static void test_no_couninitialize_server(void) ok_more_than_one_lock(); SetEvent(ncu_params.unmarshal_event); - WaitForSingleObject(thread, INFINITE); + ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); ok_no_locks(); @@ -942,7 +942,7 @@ static void test_no_couninitialize_client(void) thread = CreateThread(NULL, 0, no_couninitialize_client_proc, &ncu_params, 0, &tid); - WaitForSingleObject(thread, INFINITE); + ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); CloseHandle(thread); ok_no_locks(); @@ -1109,7 +1109,7 @@ static DWORD CALLBACK weak_and_normal_marshal_thread_proc(void *p) SetEvent(data->hReadyEvent); - while (WAIT_OBJECT_0 + 1 == MsgWaitForMultipleObjects(1, &hQuitEvent, FALSE, INFINITE, QS_ALLINPUT)) + while (WAIT_OBJECT_0 + 1 == MsgWaitForMultipleObjects(1, &hQuitEvent, FALSE, 10000, QS_ALLINPUT)) { while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessage(&msg); @@ -1141,7 +1141,7 @@ static void test_tableweak_and_normal_marshal_and_unmarshal(void) ok_ole_success(hr, CreateStreamOnHGlobal); thread = CreateThread(NULL, 0, weak_and_normal_marshal_thread_proc, &data, 0, &tid); - WaitForSingleObject(data.hReadyEvent, INFINITE); + ok( !WaitForSingleObject(data.hReadyEvent, 10000), "wait timed out\n" ); CloseHandle(data.hReadyEvent); ok_more_than_one_lock(); @@ -1170,7 +1170,7 @@ static void test_tableweak_and_normal_marshal_and_unmarshal(void) IStream_Release(data.pStreamNormal); SetEvent(data.hQuitEvent); - WaitForSingleObject(thread, INFINITE); + ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); CloseHandle(thread); } @@ -1257,7 +1257,7 @@ static void test_lock_object_external(void) IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL); hr = CoReleaseMarshalData(pStream); ok_ole_success(hr, CoReleaseMarshalData); - IStream_Release(pStream); + IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL); ok_more_than_one_lock(); @@ -1268,6 +1268,39 @@ static void test_lock_object_external(void) CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, TRUE); ok_no_locks(); + + /* test CoLockObjectExternal releases reference to object with + * fLastUnlockReleases as TRUE and there are only strong references on + * the object */ + CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, FALSE); + + ok_more_than_one_lock(); + + CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, FALSE); + + ok_no_locks(); + + /* test CoLockObjectExternal doesn't release the last reference to an + * object with fLastUnlockReleases as TRUE and there is a weak reference + * on the object */ + hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLEWEAK); + ok_ole_success(hr, CoMarshalInterface); + + ok_more_than_one_lock(); + + CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, FALSE); + + ok_more_than_one_lock(); + + CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, FALSE); + + ok_more_than_one_lock(); + + CoDisconnectObject((IUnknown*)&Test_ClassFactory, 0); + + ok_no_locks(); + + IStream_Release(pStream); } /* tests disconnecting stubs */ @@ -1449,7 +1482,7 @@ static void test_proxy_used_in_wrong_thread(void) /* create a thread that we can misbehave in */ thread = CreateThread(NULL, 0, bad_thread_proc, pProxy, 0, &tid2); - WaitForSingleObject(thread, INFINITE); + ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); CloseHandle(thread); /* do release statement on Win9x that we should have done above */ @@ -1799,6 +1832,7 @@ static HRESULT WINAPI TestRE_IClassFactory_CreateInstance( BOOL ret = SendMessageTimeout(hwnd_app, WM_NULL, 0, 0, SMTO_BLOCK, 5000, &res); ok(ret, "Timed out sending a message to originating window during RPC call\n"); } + *ppvObj = NULL; return S_FALSE; } @@ -2071,7 +2105,7 @@ static void test_freethreadedmarshaldata(IStream *pStream, MSHCTX mshctx, void * { DWORD expected_size = round_global_size(3*sizeof(DWORD) + sizeof(GUID)); ok(size == expected_size || - broken(size == round_global_size(2*sizeof(DWORD))) /* Win9x & NT4 */, + broken(size == (2*sizeof(DWORD))) /* Win9x & NT4 */, "size should have been %d instead of %d\n", expected_size, size); ok(*(DWORD *)marshal_data == mshlflags, "expected 0x%x, but got 0x%x for mshctx\n", mshlflags, *(DWORD *)marshal_data); @@ -2259,7 +2293,7 @@ static void reg_unreg_wine_test_class(BOOL Register) { error = RegCreateKeyEx(HKEY_CLASSES_ROOT, buffer, 0, NULL, 0, KEY_SET_VALUE, NULL, &hkey, &dwDisposition); ok(error == ERROR_SUCCESS, "RegCreateKeyEx failed with error %d\n", error); - error = RegSetValueEx(hkey, NULL, 0, REG_SZ, (const unsigned char *)"ole32.dll", strlen("ole32.dll") + 1); + error = RegSetValueEx(hkey, NULL, 0, REG_SZ, (const unsigned char *)"\"ole32.dll\"", strlen("\"ole32.dll\"") + 1); ok(error == ERROR_SUCCESS, "RegSetValueEx failed with error %d\n", error); RegCloseKey(hkey); } @@ -2280,7 +2314,6 @@ static void test_inproc_handler(void) reg_unreg_wine_test_class(TRUE); hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void **)&pObject); - todo_wine ok_ole_success(hr, "CoCreateInstance"); if (SUCCEEDED(hr)) @@ -2701,7 +2734,7 @@ static void test_local_server(void) ok(process != NULL, "couldn't start local server process, error was %d\n", GetLastError()); ready_event = CreateEvent(NULL, FALSE, FALSE, "Wine COM Test Ready Event"); - WaitForSingleObject(ready_event, INFINITE); + ok( !WaitForSingleObject(ready_event, 10000), "wait timed out\n" ); CloseHandle(ready_event); hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IClassFactory, (void **)&cf); @@ -2781,13 +2814,13 @@ static void test_globalinterfacetable(void) * to exit before we can return */ thread = CreateThread(NULL, 0, get_global_interface_proc, ¶ms, 0, &tid); - ret = MsgWaitForMultipleObjects(1, &thread, FALSE, INFINITE, QS_ALLINPUT); + ret = MsgWaitForMultipleObjects(1, &thread, FALSE, 10000, QS_ALLINPUT); while (ret == WAIT_OBJECT_0 + 1) { MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessage(&msg); - ret = MsgWaitForMultipleObjects(1, &thread, FALSE, INFINITE, QS_ALLINPUT); + ret = MsgWaitForMultipleObjects(1, &thread, FALSE, 10000, QS_ALLINPUT); } CloseHandle(thread); diff --git a/rostests/winetests/ole32/moniker.c b/rostests/winetests/ole32/moniker.c index 413045a06b3..b4e3e2f7db4 100644 --- a/rostests/winetests/ole32/moniker.c +++ b/rostests/winetests/ole32/moniker.c @@ -28,6 +28,7 @@ #include "windef.h" #include "winbase.h" #include "objbase.h" +#include "initguid.h" #include "comcat.h" #include "olectl.h" @@ -1142,7 +1143,7 @@ static void test_moniker( LPBYTE moniker_data; DWORD moniker_size; DWORD i; - BOOL same = TRUE; + BOOL same; BYTE buffer[128]; IMoniker * moniker_proxy; LPOLESTR display_name; @@ -1182,6 +1183,7 @@ static void test_moniker( testname, sizeof_expected_moniker_comparison_data, moniker_size); /* then do a byte-by-byte comparison */ + same = TRUE; for (i = 0; i < min(moniker_size, sizeof_expected_moniker_comparison_data); i++) { if (expected_moniker_comparison_data[i] != buffer[i]) @@ -1225,6 +1227,7 @@ static void test_moniker( testname, (DWORD)round_global_size(sizeof_expected_moniker_saved_data), moniker_size); /* then do a byte-by-byte comparison */ + same = TRUE; for (i = 0; i < min(moniker_size, round_global_size(sizeof_expected_moniker_saved_data)); i++) { if (expected_moniker_saved_data[i] != moniker_data[i]) @@ -1271,6 +1274,7 @@ static void test_moniker( testname, (DWORD)round_global_size(sizeof_expected_moniker_marshal_data), moniker_size); /* then do a byte-by-byte comparison */ + same = TRUE; if (expected_moniker_marshal_data) { for (i = 0; i < min(moniker_size, round_global_size(sizeof_expected_moniker_marshal_data)); i++) @@ -1428,6 +1432,16 @@ static void test_file_monikers(void) for (i = 0; i < COUNTOF(wszFile); ++i) { int j ; + if (i == 2) + { + BOOL used; + WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, wszFile[i], -1, NULL, 0, NULL, &used ); + if (used) + { + skip("string 2 doesn't round trip in codepage %u\n", GetACP() ); + continue; + } + } for (j = lstrlenW(wszFile[i]); j > 0; --j) { wszFile[i][j] = 0; @@ -1481,7 +1495,6 @@ static void test_item_moniker(void) /* IsRunning test */ hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL); - todo_wine ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr); hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL); @@ -1617,7 +1630,6 @@ static void test_generic_composite_moniker(void) /* IsRunning test */ hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL); - todo_wine ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr); hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL); @@ -1631,7 +1643,6 @@ static void test_generic_composite_moniker(void) todo_wine ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr); - todo_wine hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown); ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr); @@ -1853,6 +1864,75 @@ static void test_bind_context(void) ok(!refs, "bound object should have been destroyed, instead of having %d refs\n", refs); } +static void test_save_load_filemoniker(void) +{ + IMoniker* pMk; + IStream* pStm; + HRESULT hr; + ULARGE_INTEGER size; + LARGE_INTEGER zero_pos, dead_pos, nulls_pos; + DWORD some_val = 0xFEDCBA98; + int i; + + /* see FileMonikerImpl_Save docs */ + zero_pos.QuadPart = 0; + dead_pos.QuadPart = sizeof(WORD) + sizeof(DWORD) + (lstrlenW(wszFileName1) + 1) + sizeof(WORD); + nulls_pos.QuadPart = dead_pos.QuadPart + sizeof(WORD); + + /* create the stream we're going to write to */ + hr = CreateStreamOnHGlobal(NULL, TRUE, &pStm); + ok_ole_success(hr, "CreateStreamOnHGlobal"); + + size.u.LowPart = 128; + hr = IStream_SetSize(pStm, size); + ok_ole_success(hr, "IStream_SetSize"); + + /* create and save a moniker */ + hr = CreateFileMoniker(wszFileName1, &pMk); + ok_ole_success(hr, "CreateFileMoniker"); + + hr = IMoniker_Save(pMk, pStm, TRUE); + ok_ole_success(hr, "IMoniker_Save"); + + hr = IMoniker_Release(pMk); + ok_ole_success(hr, "IMoniker_Release"); + + /* overwrite the constants with various values */ + hr = IStream_Seek(pStm, zero_pos, STREAM_SEEK_SET, NULL); + ok_ole_success(hr, "IStream_Seek"); + hr = IStream_Write(pStm, &some_val, sizeof(WORD), NULL); + ok_ole_success(hr, "IStream_Write"); + + hr = IStream_Seek(pStm, dead_pos, STREAM_SEEK_SET, NULL); + ok_ole_success(hr, "IStream_Seek"); + hr = IStream_Write(pStm, &some_val, sizeof(WORD), NULL); + ok_ole_success(hr, "IStream_Write"); + + hr = IStream_Seek(pStm, nulls_pos, STREAM_SEEK_SET, NULL); + ok_ole_success(hr, "IStream_Seek"); + for(i = 0; i < 5; ++i){ + hr = IStream_Write(pStm, &some_val, sizeof(DWORD), NULL); + ok_ole_success(hr, "IStream_Write"); + } + + /* go back to the start of the stream */ + hr = IStream_Seek(pStm, zero_pos, STREAM_SEEK_SET, NULL); + ok_ole_success(hr, "IStream_Seek"); + + /* create a new moniker and load into it */ + hr = CreateFileMoniker(wszFileName1, &pMk); + ok_ole_success(hr, "CreateFileMoniker"); + + hr = IMoniker_Load(pMk, pStm); + ok_ole_success(hr, "IMoniker_Load"); + + hr = IMoniker_Release(pMk); + ok_ole_success(hr, "IMoniker_Release"); + + hr = IStream_Release(pStm); + ok_ole_success(hr, "IStream_Release"); +} + START_TEST(moniker) { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); @@ -1866,6 +1946,7 @@ START_TEST(moniker) test_anti_moniker(); test_generic_composite_moniker(); test_pointer_moniker(); + test_save_load_filemoniker(); /* FIXME: test moniker creation funcs and parsing other moniker formats */ diff --git a/rostests/winetests/ole32/ole2.c b/rostests/winetests/ole32/ole2.c index 214c17e95a5..f796cd70249 100644 --- a/rostests/winetests/ole32/ole2.c +++ b/rostests/winetests/ole32/ole2.c @@ -1556,6 +1556,45 @@ static void test_runnable(void) g_showRunnable = TRUE; } +static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) +{ + *ppv = NULL; + if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface; + if (*ppv) + { + IUnknown_AddRef((IUnknown *)*ppv); + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI Unknown_AddRef(IUnknown *iface) +{ + return 2; +} + +static ULONG WINAPI Unknown_Release(IUnknown *iface) +{ + return 1; +} + +static const IUnknownVtbl UnknownVtbl = +{ + Unknown_QueryInterface, + Unknown_AddRef, + Unknown_Release +}; + +static IUnknown Unknown2 = { &UnknownVtbl }; + +static void test_OleLockRunning(void) +{ + HRESULT hr; + + hr = OleLockRunning((LPUNKNOWN)&Unknown2, TRUE, FALSE); + ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr); +} + START_TEST(ole2) { DWORD dwRegister; @@ -1587,6 +1626,7 @@ START_TEST(ole2) test_data_cache(); test_default_handler(); test_runnable(); + test_OleLockRunning(); CoUninitialize(); } diff --git a/rostests/winetests/ole32/stg_prop.c b/rostests/winetests/ole32/stg_prop.c index 82609462dc1..37e8e1031e2 100644 --- a/rostests/winetests/ole32/stg_prop.c +++ b/rostests/winetests/ole32/stg_prop.c @@ -178,6 +178,7 @@ static void testProps(void) ok(var.vt == VT_LPSTR && !lstrcmpA(U(var).pszVal, val), "Didn't get expected type or value for property (got type %d, value %s)\n", var.vt, U(var).pszVal); + PropVariantClear(&var); /* read clipboard format */ spec.ulKind = PRSPEC_PROPID; @@ -282,6 +283,7 @@ static void testProps(void) ok(var.vt == VT_LPSTR && !lstrcmpA(U(var).pszVal, val), "Didn't get expected type or value for property (got type %d, value %s)\n", var.vt, U(var).pszVal); + PropVariantClear(&var); IPropertyStorage_Release(propertyStorage); IPropertySetStorage_Release(propSetStorage); @@ -364,11 +366,13 @@ static void testCodepage(void) ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr); ok(var.vt == VT_LPSTR && !strcmp(U(var).pszVal, "hi"), "Didn't get expected type or value for property\n"); + PropVariantClear(&var); /* This seemingly non-sensical test is to show that the string is indeed * interpreted according to the current system code page, not according to * the property set's code page. (If the latter were true, the whole * string would be maintained. As it is, only the first character is.) */ + var.vt = VT_LPSTR; U(var).pszVal = (LPSTR)wval; hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0); ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr); @@ -376,6 +380,8 @@ static void testCodepage(void) ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr); ok(var.vt == VT_LPSTR && !strcmp(U(var).pszVal, "h"), "Didn't get expected type or value for property\n"); + PropVariantClear(&var); + /* now that a property's been set, you can't change the code page */ spec.ulKind = PRSPEC_PROPID; U(spec).propid = PID_CODEPAGE; diff --git a/rostests/winetests/ole32/storage32.c b/rostests/winetests/ole32/storage32.c index da2d0aa5a6e..7568a0ceafa 100644 --- a/rostests/winetests/ole32/storage32.c +++ b/rostests/winetests/ole32/storage32.c @@ -33,6 +33,28 @@ DEFINE_GUID( test_stg_cls, 0x88888888, 0x0425, 0x0000, 0,0,0,0,0,0,0,0); #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr) +static CHAR filenameA[MAX_PATH]; +static WCHAR filename[MAX_PATH]; + +static const char file1_nameA[] = {'c','o','p','y','t','e','s','t','A',0}; +static const WCHAR file1_name[] = {'c','o','p','y','t','e','s','t','A',0}; +static const char file2_nameA[] = {'c','o','p','y','t','e','s','t','B',0}; +static const WCHAR file2_name[] = {'c','o','p','y','t','e','s','t','B',0}; +static const WCHAR stgA_name[] = {'S','t','o','r','a','g','e','A',0}; +static const WCHAR stgB_name[] = {'S','t','o','r','a','g','e','B',0}; +static const WCHAR strmA_name[] = {'S','t','r','e','a','m','A',0}; +static const WCHAR strmB_name[] = {'S','t','r','e','a','m','B',0}; +static const WCHAR strmC_name[] = {'S','t','r','e','a','m','C',0}; + +/* Win9x and WinMe don't have lstrcmpW */ +static int strcmp_ww(LPCWSTR strw1, LPCWSTR strw2) +{ + CHAR stra1[512], stra2[512]; + WideCharToMultiByte(CP_ACP, 0, strw1, -1, stra1, sizeof(stra1), NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, strw2, -1, stra2, sizeof(stra2), NULL, NULL); + return lstrcmpA(stra1, stra2); +} + static void test_hglobal_storage_stat(void) { ILockBytes *ilb = NULL; @@ -67,16 +89,10 @@ static void test_hglobal_storage_stat(void) static void test_create_storage_modes(void) { - static const WCHAR szPrefix[] = { 's','t','g',0 }; - static const WCHAR szDot[] = { '.',0 }; - WCHAR filename[MAX_PATH]; IStorage *stg = NULL; HRESULT r; - if(!GetTempFileNameW(szDot, szPrefix, 0, filename)) - return; - - DeleteFileW(filename); + DeleteFileA(filenameA); /* test with some invalid parameters */ r = StgCreateDocfile( NULL, 0, 0, &stg); @@ -144,7 +160,7 @@ static void test_create_storage_modes(void) ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n"); r = StgCreateDocfile( filename, STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READ, 0, &stg); ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n"); - ok(DeleteFileW(filename), "failed to delete file\n"); + ok(DeleteFileA(filenameA), "failed to delete file\n"); r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg); ok(r==S_OK, "StgCreateDocfile failed\n"); @@ -161,13 +177,13 @@ static void test_create_storage_modes(void) ok(r==S_OK, "StgCreateDocfile failed\n"); r = IStorage_Release(stg); ok(r == 0, "storage not released\n"); - ok(DeleteFileW(filename), "failed to delete file\n"); + ok(DeleteFileA(filenameA), "failed to delete file\n"); r = StgCreateDocfile( filename, STGM_CREATE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg); ok(r==S_OK, "StgCreateDocfile failed\n"); r = IStorage_Release(stg); ok(r == 0, "storage not released\n"); - ok(DeleteFileW(filename), "failed to delete file\n"); + ok(DeleteFileA(filenameA), "failed to delete file\n"); /* test the way excel uses StgCreateDocFile */ r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg); @@ -176,7 +192,7 @@ static void test_create_storage_modes(void) { r = IStorage_Release(stg); ok(r == 0, "storage not released\n"); - ok(DeleteFileW(filename), "failed to delete file\n"); + ok(DeleteFileA(filenameA), "failed to delete file\n"); } /* and the way windows media uses it ... */ @@ -186,7 +202,7 @@ static void test_create_storage_modes(void) { r = IStorage_Release(stg); ok(r == 0, "storage not released\n"); - ok(DeleteFileW(filename), "failed to delete file\n"); + ok(DeleteFileA(filenameA), "failed to delete file\n"); } /* looks like we need STGM_TRANSACTED or STGM_CREATE */ @@ -196,7 +212,7 @@ static void test_create_storage_modes(void) { r = IStorage_Release(stg); ok(r == 0, "storage not released\n"); - ok(DeleteFileW(filename), "failed to delete file\n"); + ok(DeleteFileA(filenameA), "failed to delete file\n"); } r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_WRITE, 0, &stg); @@ -205,7 +221,7 @@ static void test_create_storage_modes(void) { r = IStorage_Release(stg); ok(r == 0, "storage not released\n"); - ok(DeleteFileW(filename), "failed to delete file\n"); + ok(DeleteFileA(filenameA), "failed to delete file\n"); } r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg); @@ -214,7 +230,7 @@ static void test_create_storage_modes(void) { r = IStorage_Release(stg); ok(r == 0, "storage not released\n"); - ok(DeleteFileW(filename), "failed to delete file\n"); + ok(DeleteFileA(filenameA), "failed to delete file\n"); } /* test the way msi uses StgCreateDocfile */ @@ -222,19 +238,16 @@ static void test_create_storage_modes(void) ok(r==S_OK, "StgCreateDocFile failed\n"); r = IStorage_Release(stg); ok(r == 0, "storage not released\n"); - ok(DeleteFileW(filename), "failed to delete file\n"); + ok(DeleteFileA(filenameA), "failed to delete file\n"); } static void test_storage_stream(void) { static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 }; - static const WCHAR szPrefix[] = { 's','t','g',0 }; - static const WCHAR szDot[] = { '.',0 }; static const WCHAR longname[] = { 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0 }; - WCHAR filename[MAX_PATH]; IStorage *stg = NULL; HRESULT r; IStream *stm = NULL; @@ -244,10 +257,7 @@ static void test_storage_stream(void) ULARGE_INTEGER p; unsigned char buffer[0x100]; - if(!GetTempFileNameW(szDot, szPrefix, 0, filename)) - return; - - DeleteFileW(filename); + DeleteFileA(filenameA); r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg); ok(r==S_OK, "StgCreateDocfile failed\n"); @@ -345,15 +355,28 @@ static void test_storage_stream(void) r = IStorage_Release(stg); ok(r == 0, "wrong ref count\n"); - r = DeleteFileW(filename); + + /* try create some invalid streams */ + stg = NULL; + stm = NULL; + r = StgOpenStorage(filename, NULL, STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &stg); + ok(r == S_OK, "should succeed\n"); + if (stg) + { + r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm); + ok(r == STG_E_INVALIDFLAG, "IStorage->OpenStream should return STG_E_INVALIDFLAG instead of 0x%08x\n", r); + IStorage_Release(stg); + } + + r = DeleteFileA(filenameA); ok(r, "file should exist\n"); } -static BOOL touch_file(LPCWSTR filename) +static BOOL touch_file(LPCSTR filename) { HANDLE file; - file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, + file = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file==INVALID_HANDLE_VALUE) return FALSE; @@ -361,12 +384,12 @@ static BOOL touch_file(LPCWSTR filename) return TRUE; } -static BOOL is_zero_length(LPCWSTR filename) +static BOOL is_zero_length(LPCSTR filename) { HANDLE file; DWORD len; - file = CreateFileW(filename, GENERIC_READ, 0, NULL, + file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (file==INVALID_HANDLE_VALUE) return FALSE; @@ -375,11 +398,11 @@ static BOOL is_zero_length(LPCWSTR filename) return len == 0; } -static BOOL is_existing_file(LPCWSTR filename) +static BOOL is_existing_file(LPCSTR filename) { HANDLE file; - file = CreateFileW(filename, GENERIC_READ, 0, NULL, + file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (file==INVALID_HANDLE_VALUE) return FALSE; @@ -389,20 +412,14 @@ static BOOL is_existing_file(LPCWSTR filename) static void test_open_storage(void) { - static const WCHAR szPrefix[] = { 's','t','g',0 }; static const WCHAR szNonExist[] = { 'n','o','n','e','x','i','s','t',0 }; - static const WCHAR szDot[] = { '.',0 }; - WCHAR filename[MAX_PATH]; IStorage *stg = NULL, *stg2 = NULL; HRESULT r; DWORD stgm; - if(!GetTempFileNameW(szDot, szPrefix, 0, filename)) - return; - /* try opening a zero length file - it should stay zero length */ - DeleteFileW(filename); - touch_file(filename); + DeleteFileA(filenameA); + touch_file(filenameA); stgm = STGM_NOSCRATCH | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE; r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg); ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n"); @@ -410,17 +427,17 @@ static void test_open_storage(void) stgm = STGM_SHARE_EXCLUSIVE | STGM_READWRITE; r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg); ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n"); - ok(is_zero_length(filename), "file length changed\n"); + ok(is_zero_length(filenameA), "file length changed\n"); - DeleteFileW(filename); + DeleteFileA(filenameA); /* try opening a nonexistent file - it should not create it */ stgm = STGM_DIRECT | STGM_SHARE_EXCLUSIVE | STGM_READWRITE; r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg); ok(r!=S_OK, "StgOpenStorage failed: 0x%08x\n", r); if (r==S_OK) IStorage_Release(stg); - ok(!is_existing_file(filename), "StgOpenStorage should not create a file\n"); - DeleteFileW(filename); + ok(!is_existing_file(filenameA), "StgOpenStorage should not create a file\n"); + DeleteFileA(filenameA); /* create the file */ r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg); @@ -558,24 +575,18 @@ static void test_open_storage(void) r = StgOpenStorage( filename, NULL, STGM_NOSNAPSHOT | STGM_PRIORITY, NULL, 0, &stg); ok(r == STG_E_INVALIDFLAG, "should fail\n"); - r = DeleteFileW(filename); + r = DeleteFileA(filenameA); ok(r, "file didn't exist\n"); } static void test_storage_suminfo(void) { - static const WCHAR szDot[] = { '.',0 }; - static const WCHAR szPrefix[] = { 's','t','g',0 }; - WCHAR filename[MAX_PATH]; IStorage *stg = NULL; IPropertySetStorage *propset = NULL; IPropertyStorage *ps = NULL; HRESULT r; - if(!GetTempFileNameW(szDot, szPrefix, 0, filename)) - return; - - DeleteFileW(filename); + DeleteFileA(filenameA); /* create the file */ r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | @@ -673,14 +684,11 @@ static void test_storage_suminfo(void) r = IStorage_Release(stg); ok(r == 0, "ref count wrong\n"); - DeleteFileW(filename); + DeleteFileA(filenameA); } static void test_storage_refcount(void) { - static const WCHAR szPrefix[] = { 's','t','g',0 }; - static const WCHAR szDot[] = { '.',0 }; - WCHAR filename[MAX_PATH]; IStorage *stg = NULL; IStorage *stgprio = NULL; HRESULT r; @@ -691,10 +699,7 @@ static void test_storage_refcount(void) STATSTG stat; char buffer[10]; - if(!GetTempFileNameW(szDot, szPrefix, 0, filename)) - return; - - DeleteFileW(filename); + DeleteFileA(filenameA); /* create the file */ r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | @@ -774,7 +779,7 @@ static void test_storage_refcount(void) r = IStorage_Stat( stg2, &statstg, STATFLAG_DEFAULT ); ok(r == S_OK, "Stat should have succeded instead of returning 0x%08x\n", r); - ok(!lstrcmpW(statstg.pwcsName, stgname), + ok(!memcmp(statstg.pwcsName, stgname, sizeof(stgname)), "Statstg pwcsName should have been the name the storage was created with\n"); ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type); ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart); @@ -800,22 +805,16 @@ static void test_storage_refcount(void) } IStorage_Release(stgprio); - DeleteFileW(filename); + DeleteFileA(filenameA); } static void test_writeclassstg(void) { - static const WCHAR szPrefix[] = { 's','t','g',0 }; - static const WCHAR szDot[] = { '.',0 }; - WCHAR filename[MAX_PATH]; IStorage *stg = NULL; HRESULT r; CLSID temp_cls; - if(!GetTempFileNameW(szDot, szPrefix, 0, filename)) - return; - - DeleteFileW(filename); + DeleteFileA(filenameA); /* create the file */ r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | @@ -850,26 +849,22 @@ static void test_writeclassstg(void) r = IStorage_Release( stg ); ok (r == 0, "storage not released\n"); - DeleteFileW(filename); + DeleteFileA(filenameA); } static void test_streamenum(void) { - static const WCHAR szPrefix[] = { 's','t','g',0 }; - static const WCHAR szDot[] = { '.',0 }; - WCHAR filename[MAX_PATH]; IStorage *stg = NULL; HRESULT r; IStream *stm = NULL; static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 }; + static const WCHAR stmname2[] = { 'A','B','C','D','E','F','G','H','I',0 }; + static const WCHAR stmname3[] = { 'A','B','C','D','E','F','G','H','I','J',0 }; STATSTG stat; IEnumSTATSTG *ee = NULL; ULONG count; - if(!GetTempFileNameW(szDot, szPrefix, 0, filename)) - return; - - DeleteFileW(filename); + DeleteFileA(filenameA); /* create the file */ r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | @@ -897,6 +892,9 @@ static void test_streamenum(void) ok(r==S_OK, "IEnumSTATSTG->Next failed\n"); ok(count == 1, "count wrong\n"); + if (r == S_OK) + CoTaskMemFree(stat.pwcsName); + r = IEnumSTATSTG_Release(ee); /* second enum... destroy the stream before reading */ @@ -904,14 +902,12 @@ static void test_streamenum(void) ok(r==S_OK, "IStorage->EnumElements failed\n"); r = IStorage_DestroyElement(stg, stmname); - ok(r==S_OK, "IStorage->EnumElements failed\n"); + ok(r==S_OK, "IStorage->DestroyElement failed\n"); - todo_wine { count = 0xf00; r = IEnumSTATSTG_Next(ee, 1, &stat, &count); ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n"); ok(count == 0, "count wrong\n"); - } /* reset and try again */ r = IEnumSTATSTG_Reset(ee); @@ -922,49 +918,161 @@ static void test_streamenum(void) ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n"); ok(count == 0, "count wrong\n"); + /* add a stream before reading */ + r = IEnumSTATSTG_Reset(ee); + ok(r==S_OK, "IEnumSTATSTG->Reset failed\n"); + + r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm ); + ok(r==S_OK, "IStorage->CreateStream failed\n"); + + r = IStream_Release(stm); + + count = 0xf00; + r = IEnumSTATSTG_Next(ee, 1, &stat, &count); + ok(r==S_OK, "IEnumSTATSTG->Next failed\n"); + ok(count == 1, "count wrong\n"); + + if (r == S_OK) + { + ok(lstrcmpiW(stat.pwcsName, stmname) == 0, "expected CONTENTS, got %s\n", wine_dbgstr_w(stat.pwcsName)); + CoTaskMemFree(stat.pwcsName); + } + + r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm ); + ok(r==S_OK, "IStorage->CreateStream failed\n"); + + r = IStream_Release(stm); + + count = 0xf00; + r = IEnumSTATSTG_Next(ee, 1, &stat, &count); + ok(r==S_OK, "IEnumSTATSTG->Next failed\n"); + ok(count == 1, "count wrong\n"); + + if (r == S_OK) + { + ok(lstrcmpiW(stat.pwcsName, stmname2) == 0, "expected ABCDEFGHI, got %s\n", wine_dbgstr_w(stat.pwcsName)); + CoTaskMemFree(stat.pwcsName); + } + + /* delete previous and next stream after reading */ + r = IStorage_CreateStream(stg, stmname3, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm ); + ok(r==S_OK, "IStorage->CreateStream failed\n"); + + r = IStream_Release(stm); + + r = IEnumSTATSTG_Reset(ee); + ok(r==S_OK, "IEnumSTATSTG->Reset failed\n"); + + count = 0xf00; + r = IEnumSTATSTG_Next(ee, 1, &stat, &count); + ok(r==S_OK, "IEnumSTATSTG->Next failed\n"); + ok(count == 1, "count wrong\n"); + + if (r == S_OK) + { + ok(lstrcmpiW(stat.pwcsName, stmname) == 0, "expected CONTENTS, got %s\n", wine_dbgstr_w(stat.pwcsName)); + CoTaskMemFree(stat.pwcsName); + } + + r = IStorage_DestroyElement(stg, stmname); + ok(r==S_OK, "IStorage->DestroyElement failed\n"); + + r = IStorage_DestroyElement(stg, stmname2); + ok(r==S_OK, "IStorage->DestroyElement failed\n"); + + count = 0xf00; + r = IEnumSTATSTG_Next(ee, 1, &stat, &count); + ok(r==S_OK, "IEnumSTATSTG->Next failed\n"); + ok(count == 1, "count wrong\n"); + + if (r == S_OK) + { + ok(lstrcmpiW(stat.pwcsName, stmname3) == 0, "expected ABCDEFGHIJ, got %s\n", wine_dbgstr_w(stat.pwcsName)); + CoTaskMemFree(stat.pwcsName); + } + + r = IStorage_Release( stg ); + todo_wine ok (r == 0, "storage not released\n"); + + /* enumerator is still valid and working after the storage is released */ + r = IEnumSTATSTG_Reset(ee); + ok(r==S_OK, "IEnumSTATSTG->Reset failed\n"); + + count = 0xf00; + r = IEnumSTATSTG_Next(ee, 1, &stat, &count); + ok(r==S_OK, "IEnumSTATSTG->Next failed\n"); + ok(count == 1, "count wrong\n"); + + if (r == S_OK) + { + ok(lstrcmpiW(stat.pwcsName, stmname3) == 0, "expected ABCDEFGHIJ, got %s\n", wine_dbgstr_w(stat.pwcsName)); + CoTaskMemFree(stat.pwcsName); + } + + /* the storage is left open until the enumerator is freed */ + r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | + STGM_READWRITE |STGM_TRANSACTED, NULL, 0, &stg); + ok(r==STG_E_SHAREVIOLATION || + r==STG_E_LOCKVIOLATION, /* XP-SP2/W2K3-SP1 and below */ + "StgCreateDocfile failed, res=%x\n", r); + r = IEnumSTATSTG_Release(ee); ok (r == 0, "enum not released\n"); - r = IStorage_Release( stg ); - ok (r == 0, "storage not released\n"); - - DeleteFileW(filename); + DeleteFileA(filenameA); } static void test_transact(void) { - static const WCHAR szPrefix[] = { 's','t','g',0 }; - static const WCHAR szDot[] = { '.',0 }; - WCHAR filename[MAX_PATH]; - IStorage *stg = NULL, *stg2 = NULL; + IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL; HRESULT r; IStream *stm = NULL; static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 }; static const WCHAR stmname2[] = { 'F','O','O',0 }; + static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 }; + static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 }; - if(!GetTempFileNameW(szDot, szPrefix, 0, filename)) - return; - - DeleteFileW(filename); + DeleteFileA(filenameA); /* create the file */ r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg); ok(r==S_OK, "StgCreateDocfile failed\n"); - /* now create a stream, but don't commit it */ + /* commit a new stream and storage */ r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm ); ok(r==S_OK, "IStorage->CreateStream failed\n"); r = IStream_Write(stm, "this is stream 1\n", 16, NULL); ok(r==S_OK, "IStream->Write failed\n"); - r = IStream_Release(stm); + IStream_Release(stm); - r = IStorage_Commit(stg, 0); - ok(r==S_OK, "IStorage->Commit failed\n"); + r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); - /* now create a stream, but don't commit it */ + if (r == S_OK) + { + /* Create two substorages but only commit one */ + r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + if (r == S_OK) + IStorage_Release(stg3); + + r = IStorage_Commit(stg, 0); + ok(r==S_OK, "IStorage->Commit failed\n"); + + r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + if (r == S_OK) + IStorage_Release(stg3); + + IStorage_Release(stg2); + } + + /* now create a stream and storage, but don't commit them */ stm = NULL; r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm ); ok(r==S_OK, "IStorage->CreateStream failed\n"); @@ -972,10 +1080,17 @@ static void test_transact(void) r = IStream_Write(stm, "this is stream 2\n", 16, NULL); ok(r==S_OK, "IStream->Write failed\n"); + /* IStream::Commit does nothing for OLE storage streams */ r = IStream_Commit(stm, STGC_ONLYIFCURRENT | STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE); ok(r==S_OK, "IStream->Commit failed\n"); - r = IStream_Release(stm); + r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + if (r == S_OK) + IStorage_Release(stg2); + + IStream_Release(stm); IStorage_Release(stg); @@ -999,24 +1114,467 @@ static void test_transact(void) r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 ); ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r); - todo_wine { r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r); - } - if (stm) - r = IStream_Release(stm); + if (r == S_OK) + IStream_Release(stm); + + r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 ); + ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r); + if (r == S_OK) + IStorage_Release(stg2); r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 ); ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r); r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); - ok(r==S_OK, "IStorage->OpenStream should fail %08x\n", r); - if (stm) - r = IStream_Release(stm); + ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r); + if (r == S_OK) + IStream_Release(stm); + + r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 ); + ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r); + if (r == S_OK) + { + r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 ); + ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r); + if (r == S_OK) + IStorage_Release(stg3); + + r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 ); + ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r); + if (r == S_OK) + IStorage_Release(stg3); + + IStorage_Release(stg2); + } IStorage_Release(stg); - r = DeleteFileW(filename); + r = DeleteFileA(filenameA); + ok( r == TRUE, "deleted file\n"); +} + +static void test_substorage_share(void) +{ + IStorage *stg, *stg2, *stg3; + IStream *stm, *stm2; + HRESULT r; + static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 }; + static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 }; + static const WCHAR othername[] = { 'N','E','W','N','A','M','E',0 }; + + DeleteFileA(filenameA); + + /* create the file */ + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + /* create a read/write storage and try to open it again */ + r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + if (r == S_OK) + { + r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3); + ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r); + + if (r == S_OK) + IStorage_Release(stg3); + + r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3); + ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r); + + if (r == S_OK) + IStorage_Release(stg3); + + /* cannot rename the storage while it's open */ + r = IStorage_RenameElement(stg, stgname, othername); + ok(r==STG_E_ACCESSDENIED, "IStorage->RenameElement should fail %08x\n", r); + if (SUCCEEDED(r)) IStorage_RenameElement(stg, othername, stgname); + + /* destroying an object while it's open invalidates it */ + r = IStorage_DestroyElement(stg, stgname); + ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r); + + r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm); + ok(r==STG_E_REVERTED, "IStorage->CreateStream failed, hr=%08x\n", r); + + if (r == S_OK) + IStorage_Release(stm); + + IStorage_Release(stg2); + } + + /* create a read/write stream and try to open it again */ + r = IStorage_CreateStream(stg, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm); + ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r); + + if (r == S_OK) + { + r = IStorage_OpenStream(stg, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm2); + ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r); + + if (r == S_OK) + IStorage_Release(stm2); + + r = IStorage_OpenStream(stg, stmname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm2); + ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r); + + if (r == S_OK) + IStorage_Release(stm2); + + /* cannot rename the stream while it's open */ + r = IStorage_RenameElement(stg, stmname, othername); + ok(r==STG_E_ACCESSDENIED, "IStorage->RenameElement should fail %08x\n", r); + if (SUCCEEDED(r)) IStorage_RenameElement(stg, othername, stmname); + + /* destroying an object while it's open invalidates it */ + r = IStorage_DestroyElement(stg, stmname); + ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r); + + r = IStream_Write(stm, "this shouldn't work\n", 20, NULL); + ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r); + + IStorage_Release(stm); + } + + IStorage_Release(stg); + + r = DeleteFileA(filenameA); + ok( r == TRUE, "deleted file\n"); +} + +static void test_revert(void) +{ + IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL; + HRESULT r; + IStream *stm = NULL, *stm2 = NULL; + static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 }; + static const WCHAR stmname2[] = { 'F','O','O',0 }; + static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 }; + static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 }; + STATSTG statstg; + + DeleteFileA(filenameA); + + /* create the file */ + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE |STGM_TRANSACTED, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + /* commit a new stream and storage */ + r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm ); + ok(r==S_OK, "IStorage->CreateStream failed\n"); + + r = IStream_Write(stm, "this is stream 1\n", 16, NULL); + ok(r==S_OK, "IStream->Write failed\n"); + + r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + if (r == S_OK) + { + /* Create two substorages but only commit one */ + r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + if (r == S_OK) + IStorage_Release(stg3); + + r = IStorage_Commit(stg, 0); + ok(r==S_OK, "IStorage->Commit failed\n"); + + r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + if (r == S_OK) + IStorage_Release(stg3); + } + + /* now create a stream and storage, then revert */ + r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm2 ); + ok(r==S_OK, "IStorage->CreateStream failed\n"); + + r = IStream_Write(stm2, "this is stream 2\n", 16, NULL); + ok(r==S_OK, "IStream->Write failed\n"); + + r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + r = IStorage_Revert(stg); + + /* all open objects become invalid */ + r = IStream_Write(stm, "this shouldn't work\n", 20, NULL); + ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r); + + r = IStream_Write(stm2, "this shouldn't work\n", 20, NULL); + ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r); + + r = IStorage_Stat(stg2, &statstg, STATFLAG_NONAME); + ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r); + + r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME); + ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r); + + IStream_Release(stm); + IStream_Release(stm2); + IStorage_Release(stg2); + IStorage_Release(stg3); + + r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm ); + ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r); + + r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); + ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r); + + r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); + ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r); + + r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 ); + ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r); + + r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); + ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r); + if (r == S_OK) + IStream_Release(stm); + + r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 ); + ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r); + if (r == S_OK) + IStorage_Release(stg2); + + r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 ); + ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r); + + r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); + ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r); + if (r == S_OK) + IStream_Release(stm); + + r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 ); + ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r); + if (r == S_OK) + { + r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 ); + ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r); + if (r == S_OK) + IStorage_Release(stg3); + + r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 ); + ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r); + if (r == S_OK) + IStorage_Release(stg3); + + IStorage_Release(stg2); + } + + IStorage_Release(stg); + + r = DeleteFileA(filenameA); + ok( r == TRUE, "deleted file\n"); + + /* Revert only invalidates objects in transacted mode */ + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm ); + ok(r==S_OK, "IStorage->CreateStream failed\n"); + + r = IStorage_Revert(stg); + ok(r==S_OK, "IStorage->Revert failed %08x\n", r); + + r = IStream_Write(stm, "this works\n", 11, NULL); + ok(r==S_OK, "IStream_Write should succeed %08x\n", r); + + IStream_Release(stm); + IStream_Release(stg); + + r = DeleteFileA(filenameA); + ok( r == TRUE, "deleted file\n"); +} + +static void test_parent_free(void) +{ + IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL; + HRESULT r; + IStream *stm = NULL; + static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 }; + static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 }; + ULONG ref; + STATSTG statstg; + + DeleteFileA(filenameA); + + /* create the file */ + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE |STGM_TRANSACTED, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + /* create a new storage */ + r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + if (r == S_OK) + { + /* now create a stream inside the new storage */ + r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm ); + ok(r==S_OK, "IStorage->CreateStream failed\n"); + + if (r == S_OK) + { + /* create a storage inside the new storage */ + r = IStorage_CreateStorage(stg2, stgname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg3 ); + ok(r==S_OK, "IStorage->CreateStorage failed\n"); + } + + /* free the parent */ + ref = IStorage_Release(stg2); + ok(ref == 0, "IStorage still has %u references\n", ref); + + /* child objects are invalid */ + if (r == S_OK) + { + r = IStream_Write(stm, "this should fail\n", 17, NULL); + ok(r==STG_E_REVERTED, "IStream->Write sould fail, hr=%x\n", r); + + IStream_Release(stm); + + r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME); + ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r); + + r = IStorage_SetStateBits(stg3, 1, 1); + ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r); + + IStorage_Release(stg3); + } + } + + IStorage_Release(stg); + + r = DeleteFileA(filenameA); + ok( r == TRUE, "deleted file\n"); +} + +static void test_nonroot_transacted(void) +{ + IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL; + HRESULT r; + IStream *stm = NULL; + static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 }; + static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 }; + static const WCHAR stmname2[] = { 'F','O','O',0 }; + + DeleteFileA(filenameA); + + /* create a transacted file */ + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE |STGM_TRANSACTED, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + /* create a transacted substorage */ + r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + if (r == S_OK) + { + /* create and commit stmname */ + r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm ); + ok(r==S_OK, "IStorage->CreateStream failed\n"); + if (r == S_OK) + IStream_Release(stm); + + IStorage_Commit(stg2, 0); + + /* create and revert stmname2 */ + r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm ); + ok(r==S_OK, "IStorage->CreateStream failed\n"); + if (r == S_OK) + IStream_Release(stm); + + IStorage_Revert(stg2); + + /* check that Commit and Revert really worked */ + r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); + ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r); + if (r == S_OK) + IStream_Release(stm); + + r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); + ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r); + if (r == S_OK) + IStream_Release(stm); + + IStorage_Release(stg2); + } + + /* create a read-only transacted substorage */ + r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, NULL, 0, &stg2); + ok(r==S_OK, "IStorage->OpenStorage failed, hr=%08x\n", r); + + if (r == S_OK) + { + /* The storage can be modified. */ + r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + if (r == S_OK) + IStream_Release(stg3); + + /* But changes cannot be committed. */ + r = IStorage_Commit(stg2, 0); + ok(r==STG_E_ACCESSDENIED, "IStorage->Commit should fail, hr=%08x\n", r); + + IStorage_Release(stg2); + } + + IStorage_Release(stg); + + /* create a non-transacted file */ + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + /* create a transacted substorage */ + r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + if (r == S_OK) + { + /* create and commit stmname */ + r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm ); + ok(r==S_OK, "IStorage->CreateStream failed\n"); + if (r == S_OK) + IStream_Release(stm); + + IStorage_Commit(stg2, 0); + + /* create and revert stmname2 */ + r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm ); + ok(r==S_OK, "IStorage->CreateStream failed\n"); + if (r == S_OK) + IStream_Release(stm); + + IStorage_Revert(stg2); + + /* check that Commit and Revert really worked */ + r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); + ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r); + if (r == S_OK) + IStream_Release(stm); + + r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); + ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r); + if (r == S_OK) + IStream_Release(stm); + + IStorage_Release(stg2); + } + + IStream_Release(stg); + + r = DeleteFileA(filenameA); ok( r == TRUE, "deleted file\n"); } @@ -1048,6 +1606,8 @@ static void test_ReadClassStm(void) hr = ReadClassStm(pStream, &clsid); ok_ole_success(hr, "ReadClassStm"); ok(IsEqualCLSID(&clsid, &test_stg_cls), "clsid should have been set to CLSID_WineTest\n"); + + IStream_Release(pStream); } struct access_res @@ -1267,8 +1827,1014 @@ static void test_access(void) DeleteFileA("winetest"); } +static void test_readonly(void) +{ + IStorage *stg, *stg2, *stg3; + IStream *stream; + HRESULT hr; + static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0}; + static const WCHAR storageW[] = {'s','t','o','r','a','g','e',0}; + static const WCHAR streamW[] = {'s','t','r','e','a','m',0}; + + hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg); + ok(hr == S_OK, "should succeed, res=%x\n", hr); + if (SUCCEEDED(hr)) + { + hr = IStorage_CreateStorage( stg, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2 ); + ok(hr == S_OK, "should succeed, res=%x\n", hr); + if (SUCCEEDED(hr)) + { + hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stream ); + ok(hr == S_OK, "should succeed, res=%x\n", hr); + if (SUCCEEDED(hr)) + IStream_Release(stream); + IStorage_Release(stg2); + } + IStorage_Release(stg); + } + + /* re-open read only */ + hr = StgOpenStorage( fileW, NULL, STGM_TRANSACTED | STGM_SHARE_DENY_NONE | STGM_READ, NULL, 0, &stg); + ok(hr == S_OK, "should succeed, res=%x\n", hr); + if (SUCCEEDED(hr)) + { + hr = IStorage_OpenStorage( stg, storageW, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2 ); + ok(hr == S_OK, "should succeed, res=%x\n", hr); + if (SUCCEEDED(hr)) + { + /* CreateStream on read-only storage, name exists */ + hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream ); + ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr); + if (SUCCEEDED(hr)) + IStream_Release(stream); + + /* CreateStream on read-only storage, name does not exist */ + hr = IStorage_CreateStream( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream ); + ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr); + if (SUCCEEDED(hr)) + IStream_Release(stream); + + /* CreateStorage on read-only storage, name exists */ + hr = IStorage_CreateStorage( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 ); + ok(hr == STG_E_FILEALREADYEXISTS, "should fail, res=%x\n", hr); + if (SUCCEEDED(hr)) + IStream_Release(stg3); + + /* CreateStorage on read-only storage, name does not exist */ + hr = IStorage_CreateStorage( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 ); + ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr); + if (SUCCEEDED(hr)) + IStream_Release(stg3); + + /* DestroyElement on read-only storage, name exists */ + hr = IStorage_DestroyElement( stg2, streamW ); + ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr); + + /* DestroyElement on read-only storage, name does not exist */ + hr = IStorage_DestroyElement( stg2, storageW ); + ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr); + + IStorage_Release(stg2); + } + + IStorage_Release(stg); + } + + DeleteFileA("winetest"); +} + +static void test_simple(void) +{ + /* Tests for STGM_SIMPLE mode */ + + IStorage *stg, *stg2; + HRESULT r; + IStream *stm; + static const WCHAR stgname[] = { 'S','t','g',0 }; + static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 }; + static const WCHAR stmname2[] = { 'S','m','a','l','l',0 }; + LARGE_INTEGER pos; + ULARGE_INTEGER upos; + DWORD count; + STATSTG stat; + + DeleteFileA(filenameA); + + r = StgCreateDocfile( filename, STGM_SIMPLE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg); + ok(r == S_OK, "got %08x\n", r); + + r = IStorage_CreateStorage(stg, stgname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2); + ok(r == STG_E_INVALIDFUNCTION, "got %08x\n", r); + if (SUCCEEDED(r)) IStorage_Release(stg2); + + r = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm); + ok(r == STG_E_INVALIDFLAG, "got %08x\n", r); + r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm); + ok(r == S_OK, "got %08x\n", r); + + upos.QuadPart = 6000; + r = IStream_SetSize(stm, upos); + ok(r == S_OK, "got %08x\n", r); + + r = IStream_Write(stm, "foo", 3, &count); + ok(r == S_OK, "got %08x\n", r); + ok(count == 3, "got %d\n", count); + + pos.QuadPart = 0; + r = IStream_Seek(stm, pos, STREAM_SEEK_CUR, &upos); + ok(r == S_OK, "got %08x\n", r); + ok(upos.QuadPart == 3, "got %d\n", upos.u.LowPart); + + r = IStream_Stat(stm, &stat, STATFLAG_NONAME); + ok(r == S_OK || + broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */ + "got %08x\n", r); + if (r == S_OK) + ok(stat.cbSize.QuadPart == 3, "got %d\n", stat.cbSize.u.LowPart); + + pos.QuadPart = 1; + r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &upos); + ok(r == S_OK, "got %08x\n", r); + ok(upos.QuadPart == 1, "got %d\n", upos.u.LowPart); + + r = IStream_Stat(stm, &stat, STATFLAG_NONAME); + ok(r == S_OK || + broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */ + "got %08x\n", r); + if (r == S_OK) + ok(stat.cbSize.QuadPart == 1, "got %d\n", stat.cbSize.u.LowPart); + + IStream_Release(stm); + + r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm); + ok(r == S_OK, "got %08x\n", r); + + upos.QuadPart = 100; + r = IStream_SetSize(stm, upos); + ok(r == S_OK, "got %08x\n", r); + + r = IStream_Write(stm, "foo", 3, &count); + ok(r == S_OK, "got %08x\n", r); + ok(count == 3, "got %d\n", count); + + IStream_Release(stm); + + IStorage_Commit(stg, STGC_DEFAULT); + IStorage_Release(stg); + + r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg); + if (r == STG_E_INVALIDFLAG) + { + win_skip("Flag combination is not supported on NT4 and below\n"); + DeleteFileA(filenameA); + return; + } + ok(r == S_OK, "got %08x\n", r); + + r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg2); + ok(r == STG_E_INVALIDFUNCTION, "got %08x\n", r); + if (SUCCEEDED(r)) IStorage_Release(stg2); + + r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm); + ok(r == S_OK, "got %08x\n", r); + + r = IStream_Stat(stm, &stat, STATFLAG_NONAME); + ok(r == S_OK, "got %08x\n", r); + ok(stat.cbSize.QuadPart == 6000, "got %d\n", stat.cbSize.u.LowPart); + + IStream_Release(stm); + + r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm); + ok(r == S_OK, "got %08x\n", r); + + r = IStream_Stat(stm, &stat, STATFLAG_NONAME); + ok(r == S_OK, "got %08x\n", r); + ok(stat.cbSize.QuadPart == 4096, "got %d\n", stat.cbSize.u.LowPart); + + IStream_Release(stm); + + + IStorage_Release(stg); + + DeleteFileA(filenameA); +} + +static void test_fmtusertypestg(void) +{ + IStorage *stg; + IEnumSTATSTG *stat; + HRESULT hr; + static const char fileA[] = {'f','m','t','t','e','s','t',0}; + static const WCHAR fileW[] = {'f','m','t','t','e','s','t',0}; + static WCHAR userTypeW[] = {'S','t','g','U','s','r','T','y','p','e',0}; + static WCHAR strmNameW[] = {1,'C','o','m','p','O','b','j',0}; + + hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg); + ok(hr == S_OK, "should succeed, res=%x\n", hr); + + if (SUCCEEDED(hr)) + { + /* try to write the stream */ + hr = WriteFmtUserTypeStg(stg, 0, userTypeW); + ok(hr == S_OK, "should succeed, res=%x\n", hr); + + /* check that the stream was created */ + hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat); + ok(hr == S_OK, "should succeed, res=%x\n", hr); + if (SUCCEEDED(hr)) + { + BOOL found = FALSE; + STATSTG statstg; + DWORD got; + while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1) + { + if (strcmp_ww(statstg.pwcsName, strmNameW) == 0) + found = TRUE; + else + ok(0, "found unexpected stream or storage\n"); + CoTaskMemFree(statstg.pwcsName); + } + ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n"); + IEnumSTATSTG_Release(stat); + } + + /* re-write the stream */ + hr = WriteFmtUserTypeStg(stg, 0, userTypeW); + ok(hr == S_OK, "should succeed, res=%x\n", hr); + + /* check that the stream is still there */ + hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat); + ok(hr == S_OK, "should succeed, res=%x\n", hr); + if (SUCCEEDED(hr)) + { + BOOL found = FALSE; + STATSTG statstg; + DWORD got; + while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1) + { + if (strcmp_ww(statstg.pwcsName, strmNameW) == 0) + found = TRUE; + else + ok(0, "found unexpected stream or storage\n"); + CoTaskMemFree(statstg.pwcsName); + } + ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n"); + IEnumSTATSTG_Release(stat); + } + + IStorage_Release(stg); + DeleteFileA( fileA ); + } +} + +static void test_references(void) +{ + IStorage *stg,*stg2; + HRESULT hr; + unsigned c1,c2; + static const WCHAR StorName[] = { 'D','a','t','a','S','p','a','c','e','I','n','f','o',0 }; + + DeleteFileA(filenameA); + + hr = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg); + ok(hr==S_OK, "StgCreateDocfile failed\n"); + + if (SUCCEEDED(hr)) + { + IStorage_Release(stg); + + hr = StgOpenStorage( filename, NULL, STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg); + ok(hr==S_OK, "StgOpenStorage failed (result=%x)\n",hr); + + if (SUCCEEDED(hr)) + { + hr = IStorage_CreateStorage(stg,StorName,STGM_READWRITE | STGM_SHARE_EXCLUSIVE,0,0,&stg2); + ok(hr == S_OK, "IStorage_CreateStorage failed (result=%x)\n",hr); + + if (SUCCEEDED(hr)) + { + c1 = IStorage_AddRef(stg); + ok(c1 == 2, "creating internal storage added references to ancestor\n"); + c1 = IStorage_AddRef(stg); + IStorage_Release(stg2); + c2 = IStorage_AddRef(stg) - 1; + ok(c1 == c2, "releasing internal storage removed references to ancestor\n"); + } + c1 = IStorage_Release(stg); + while ( c1 ) c1 = IStorage_Release(stg); + } + } + + DeleteFileA(filenameA); +} + +/* dest + * |-StorageA + * | `StreamA: "StreamA" + * |-StorageB + * | `StreamB: "StreamB" + * `StreamC: "StreamC" + */ +static HRESULT create_test_file(IStorage *dest) +{ + IStorage *stgA = NULL, *stgB = NULL; + IStream *strmA = NULL, *strmB = NULL, *strmC = NULL; + const ULONG strmA_name_size = lstrlenW(strmA_name) * sizeof(WCHAR); + const ULONG strmB_name_size = lstrlenW(strmB_name) * sizeof(WCHAR); + const ULONG strmC_name_size = lstrlenW(strmC_name) * sizeof(WCHAR); + ULONG bytes; + HRESULT hr; + + hr = IStorage_CreateStorage(dest, stgA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgA); + ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + hr = IStorage_CreateStream(stgA, strmA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmA); + ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + hr = IStream_Write(strmA, strmA_name, strmA_name_size, &bytes); + ok(hr == S_OK && bytes == strmA_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmA_name_size); + + hr = IStorage_CreateStorage(dest, stgB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgB); + ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + hr = IStorage_CreateStream(stgB, strmB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmB); + ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + hr = IStream_Write(strmB, strmB_name, strmB_name_size, &bytes); + ok(hr == S_OK && bytes == strmB_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmB_name_size); + + hr = IStorage_CreateStream(dest, strmC_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmC); + ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + hr = IStream_Write(strmC, strmC_name, strmC_name_size, &bytes); + ok(hr == S_OK && bytes == strmC_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmC_name_size); + +cleanup: + if(strmC) + IStream_Release(strmC); + if(strmB) + IStream_Release(strmB); + if(stgB) + IStorage_Release(stgB); + if(strmA) + IStream_Release(strmA); + if(stgA) + IStorage_Release(stgA); + + return hr; +} + +static void test_copyto(void) +{ + IStorage *file1 = NULL, *file2 = NULL, *stg_tmp; + IStream *strm_tmp; + WCHAR buf[64]; + HRESULT hr; + + /* create & populate file1 */ + hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1); + ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + hr = create_test_file(file1); + if(FAILED(hr)) + goto cleanup; + + /* create file2 */ + hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2); + ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + /* copy file1 into file2 */ + hr = IStorage_CopyTo(file1, 0, NULL, NULL, NULL); + ok(hr == STG_E_INVALIDPOINTER, "CopyTo should give STG_E_INVALIDPONITER, gave: 0x%08x\n", hr); + + hr = IStorage_CopyTo(file1, 0, NULL, NULL, file2); + ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + /* verify that all of file1 was copied */ + hr = IStorage_OpenStorage(file2, stgA_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp); + ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr); + + if(SUCCEEDED(hr)){ + hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp); + ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr); + + if(SUCCEEDED(hr)){ + memset(buf, 0, sizeof(buf)); + hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL); + ok(hr == S_OK, "Read failed: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + ok(strcmp_ww(buf, strmA_name) == 0, + "Expected %s to be read, got %s\n", wine_dbgstr_w(strmA_name), wine_dbgstr_w(buf)); + + IStream_Release(strm_tmp); + } + + IStorage_Release(stg_tmp); + } + + hr = IStorage_OpenStorage(file2, stgB_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp); + ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr); + + if(SUCCEEDED(hr)){ + hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp); + ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr); + + if(SUCCEEDED(hr)){ + memset(buf, 0, sizeof(buf)); + hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL); + ok(hr == S_OK, "Read failed: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + ok(strcmp_ww(buf, strmB_name) == 0, + "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf)); + + IStream_Release(strm_tmp); + } + + IStorage_Release(stg_tmp); + } + + hr = IStorage_OpenStream(file2, strmC_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp); + ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr); + + if(SUCCEEDED(hr)){ + memset(buf, 0, sizeof(buf)); + hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL); + ok(hr == S_OK, "Read failed: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + ok(strcmp_ww(buf, strmC_name) == 0, + "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf)); + + IStream_Release(strm_tmp); + } + +cleanup: + if(file1) + IStorage_Release(file1); + if(file2) + IStorage_Release(file2); + + DeleteFileA(file1_nameA); + DeleteFileA(file2_nameA); +} + +static void test_copyto_snbexclusions(void) +{ + static const WCHAR *snb_exclude[] = {stgA_name, strmB_name, strmC_name, 0}; + + IStorage *file1 = NULL, *file2 = NULL, *stg_tmp; + IStream *strm_tmp; + WCHAR buf[64]; + HRESULT hr; + + /* create & populate file1 */ + hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1); + ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + hr = create_test_file(file1); + if(FAILED(hr)) + goto cleanup; + + /* create file2 */ + hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2); + ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + /* copy file1 to file2 with name exclusions */ + hr = IStorage_CopyTo(file1, 0, NULL, (SNB)snb_exclude, file2); + ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + /* verify that file1 copied over, respecting exclusions */ + hr = IStorage_OpenStorage(file2, stgA_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp); + ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + IStorage_Release(stg_tmp); + + hr = IStorage_OpenStream(file2, strmA_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp); + ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + IStream_Release(strm_tmp); + + hr = IStorage_OpenStorage(file2, stgB_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp); + ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr); + + if(SUCCEEDED(hr)){ + hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp); + ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr); + + if(SUCCEEDED(hr)){ + memset(buf, 0, sizeof(buf)); + hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL); + ok(hr == S_OK, "Read failed: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + ok(strcmp_ww(buf, strmB_name) == 0, + "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf)); + + IStream_Release(strm_tmp); + } + + IStorage_Release(stg_tmp); + } + + hr = IStorage_OpenStream(file2, strmC_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp); + ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + IStream_Release(strm_tmp); + +cleanup: + if(file1) + IStorage_Release(file1); + if(file2) + IStorage_Release(file2); + + DeleteFileA(file1_nameA); + DeleteFileA(file2_nameA); +} + +static void test_copyto_iidexclusions_storage(void) +{ + IStorage *file1 = NULL, *file2 = NULL, *stg_tmp; + IStream *strm_tmp; + WCHAR buf[64]; + HRESULT hr; + + /* create & populate file1 */ + hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1); + ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + hr = create_test_file(file1); + if(FAILED(hr)) + goto cleanup; + + /* create file2 */ + hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2); + ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + /* copy file1 to file2 with iid exclusions */ + hr = IStorage_CopyTo(file1, 1, &IID_IStorage, NULL, file2); + ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + /* verify that file1 copied over, respecting exclusions */ + hr = IStorage_OpenStorage(file2, stgA_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp); + ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + IStorage_Release(stg_tmp); + + hr = IStorage_OpenStream(file2, strmA_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp); + ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + IStream_Release(strm_tmp); + + hr = IStorage_OpenStorage(file2, stgB_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp); + ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + IStorage_Release(stg_tmp); + + hr = IStorage_OpenStream(file2, strmB_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp); + ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + IStream_Release(strm_tmp); + + hr = IStorage_OpenStream(file2, strmC_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp); + ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr); + + if(SUCCEEDED(hr)){ + memset(buf, 0, sizeof(buf)); + hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL); + ok(hr == S_OK, "Read failed: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + ok(strcmp_ww(buf, strmC_name) == 0, + "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf)); + + IStream_Release(strm_tmp); + } + +cleanup: + if(file1) + IStorage_Release(file1); + if(file2) + IStorage_Release(file2); + + DeleteFileA(file1_nameA); + DeleteFileA(file2_nameA); +} + +static void test_copyto_iidexclusions_stream(void) +{ + IStorage *file1 = NULL, *file2 = NULL, *stg_tmp; + IStream *strm_tmp; + HRESULT hr; + + /* create & populate file1 */ + hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1); + ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + hr = create_test_file(file1); + if(FAILED(hr)) + goto cleanup; + + /* create file2 */ + hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2); + ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + /* copy file1 to file2 with iid exclusions */ + hr = IStorage_CopyTo(file1, 1, &IID_IStream, NULL, file2); + ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr); + if(FAILED(hr)) + goto cleanup; + + /* verify that file1 copied over, respecting exclusions */ + hr = IStorage_OpenStorage(file2, stgA_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp); + ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr); + + if(SUCCEEDED(hr)){ + hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp); + ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + IStream_Release(strm_tmp); + + IStorage_Release(stg_tmp); + } + + hr = IStorage_OpenStorage(file2, stgB_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp); + ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr); + + if(SUCCEEDED(hr)){ + hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp); + ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + IStream_Release(strm_tmp); + + IStorage_Release(stg_tmp); + } + + hr = IStorage_OpenStream(file2, strmC_name, NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp); + ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr); + if(SUCCEEDED(hr)) + IStream_Release(strm_tmp); + +cleanup: + if(file1) + IStorage_Release(file1); + if(file2) + IStorage_Release(file2); + + DeleteFileA(file1_nameA); + DeleteFileA(file2_nameA); +} + +static void test_rename(void) +{ + IStorage *stg, *stg2; + IStream *stm; + HRESULT r; + static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 }; + static const WCHAR stgname2[] = { 'S','T','G',0 }; + static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 }; + static const WCHAR stmname2[] = { 'E','N','T','S',0 }; + + DeleteFileA(filenameA); + + /* create the file */ + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + /* create a substorage */ + r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + /* create a stream in the substorage */ + r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm); + ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r); + IStream_Release(stm); + + /* rename the stream */ + r = IStorage_RenameElement(stg2, stmname, stmname2); + ok(r==S_OK, "IStorage->RenameElement failed, hr=%08x\n", r); + + /* cannot open stream with old name */ + r = IStorage_OpenStream(stg2, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm); + ok(r==STG_E_FILENOTFOUND, "IStorage_OpenStream should fail, hr=%08x\n", r); + if (SUCCEEDED(r)) IStream_Release(stm); + + /* can open stream with new name */ + r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm); + ok(r==S_OK, "IStorage_OpenStream failed, hr=%08x\n", r); + if (SUCCEEDED(r)) IStream_Release(stm); + + IStorage_Release(stg2); + + /* rename the storage */ + IStorage_RenameElement(stg, stgname, stgname2); + + /* cannot open storage with old name */ + r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg2); + ok(r==STG_E_FILENOTFOUND, "IStorage_OpenStream should fail, hr=%08x\n", r); + if (SUCCEEDED(r)) IStorage_Release(stg2); + + /* can open storage with new name */ + r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg2); + ok(r==S_OK, "IStorage_OpenStream should fail, hr=%08x\n", r); + if (SUCCEEDED(r)) + { + /* opened storage still has the stream */ + r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm); + ok(r==S_OK, "IStorage_OpenStream failed, hr=%08x\n", r); + if (SUCCEEDED(r)) IStream_Release(stm); + + IStorage_Release(stg2); + } + + IStorage_Release(stg); + + r = DeleteFileA(filenameA); + ok( r == TRUE, "deleted file\n"); +} + +static void test_toplevel_stat(void) +{ + IStorage *stg = NULL; + HRESULT r; + STATSTG stat; + char prev_dir[MAX_PATH]; + char temp[MAX_PATH]; + char full_path[MAX_PATH]; + LPSTR rel_pathA; + WCHAR rel_path[MAX_PATH]; + + DeleteFileA(filenameA); + + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE |STGM_TRANSACTED, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT ); + ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n", + wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName)); + CoTaskMemFree(stat.pwcsName); + + IStorage_Release( stg ); + + r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg); + ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r); + + r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT ); + ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n", + wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName)); + CoTaskMemFree(stat.pwcsName); + + IStorage_Release( stg ); + + DeleteFileA(filenameA); + + /* Stat always returns the full path, even for files opened with a relative path. */ + GetCurrentDirectoryA(MAX_PATH, prev_dir); + + GetTempPathA(MAX_PATH, temp); + + SetCurrentDirectoryA(temp); + + GetFullPathNameA(filenameA, MAX_PATH, full_path, &rel_pathA); + MultiByteToWideChar(CP_ACP, 0, rel_pathA, -1, rel_path, MAX_PATH); + + r = StgCreateDocfile( rel_path, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE |STGM_TRANSACTED, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT ); + ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n", + wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName)); + CoTaskMemFree(stat.pwcsName); + + IStorage_Release( stg ); + + r = StgOpenStorage( rel_path, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg); + ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r); + + r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT ); + ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n", + wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName)); + CoTaskMemFree(stat.pwcsName); + + IStorage_Release( stg ); + + SetCurrentDirectoryA(prev_dir); + + DeleteFileA(filenameA); +} + +static void test_substorage_enum(void) +{ + IStorage *stg, *stg2; + IEnumSTATSTG *ee; + HRESULT r; + ULONG ref; + static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 }; + + DeleteFileA(filenameA); + + /* create the file */ + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + /* create a substorage */ + r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + /* create an enumelements */ + r = IStorage_EnumElements(stg2, 0, NULL, 0, &ee); + ok(r==S_OK, "IStorage->EnumElements failed, hr=%08x\n", r); + + /* release the substorage */ + ref = IStorage_Release(stg2); + todo_wine ok(ref==0, "storage not released\n"); + + /* reopening fails, because the substorage is really still open */ + r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2); + ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage failed, hr=%08x\n", r); + + /* destroying the storage invalidates the enumerator */ + r = IStorage_DestroyElement(stg, stgname); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + r = IEnumSTATSTG_Reset(ee); + ok(r==STG_E_REVERTED, "IEnumSTATSTG->Reset failed, hr=%08x\n", r); + + IEnumSTATSTG_Release(ee); + + IStorage_Release(stg); + + r = DeleteFileA(filenameA); + ok( r == TRUE, "deleted file\n"); +} + +static void test_copyto_locking(void) +{ + IStorage *stg, *stg2, *stg3, *stg4; + IStream *stm; + HRESULT r; + static const WCHAR stgname[] = { 'S','T','G','1',0 }; + static const WCHAR stgname2[] = { 'S','T','G','2',0 }; + static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 }; + + DeleteFileA(filenameA); + + /* create the file */ + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + /* create a substorage */ + r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + /* create another substorage */ + r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + /* add a stream, and leave it open */ + r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm); + ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r); + + /* Try to copy the storage while the stream is open */ + r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3); + todo_wine ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r); + + IStream_Release(stm); + + /* create a substorage */ + r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg4); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + /* Try to copy the storage while the substorage is open */ + r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3); + todo_wine ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r); + + IStorage_Release(stg4); + IStorage_Release(stg3); + IStorage_Release(stg2); + IStorage_Release(stg); + + r = DeleteFileA(filenameA); + ok( r == TRUE, "deleted file\n"); +} + +static void test_copyto_recursive(void) +{ + IStorage *stg, *stg2, *stg3, *stg4; + HRESULT r; + static const WCHAR stgname[] = { 'S','T','G','1',0 }; + static const WCHAR stgname2[] = { 'S','T','G','2',0 }; + + DeleteFileA(filenameA); + + /* create the file */ + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + /* create a substorage */ + r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + /* copy the parent to the child */ + r = IStorage_CopyTo(stg, 0, NULL, NULL, stg2); + ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r); + + /* create a transacted substorage */ + r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg3); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + /* copy the parent to the transacted child */ + r = IStorage_CopyTo(stg, 0, NULL, NULL, stg2); + ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r); + + /* create a transacted subsubstorage */ + r = IStorage_CreateStorage(stg3, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg4); + ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + + /* copy the parent to the transacted child of the transacted child */ + r = IStorage_CopyTo(stg, 0, NULL, NULL, stg4); + ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r); + + /* copy the parent but exclude storage objects */ + r = IStorage_CopyTo(stg, 1, &IID_IStorage, NULL, stg4); + ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r); + + IStorage_Release(stg4); + IStorage_Release(stg3); + IStorage_Release(stg2); + IStorage_Release(stg); + + r = DeleteFileA(filenameA); + ok( r == TRUE, "deleted file\n"); +} + START_TEST(storage32) { + CHAR temp[MAX_PATH]; + + GetTempPathA(MAX_PATH, temp); + if(!GetTempFileNameA(temp, "stg", 0, filenameA)) + { + win_skip("Could not create temp file, %u\n", GetLastError()); + return; + } + MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filename, MAX_PATH); + DeleteFileA(filenameA); + test_hglobal_storage_stat(); test_create_storage_modes(); test_storage_stream(); @@ -1277,7 +2843,24 @@ START_TEST(storage32) test_storage_refcount(); test_streamenum(); test_transact(); + test_substorage_share(); + test_revert(); + test_parent_free(); + test_nonroot_transacted(); test_ReadClassStm(); test_access(); test_writeclassstg(); + test_readonly(); + test_simple(); + test_fmtusertypestg(); + test_references(); + test_copyto(); + test_copyto_snbexclusions(); + test_copyto_iidexclusions_storage(); + test_copyto_iidexclusions_stream(); + test_rename(); + test_toplevel_stat(); + test_substorage_enum(); + test_copyto_locking(); + test_copyto_recursive(); } diff --git a/rostests/winetests/ole32/usrmarshal.c b/rostests/winetests/ole32/usrmarshal.c index 3411cc283b1..a6553977744 100644 --- a/rostests/winetests/ole32/usrmarshal.c +++ b/rostests/winetests/ole32/usrmarshal.c @@ -29,7 +29,7 @@ #include "wine/test.h" -ULONG __RPC_USER HMETAFILE_UserSize(ULONG *, unsigned long, HMETAFILE *); +ULONG __RPC_USER HMETAFILE_UserSize(ULONG *, ULONG, HMETAFILE *); unsigned char * __RPC_USER HMETAFILE_UserMarshal(ULONG *, unsigned char *, HMETAFILE *); unsigned char * __RPC_USER HMETAFILE_UserUnmarshal(ULONG *, unsigned char *, HMETAFILE *); void __RPC_USER HMETAFILE_UserFree(ULONG *, HMETAFILE *); @@ -145,7 +145,7 @@ static void test_marshal_HWND(void) HWND_UserMarshal(&umcb.Flags, buffer, &hwnd); wirehwnd = (wireHWND)buffer; ok(wirehwnd->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", wirehwnd->fContext); - ok(wirehwnd->u.hInproc == (LONG_PTR)hwnd, "Marshaled value should be %p instead of %p\n", hwnd, (HANDLE)wirehwnd->u.hRemote); + ok(wirehwnd->u.hInproc == (LONG_PTR)hwnd, "Marshaled value should be %p instead of %x\n", hwnd, wirehwnd->u.hRemote); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); HWND_UserUnmarshal(&umcb.Flags, buffer, &hwnd2); @@ -162,7 +162,7 @@ static void test_marshal_HGLOBAL(void) MIDL_STUB_MESSAGE stub_msg; RPC_MESSAGE rpc_msg; unsigned char *buffer; - ULONG size; + ULONG size, block_size; HGLOBAL hglobal; HGLOBAL hglobal2; unsigned char *wirehglobal; @@ -188,39 +188,52 @@ static void test_marshal_HGLOBAL(void) init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL); HGLOBAL_UserFree(&umcb.Flags, &hglobal2); - hglobal = GlobalAlloc(0, 4); - buffer = GlobalLock(hglobal); - for (i = 0; i < 4; i++) - buffer[i] = i; - GlobalUnlock(hglobal); - init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL); - size = HGLOBAL_UserSize(&umcb.Flags, 0, &hglobal); - /* native is poorly programmed and allocates 4/8 bytes more than it needs to - * here - Wine doesn't have to emulate that */ - ok((size == 24) || broken(size == 28) || broken(size == 32), "Size should be 24, instead of %d\n", size); - buffer = HeapAlloc(GetProcessHeap(), 0, size); - init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); - HGLOBAL_UserMarshal(&umcb.Flags, buffer, &hglobal); - wirehglobal = buffer; - ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal); - wirehglobal += sizeof(ULONG); - ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0x4 should be HGLOBAL\n"); - wirehglobal += sizeof(ULONG); - ok(*(ULONG *)wirehglobal == 4, "buffer+0x8 should be size of HGLOBAL instead of %d\n", *(ULONG *)wirehglobal); - wirehglobal += sizeof(ULONG); - ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0xc should be HGLOBAL\n"); - wirehglobal += sizeof(ULONG); - ok(*(ULONG *)wirehglobal == 4, "buffer+0x10 should be size of HGLOBAL instead of %d\n", *(ULONG *)wirehglobal); - wirehglobal += sizeof(ULONG); - for (i = 0; i < 4; i++) - ok(wirehglobal[i] == i, "buffer+0x%x should be %d\n", 0x10 + i, i); - init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); - HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2); - ok(hglobal2 != NULL, "Didn't unmarshal properly\n"); - HeapFree(GetProcessHeap(), 0, buffer); - init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL); - HGLOBAL_UserFree(&umcb.Flags, &hglobal2); - GlobalFree(hglobal); + + for(block_size = 0; block_size <= 17; block_size++) + { + ULONG actual_size, expected_size; + + hglobal = GlobalAlloc(0, block_size); + buffer = GlobalLock(hglobal); + for (i = 0; i < block_size; i++) + buffer[i] = i; + GlobalUnlock(hglobal); + actual_size = GlobalSize(hglobal); + expected_size = actual_size + 5 * sizeof(DWORD); + trace("%d: actual size %d\n", block_size, actual_size); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL); + size = HGLOBAL_UserSize(&umcb.Flags, 0, &hglobal); + /* native is poorly programmed and allocates 4/8 bytes more than it needs to + * here - Wine doesn't have to emulate that */ + ok(size == expected_size || + broken(size == expected_size + 4) || + broken(size == expected_size + 8), + "%d: got size %d\n", block_size, size); + buffer = HeapAlloc(GetProcessHeap(), 0, size); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); + HGLOBAL_UserMarshal(&umcb.Flags, buffer, &hglobal); + wirehglobal = buffer; + ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal); + wirehglobal += sizeof(ULONG); + ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0x4 should be HGLOBAL\n"); + wirehglobal += sizeof(ULONG); + ok(*(ULONG *)wirehglobal == actual_size, "%d: buffer+0x8 %08x\n", block_size, *(ULONG *)wirehglobal); + wirehglobal += sizeof(ULONG); + ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0xc should be HGLOBAL\n"); + wirehglobal += sizeof(ULONG); + ok(*(ULONG *)wirehglobal == actual_size, "%d: buffer+0x10 %08x\n", block_size, *(ULONG *)wirehglobal); + wirehglobal += sizeof(ULONG); + for (i = 0; i < block_size; i++) + ok(wirehglobal[i] == i, "buffer+0x%x should be %d\n", 0x10 + i, i); + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); + HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2); + ok(hglobal2 != NULL, "Didn't unmarshal properly\n"); + HeapFree(GetProcessHeap(), 0, buffer); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL); + HGLOBAL_UserFree(&umcb.Flags, &hglobal2); + GlobalFree(hglobal); + } } static HENHMETAFILE create_emf(void) @@ -495,14 +508,50 @@ static const IUnknownVtbl TestUnknown_Vtbl = Test_IUnknown_Release, }; +static HRESULT WINAPI Test_IStream_QueryInterface(IStream *iface, + REFIID riid, LPVOID *ppvObj) +{ + if (ppvObj == NULL) return E_POINTER; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IStream)) + { + *ppvObj = iface; + IStream_AddRef(iface); + return S_OK; + } + + *ppvObj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI Test_IStream_AddRef(IStream *iface) +{ + return 2; /* non-heap-based object */ +} + +static ULONG WINAPI Test_IStream_Release(IStream *iface) +{ + return 1; /* non-heap-based object */ +} + +static const IStreamVtbl TestStream_Vtbl = +{ + Test_IStream_QueryInterface, + Test_IStream_AddRef, + Test_IStream_Release + /* the rest can be NULLs */ +}; + static IUnknown Test_Unknown = { &TestUnknown_Vtbl }; +static IStream Test_Stream = { &TestStream_Vtbl }; ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *, ULONG, ULONG, IUnknown *, REFIID); unsigned char * __RPC_USER WdtpInterfacePointer_UserMarshal(ULONG *, ULONG, unsigned char *, IUnknown *, REFIID); unsigned char * __RPC_USER WdtpInterfacePointer_UserUnmarshal(ULONG *, unsigned char *, IUnknown **, REFIID); void __RPC_USER WdtpInterfacePointer_UserFree(IUnknown *); -static void test_marshal_WdtpInterfacePointer(void) +static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx) { USER_MARSHAL_CB umcb; MIDL_STUB_MESSAGE stub_msg; @@ -512,64 +561,196 @@ static void test_marshal_WdtpInterfacePointer(void) IUnknown *unk; IUnknown *unk2; unsigned char *wireip; - const IID *iid; + HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, 0); + IStream *stm; + void *marshal_data; + LARGE_INTEGER zero; + ULARGE_INTEGER pos; + DWORD marshal_size; /* shows that the WdtpInterfacePointer functions don't marshal anything for * NULL pointers, so code using these functions must handle that case * itself */ + unk = NULL; - init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC); - size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 0, unk, &IID_IUnknown); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, umcb_ctx); + size = WdtpInterfacePointer_UserSize(&umcb.Flags, ctx, 0, unk, &IID_IUnknown); ok(size == 0, "size should be 0 bytes, not %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); - buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, buffer, unk, &IID_IUnknown); + buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown); wireip = buffer; HeapFree(GetProcessHeap(), 0, buffer); + /* Now for a non-NULL pointer. The marshalled data are two size DWORDS and then + the result of CoMarshalInterface called with the LOWORD of the ctx */ + unk = &Test_Unknown; - init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC); - size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 0, unk, &IID_IUnknown); - todo_wine - ok(size > 28, "size should be > 28 bytes, not %d\n", size); - trace("WdtpInterfacePointer_UserSize returned %d\n", size); + + CreateStreamOnHGlobal(h, TRUE, &stm); + CoMarshalInterface(stm, &IID_IUnknown, unk, LOWORD(ctx), NULL, MSHLFLAGS_NORMAL); + zero.QuadPart = 0; + IStream_Seek(stm, zero, STREAM_SEEK_CUR, &pos); + marshal_size = pos.u.LowPart; + marshal_data = GlobalLock(h); + trace("marshal_size %x\n", marshal_size); + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, umcb_ctx); + size = WdtpInterfacePointer_UserSize(&umcb.Flags, ctx, 0, unk, &IID_IUnknown); + ok(size >= marshal_size + 2 * sizeof(DWORD), "marshal size %x got %x\n", marshal_size, size); + trace("WdtpInterfacePointer_UserSize returned %x\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); - init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC); - buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, buffer, unk, &IID_IUnknown); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx); + buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown); wireip = buffer; - if (size >= 28) - { - ok(*(DWORD *)wireip == 0x44, "wireip + 0x0 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip); - wireip += sizeof(DWORD); - ok(*(DWORD *)wireip == 0x44, "wireip + 0x4 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip); - wireip += sizeof(DWORD); - ok(*(DWORD *)wireip == 0x574f454d /* 'MEOW' */, "wireip + 0x8 should be 0x574f454d instead of 0x%08x\n", *(DWORD *)wireip); - wireip += sizeof(DWORD); - ok(*(DWORD *)wireip == 0x1, "wireip + 0xc should be 0x1 instead of 0x%08x\n", *(DWORD *)wireip); - wireip += sizeof(DWORD); - iid = (const IID *)wireip; - ok(IsEqualIID(iid, &IID_IUnknown), - "wireip + 0x10 should be IID_IUnknown instead of {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", - iid->Data1, iid->Data2, iid->Data3, - iid->Data4[0], iid->Data4[1], iid->Data4[2], iid->Data4[3], - iid->Data4[4], iid->Data4[5], iid->Data4[6], iid->Data4[7]); - wireip += sizeof(IID); - ok(*(DWORD *)wireip == 0, "wireip + 0x1c should be 0 instead of 0x%08x\n", *(DWORD *)wireip); - wireip += sizeof(DWORD); - ok(*(DWORD *)wireip == 5, "wireip + 0x20 should be 5 instead of %d\n", *(DWORD *)wireip); - wireip += sizeof(DWORD); - /* the rest is dynamic so can't really be tested */ - } + + ok(buffer_end == buffer + marshal_size + 2 * sizeof(DWORD), "buffer_end %p buffer %p (diff %x)\n", buffer_end, buffer, buffer_end - buffer); + + ok(*(DWORD *)wireip == marshal_size, "wireip + 0x0 should be %x instead of %x\n", marshal_size, *(DWORD *)wireip); + wireip += sizeof(DWORD); + ok(*(DWORD *)wireip == marshal_size, "wireip + 0x4 should be %x instead of %x\n", marshal_size, *(DWORD *)wireip); + wireip += sizeof(DWORD); + + ok(!memcmp(marshal_data, wireip, marshal_size), "buffer mismatch\n"); + GlobalUnlock(h); + zero.QuadPart = 0; + IStream_Seek(stm, zero, STREAM_SEEK_SET, NULL); + CoReleaseMarshalData(stm); + IStream_Release(stm); unk2 = NULL; - init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx); WdtpInterfacePointer_UserUnmarshal(&umcb.Flags, buffer, &unk2, &IID_IUnknown); - todo_wine ok(unk2 != NULL, "IUnknown object didn't unmarshal properly\n"); HeapFree(GetProcessHeap(), 0, buffer); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC); WdtpInterfacePointer_UserFree(unk2); } +static void test_marshal_WdtpInterfacePointer(void) +{ + /* + * There are two places where we can pass the marshalling ctx: as + * part of the umcb and as a separate flag. The loword of that + * separate flag field is what matters. + */ + + /* All three are marshalled as inproc */ + marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_INPROC); + marshal_WdtpInterfacePointer(MSHCTX_DIFFERENTMACHINE, MSHCTX_INPROC); + marshal_WdtpInterfacePointer(MSHCTX_INPROC, MAKELONG(MSHCTX_INPROC, 0xffff)); + + /* All three are marshalled as remote */ + marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE); + marshal_WdtpInterfacePointer(MSHCTX_DIFFERENTMACHINE, MSHCTX_DIFFERENTMACHINE); + marshal_WdtpInterfacePointer(MSHCTX_INPROC, MAKELONG(MSHCTX_DIFFERENTMACHINE, 0xffff)); +} + +static void test_marshal_STGMEDIUM(void) +{ + USER_MARSHAL_CB umcb; + MIDL_STUB_MESSAGE stub_msg; + RPC_MESSAGE rpc_msg; + unsigned char *buffer, *buffer_end, *expect_buffer, *expect_buffer_end; + ULONG size, expect_size; + STGMEDIUM med, med2; + IUnknown *unk = &Test_Unknown; + IStream *stm = &Test_Stream; + + /* TYMED_NULL with pUnkForRelease */ + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); + expect_size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 2 * sizeof(DWORD), unk, &IID_IUnknown); + expect_buffer = HeapAlloc(GetProcessHeap(), 0, expect_size); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, expect_buffer, expect_size, MSHCTX_DIFFERENTMACHINE); + expect_buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, expect_buffer + 2 * sizeof(DWORD), unk, &IID_IUnknown); + + med.tymed = TYMED_NULL; + U(med).pstg = NULL; + med.pUnkForRelease = unk; + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); + size = STGMEDIUM_UserSize(&umcb.Flags, 0, &med); + ok(size == expect_size, "size %d should be %d bytes\n", size, expect_size); + + buffer = HeapAlloc(GetProcessHeap(), 0, size); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); + buffer_end = STGMEDIUM_UserMarshal(&umcb.Flags, buffer, &med); + ok(buffer_end - buffer == expect_buffer_end - expect_buffer, "buffer size mismatch\n"); + ok(*(DWORD*)buffer == TYMED_NULL, "got %08x\n", *(DWORD*)buffer); + ok(*((DWORD*)buffer+1) != 0, "got %08x\n", *((DWORD*)buffer+1)); + ok(!memcmp(buffer+8, expect_buffer + 8, expect_buffer_end - expect_buffer - 8), "buffer mismatch\n"); + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); + + /* native crashes if this is uninitialised, presumably because it + tries to release it */ + med2.tymed = TYMED_NULL; + U(med2).pstm = NULL; + med2.pUnkForRelease = NULL; + + STGMEDIUM_UserUnmarshal(&umcb.Flags, buffer, &med2); + + ok(med2.tymed == TYMED_NULL, "got tymed %x\n", med2.tymed); + ok(med2.pUnkForRelease != NULL, "Incorrectly unmarshalled\n"); + + HeapFree(GetProcessHeap(), 0, buffer); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); + STGMEDIUM_UserFree(&umcb.Flags, &med2); + + HeapFree(GetProcessHeap(), 0, expect_buffer); + + /* TYMED_ISTREAM with pUnkForRelease */ + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); + expect_size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 3 * sizeof(DWORD), (IUnknown*)stm, &IID_IStream); + expect_size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, expect_size, unk, &IID_IUnknown); + + expect_buffer = HeapAlloc(GetProcessHeap(), 0, expect_size); + /* There may be a hole between the two interfaces so init the buffer to something */ + memset(expect_buffer, 0xcc, expect_size); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, expect_buffer, expect_size, MSHCTX_DIFFERENTMACHINE); + expect_buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, expect_buffer + 3 * sizeof(DWORD), (IUnknown*)stm, &IID_IStream); + expect_buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, expect_buffer_end, unk, &IID_IUnknown); + + med.tymed = TYMED_ISTREAM; + U(med).pstm = stm; + med.pUnkForRelease = unk; + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); + size = STGMEDIUM_UserSize(&umcb.Flags, 0, &med); + ok(size == expect_size, "size %d should be %d bytes\n", size, expect_size); + + buffer = HeapAlloc(GetProcessHeap(), 0, size); + memset(buffer, 0xcc, size); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); + buffer_end = STGMEDIUM_UserMarshal(&umcb.Flags, buffer, &med); + ok(buffer_end - buffer == expect_buffer_end - expect_buffer, "buffer size mismatch\n"); + ok(*(DWORD*)buffer == TYMED_ISTREAM, "got %08x\n", *(DWORD*)buffer); + ok(*((DWORD*)buffer+1) != 0, "got %08x\n", *((DWORD*)buffer+1)); + ok(*((DWORD*)buffer+2) != 0, "got %08x\n", *((DWORD*)buffer+2)); + ok(!memcmp(buffer + 12, expect_buffer + 12, (buffer_end - buffer) - 12), "buffer mismatch\n"); + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); + + /* native crashes if this is uninitialised, presumably because it + tries to release it */ + med2.tymed = TYMED_NULL; + U(med2).pstm = NULL; + med2.pUnkForRelease = NULL; + + STGMEDIUM_UserUnmarshal(&umcb.Flags, buffer, &med2); + + ok(med2.tymed == TYMED_ISTREAM, "got tymed %x\n", med2.tymed); + ok(U(med2).pstm != NULL, "Incorrectly unmarshalled\n"); + ok(med2.pUnkForRelease != NULL, "Incorrectly unmarshalled\n"); + + HeapFree(GetProcessHeap(), 0, buffer); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); + STGMEDIUM_UserFree(&umcb.Flags, &med2); + + HeapFree(GetProcessHeap(), 0, expect_buffer); +} + START_TEST(usrmarshal) { CoInitialize(NULL); @@ -581,6 +762,7 @@ START_TEST(usrmarshal) test_marshal_HMETAFILE(); test_marshal_HMETAFILEPICT(); test_marshal_WdtpInterfacePointer(); + test_marshal_STGMEDIUM(); CoUninitialize(); } From 1733eb0a2f1b464b6d6482a167cd73b93f93216f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 10 Mar 2010 22:25:40 +0000 Subject: [PATCH 33/64] - We forget that AE_BUFFER_OVERFLOW is normal and expected since our buffer length is 0 so don't fail if that status is returned - For any device that actually had resources we would return STATUS_SUCCESS without building a resource list and if the device didn't have resources we would end up freeing a NULL pointer, storing stack trash in Irp->IoStatus.Information, and then returning STATUS_SUCCESS - Fixes reporting device resources (and possibly the VBox additions crash with ACPI enabled) svn path=/trunk/; revision=46080 --- reactos/drivers/bus/acpi/buspdo.c | 56 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/reactos/drivers/bus/acpi/buspdo.c b/reactos/drivers/bus/acpi/buspdo.c index 25fbe324f4f..e7cc65b0c19 100644 --- a/reactos/drivers/bus/acpi/buspdo.c +++ b/reactos/drivers/bus/acpi/buspdo.c @@ -598,24 +598,24 @@ Bus_PDO_QueryResources( /* Get current resources */ Buffer.Length = 0; + AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); + if ((!ACPI_SUCCESS(AcpiStatus) && AcpiStatus != AE_BUFFER_OVERFLOW) || + Buffer.Length == 0) + { + return Irp->IoStatus.Status; + } + + Buffer.Pointer = ExAllocatePool(PagedPool, Buffer.Length); + if (!Buffer.Pointer) + return STATUS_INSUFFICIENT_RESOURCES; + AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); if (!ACPI_SUCCESS(AcpiStatus)) { - return STATUS_SUCCESS; + DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus); + ASSERT(FALSE); + return STATUS_UNSUCCESSFUL; } - if (Buffer.Length > 0) - { - Buffer.Pointer = ExAllocatePool(PagedPool, Buffer.Length); - if (!Buffer.Pointer) - { - ASSERT(FALSE); - } - AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); - if (!ACPI_SUCCESS(AcpiStatus)) - { - ASSERT(FALSE); - } - } resource= Buffer.Pointer; /* Count number of resources */ @@ -775,24 +775,24 @@ Bus_PDO_QueryResourceRequirements( /* Get current resources */ Buffer.Length = 0; + AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); + if ((!ACPI_SUCCESS(AcpiStatus) && AcpiStatus != AE_BUFFER_OVERFLOW) || + Buffer.Length == 0) + { + return Irp->IoStatus.Status; + } + + Buffer.Pointer = ExAllocatePool(PagedPool, Buffer.Length); + if (!Buffer.Pointer) + return STATUS_INSUFFICIENT_RESOURCES; + AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); if (!ACPI_SUCCESS(AcpiStatus)) { - return STATUS_SUCCESS; + DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus); + ASSERT(FALSE); + return STATUS_UNSUCCESSFUL; } - if (Buffer.Length > 0) - { - Buffer.Pointer = ExAllocatePool(PagedPool, Buffer.Length); - if (!Buffer.Pointer) - { - ASSERT(FALSE); - } - AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); - if (!ACPI_SUCCESS(AcpiStatus)) - { - ASSERT(FALSE); - } - } resource= Buffer.Pointer; /* Count number of resources */ From a6789f14311d4994f72626d0f5cbf72b7d98a864 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Thu, 11 Mar 2010 02:43:51 +0000 Subject: [PATCH 34/64] - Add new menu structures. svn path=/trunk/; revision=46090 --- reactos/include/reactos/win32k/ntuser.h | 51 +++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index 9354faccd56..a9feb1fb69f 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -221,6 +221,57 @@ C_ASSERT(sizeof(CLIENTINFO) == FIELD_OFFSET(TEB, glDispatchTable) - FIELD_OFFSET #define GetWin32ClientInfo() ((PCLIENTINFO)(NtCurrentTeb()->Win32ClientInfo)) +typedef struct tagITEM +{ + UINT fType; + UINT fState; + UINT wID; + struct tagMENU* spSubMenu; /* Pop-up menu. */ + HANDLE hbmpChecked; + HANDLE hbmpUnchecked; + USHORT* lpstr; /* Item text pointer. */ + ULONG cch; + DWORD_PTR dwItemData; + ULONG xItem; /* Item position. left */ + ULONG yItem; /* " top */ + ULONG cxItem; /* Item Size Width */ + ULONG cyItem; /* " Height */ + ULONG dxTab; /* X position of text after Tab */ + ULONG ulX; /* underline.. start position */ + ULONG ulWidth; /* underline.. width */ + HBITMAP hbmp; /* bitmap */ + INT cxBmp; /* Width Maximum size of the bitmap items in MIIM_BITMAP state */ + INT cyBmp; /* Height " */ +} ITEM, *PITEM; + +typedef struct tagMENULIST +{ + struct tagMENULIST* pNext; + struct tagMENU* pMenu; +} MENULIST, *PMENULIST; + +typedef struct tagMENU +{ + PROCDESKHEAD head; + ULONG fFlags; /* Menu flags (MF_POPUP, MF_SYSMENU) */ + INT iItem; /* nPos of selected item, if -1 not selected. */ + UINT cAlloced; /* Number of allocated items. */ + UINT cItems; /* Number of items in the menu */ + ULONG cxMenu; /* Width of the whole menu */ + ULONG cyMenu; /* Height of the whole menu */ + ULONG cxTextAlign; /* Offset of text when items have both bitmaps and text */ + struct _WND *spwndNotify; /* window receiving the messages for ownerdraw */ + PITEM rgItems; /* Array of menu items */ + struct tagMENULIST* pParentMenus; /* If this is SubMenu, list of parents. */ + DWORD dwContextHelpId; + ULONG cyMax; /* max height of the whole menu, 0 is screen height */ + DWORD_PTR dwMenuData; /* application defined value */ + HBRUSH hbrBack; /* brush for menu background */ + INT iTop; /* Current scroll position Top */ + INT iMaxTop; /* Current scroll position Max Top */ + DWORD dwArrowsOn:2; /* Arrows: 0 off, 1 on, 2 to the top, 3 to the bottom. */ +} MENU, *PMENU; + typedef struct _REGISTER_SYSCLASS { /* This is a reactos specific class used to initialize the From e04c0cda3e4f9690645c921fdd107c8c8dc2a681 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Thu, 11 Mar 2010 03:28:32 +0000 Subject: [PATCH 35/64] - Fix build! svn path=/trunk/; revision=46091 --- reactos/include/psdk/guiddef.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/reactos/include/psdk/guiddef.h b/reactos/include/psdk/guiddef.h index e96e9e9f566..b02e57e4972 100644 --- a/reactos/include/psdk/guiddef.h +++ b/reactos/include/psdk/guiddef.h @@ -140,6 +140,4 @@ inline bool operator!=(const GUID& guidOne, const GUID& guidOther) #endif #endif -extern const IID GUID_NULL; - #endif /* _GUIDDEF_H_ */ From 0b49f57301789ea212edb98336972dfd13808b85 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Thu, 11 Mar 2010 03:29:01 +0000 Subject: [PATCH 36/64] - Fix test build! svn path=/trunk/; revision=46092 --- rostests/winetests/ole32/compobj.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rostests/winetests/ole32/compobj.c b/rostests/winetests/ole32/compobj.c index 9d469b4b174..755d15a9f66 100644 --- a/rostests/winetests/ole32/compobj.c +++ b/rostests/winetests/ole32/compobj.c @@ -35,6 +35,8 @@ #include "wine/test.h" +extern const IID GUID_NULL; + /* functions that are not present on all versions of Windows */ HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit); HRESULT (WINAPI * pCoGetObjectContext)(REFIID riid, LPVOID *ppv); From 3b52f6a934a6d084b1c78fb65adf65e161721bd8 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 11 Mar 2010 10:28:34 +0000 Subject: [PATCH 37/64] [OLEAUT32] - Sync to Wine-1.1.40. svn path=/trunk/; revision=46093 --- reactos/dll/win32/oleaut32/dispatch.c | 31 +- reactos/dll/win32/oleaut32/oleaut.c | 32 +- reactos/dll/win32/oleaut32/oleaut32.rbuild | 4 +- reactos/dll/win32/oleaut32/oleaut32.rc | 12 +- reactos/dll/win32/oleaut32/oleaut32_Bg.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Cz.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Da.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_De.rc | 4 + reactos/dll/win32/oleaut32/oleaut32_El.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_En.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Eo.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Es.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Fr.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Hu.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_It.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Ko.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Lt.rc | 36 + reactos/dll/win32/oleaut32/oleaut32_Nl.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_No.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Pl.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Pt.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Ro.rc | 4 +- reactos/dll/win32/oleaut32/oleaut32_Ru.rc | 17 +- reactos/dll/win32/oleaut32/oleaut32_Si.rc | 4 +- reactos/dll/win32/oleaut32/oleaut32_Sv.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Th.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Tr.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Uk.rc | 23 +- reactos/dll/win32/oleaut32/oleaut32_Zh.rc | 4 +- reactos/dll/win32/oleaut32/oleaut32_ros.diff | 74 -- reactos/dll/win32/oleaut32/olefont.c | 432 +++++--- reactos/dll/win32/oleaut32/olepicture.c | 2 +- reactos/dll/win32/oleaut32/regsvr.c | 85 +- reactos/dll/win32/oleaut32/tmarshal.c | 220 +--- reactos/dll/win32/oleaut32/typelib.c | 422 ++++--- reactos/dll/win32/oleaut32/typelib.h | 3 +- reactos/dll/win32/oleaut32/typelib2.c | 1040 +++++++++++++++--- reactos/dll/win32/oleaut32/usrmarshal.c | 101 +- reactos/dll/win32/oleaut32/varformat.c | 22 +- reactos/dll/win32/oleaut32/variant.c | 173 ++- reactos/dll/win32/oleaut32/variant.h | 1 + reactos/dll/win32/oleaut32/vartype.c | 40 +- reactos/media/doc/README.WINE | 2 +- 43 files changed, 1896 insertions(+), 928 deletions(-) create mode 100644 reactos/dll/win32/oleaut32/oleaut32_Lt.rc delete mode 100644 reactos/dll/win32/oleaut32/oleaut32_ros.diff diff --git a/reactos/dll/win32/oleaut32/dispatch.c b/reactos/dll/win32/oleaut32/dispatch.c index 2fd8bb42d00..ed3fad47019 100644 --- a/reactos/dll/win32/oleaut32/dispatch.c +++ b/reactos/dll/win32/oleaut32/dispatch.c @@ -130,10 +130,14 @@ HRESULT WINAPI DispGetParam( TRACE("position=%d, cArgs=%d, cNamedArgs=%d\n", position, pdispparams->cArgs, pdispparams->cNamedArgs); - if (position < pdispparams->cArgs) { + + if (position < pdispparams->cArgs) + { /* positional arg? */ pos = pdispparams->cArgs - position - 1; - } else { + } + else + { /* FIXME: is this how to handle named args? */ for (pos=0; poscNamedArgs; pos++) if (pdispparams->rgdispidNamedArgs[pos] == position) break; @@ -141,10 +145,27 @@ HRESULT WINAPI DispGetParam( if (pos==pdispparams->cNamedArgs) return DISP_E_PARAMNOTFOUND; } + + if (pdispparams->cArgs > 0 && !pdispparams->rgvarg) + { + hr = E_INVALIDARG; + goto done; + } + + if (!pvarResult) + { + hr = E_INVALIDARG; + goto done; + } + hr = VariantChangeType(pvarResult, &pdispparams->rgvarg[pos], 0, vtTarg); - if (hr == DISP_E_TYPEMISMATCH) *puArgErr = pos; + +done: + if (FAILED(hr)) + *puArgErr = pos; + return hr; } @@ -234,8 +255,8 @@ static HRESULT WINAPI StdDispatch_QueryInterface( IsEqualIID(riid, &IID_IUnknown)) { *ppvObject = This; - IUnknown_AddRef((LPUNKNOWN)*ppvObject); - return S_OK; + IUnknown_AddRef((LPUNKNOWN)*ppvObject); + return S_OK; } return E_NOINTERFACE; } diff --git a/reactos/dll/win32/oleaut32/oleaut.c b/reactos/dll/win32/oleaut32/oleaut.c index 0eaddb15b6d..89e1ab9dc2c 100644 --- a/reactos/dll/win32/oleaut32/oleaut.c +++ b/reactos/dll/win32/oleaut32/oleaut.c @@ -294,19 +294,17 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len) return 0; if (*old!=NULL) { + BSTR old_copy = *old; DWORD newbytelen = len*sizeof(WCHAR); DWORD *ptr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,newbytelen+sizeof(WCHAR)+sizeof(DWORD)); *old = (BSTR)(ptr+1); *ptr = newbytelen; - if (str) { - memmove(*old, str, newbytelen); - (*old)[len] = 0; - } else { - /* Subtle hidden feature: The old string data is still there - * when 'in' is NULL! - * Some Microsoft program needs it. - */ - } + /* Subtle hidden feature: The old string data is still there + * when 'in' is NULL! + * Some Microsoft program needs it. + */ + if (str && old_copy!=str) memmove(*old, str, newbytelen); + (*old)[len] = 0; } else { /* * Allocate the new string @@ -696,6 +694,7 @@ HRESULT WINAPI OleTranslateColor( extern HRESULT WINAPI OLEAUTPS_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN; extern BOOL WINAPI OLEAUTPS_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN; +extern GUID const CLSID_PSFactoryBuffer DECLSPEC_HIDDEN; extern void _get_STDFONT_CF(LPVOID *); extern void _get_STDPIC_CF(LPVOID *); @@ -728,7 +727,7 @@ static HRESULT WINAPI PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer *iface, IUnk HRESULT hr; if (IsEqualIID(riid, &IID_IDispatch)) - hr = OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, &IID_IPSFactoryBuffer, (void **)&pPSFB); + hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&pPSFB); else hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface, &IID_IPSFactoryBuffer, (void **)&pPSFB); @@ -746,7 +745,7 @@ static HRESULT WINAPI PSDispatchFacBuf_CreateStub(IPSFactoryBuffer *iface, REFII HRESULT hr; if (IsEqualIID(riid, &IID_IDispatch)) - hr = OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, &IID_IPSFactoryBuffer, (void **)&pPSFB); + hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&pPSFB); else hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface, &IID_IPSFactoryBuffer, (void **)&pPSFB); @@ -790,11 +789,6 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) return S_OK; } } - if (IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) || - IsEqualCLSID(rclsid, &CLSID_PSTypeLib) || - IsEqualCLSID(rclsid, &CLSID_PSEnumVariant)) { - return OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, iid, ppv); - } if (IsEqualCLSID(rclsid, &CLSID_PSDispatch) && IsEqualIID(iid, &IID_IPSFactoryBuffer)) { *ppv = &pPSDispatchFacBuf; IPSFactoryBuffer_AddRef((IPSFactoryBuffer *)*ppv); @@ -805,6 +799,12 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) return S_OK; /*FALLTHROUGH*/ } + if (IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) || + IsEqualCLSID(rclsid, &CLSID_PSTypeLib) || + IsEqualCLSID(rclsid, &CLSID_PSDispatch) || + IsEqualCLSID(rclsid, &CLSID_PSEnumVariant)) + return OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, iid, ppv); + return OLEAUTPS_DllGetClassObject(rclsid, iid, ppv); } diff --git a/reactos/dll/win32/oleaut32/oleaut32.rbuild b/reactos/dll/win32/oleaut32/oleaut32.rbuild index 8b117b93ace..1873cade868 100644 --- a/reactos/dll/win32/oleaut32/oleaut32.rbuild +++ b/reactos/dll/win32/oleaut32/oleaut32.rbuild @@ -9,7 +9,7 @@ include/reactos/wine 0x600 - CLSID_PSDispatch + {0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}} @@ -54,7 +54,7 @@ - CLSID_PSDispatch + {0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}} diff --git a/reactos/dll/win32/oleaut32/oleaut32.rc b/reactos/dll/win32/oleaut32/oleaut32.rc index e05528ee698..847da8beff4 100644 --- a/reactos/dll/win32/oleaut32/oleaut32.rc +++ b/reactos/dll/win32/oleaut32/oleaut32.rc @@ -26,7 +26,6 @@ #include "oleaut32_Bg.rc" #include "oleaut32_Da.rc" -#include "oleaut32_De.rc" #include "oleaut32_El.rc" #include "oleaut32_En.rc" #include "oleaut32_Eo.rc" @@ -41,14 +40,17 @@ #include "oleaut32_No.rc" #include "oleaut32_Pl.rc" #include "oleaut32_Pt.rc" -#include "oleaut32_Ro.rc" -#include "oleaut32_Ru.rc" -#include "oleaut32_Si.rc" #include "oleaut32_Sv.rc" #include "oleaut32_Th.rc" #include "oleaut32_Tr.rc" -#include "oleaut32_Zh.rc" + +#include "oleaut32_De.rc" +#include "oleaut32_Lt.rc" +#include "oleaut32_Ro.rc" +#include "oleaut32_Ru.rc" +#include "oleaut32_Si.rc" #include "oleaut32_Uk.rc" +#include "oleaut32_Zh.rc" /* * FIXME: diff --git a/reactos/dll/win32/oleaut32/oleaut32_Bg.rc b/reactos/dll/win32/oleaut32/oleaut32_Bg.rc index 7e930f41020..7f0180b2b09 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Bg.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Bg.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Cz.rc b/reactos/dll/win32/oleaut32/oleaut32_Cz.rc index 7075b43cc0e..48be0b70a82 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Cz.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Cz.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_CZECH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Da.rc b/reactos/dll/win32/oleaut32/oleaut32_Da.rc index 6f1dcbcad91..e28922fa1bf 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Da.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Da.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_DANISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_De.rc b/reactos/dll/win32/oleaut32/oleaut32_De.rc index 9fb786cfca0..1dbee3ee8c7 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_De.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_De.rc @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + +#pragma code_page(65001) + LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_El.rc b/reactos/dll/win32/oleaut32/oleaut32_El.rc index 145c1a12959..a0337950262 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_El.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_El.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_GREEK, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_En.rc b/reactos/dll/win32/oleaut32/oleaut32_En.rc index e56eb11d6e3..6a98642e7ca 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_En.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_En.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Eo.rc b/reactos/dll/win32/oleaut32/oleaut32_Eo.rc index c00e2fd4f44..ae67139109e 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Eo.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Eo.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Es.rc b/reactos/dll/win32/oleaut32/oleaut32_Es.rc index 5cc25ca49d5..5c187db364f 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Es.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Es.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Fr.rc b/reactos/dll/win32/oleaut32/oleaut32_Fr.rc index 40e392ee162..d6136ef8cda 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Fr.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Fr.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Hu.rc b/reactos/dll/win32/oleaut32/oleaut32_Hu.rc index 35283c8314a..ec3b9827e3f 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Hu.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Hu.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_It.rc b/reactos/dll/win32/oleaut32/oleaut32_It.rc index 0dee161a217..69fa31a34a7 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_It.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_It.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Ko.rc b/reactos/dll/win32/oleaut32/oleaut32_Ko.rc index 0134c7a54b9..541380543a5 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Ko.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Ko.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Lt.rc b/reactos/dll/win32/oleaut32/oleaut32_Lt.rc new file mode 100644 index 00000000000..c568d93cb78 --- /dev/null +++ b/reactos/dll/win32/oleaut32/oleaut32_Lt.rc @@ -0,0 +1,36 @@ +/* + * Lithuanian resources for oleaut32 + * + * Copyright 2009 Aurimas FiÅ¡eras + * + * 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 "resource.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "Tiesa" + IDS_FALSE "Netiesa" + IDS_YES "Taip" + IDS_NO "Ne" + IDS_ON "Ä®jungta" + IDS_OFF "IÅ¡jungta" +} diff --git a/reactos/dll/win32/oleaut32/oleaut32_Nl.rc b/reactos/dll/win32/oleaut32/oleaut32_Nl.rc index 6affb2d638c..e2ae3dea380 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Nl.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Nl.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_No.rc b/reactos/dll/win32/oleaut32/oleaut32_No.rc index 7ca883c350d..1f99f7bbe56 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_No.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_No.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Pl.rc b/reactos/dll/win32/oleaut32/oleaut32_Pl.rc index 8c250cbbb9f..7d34796fd0b 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Pl.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Pl.rc @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_POLISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Pt.rc b/reactos/dll/win32/oleaut32/oleaut32_Pt.rc index 1cbd389209a..de008bbd0f9 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Pt.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Pt.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Ro.rc b/reactos/dll/win32/oleaut32/oleaut32_Ro.rc index 52421a8cca2..3a37a69ddef 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Ro.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Ro.rc @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL #pragma code_page(65001) @@ -30,5 +32,3 @@ STRINGTABLE DISCARDABLE IDS_ON "Activat" IDS_OFF "Dezactivat" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/oleaut32/oleaut32_Ru.rc b/reactos/dll/win32/oleaut32/oleaut32_Ru.rc index 194ca9e1a8e..e7c31073e33 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Ru.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Ru.rc @@ -18,14 +18,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + +/* UTF-8 */ +#pragma code_page(65001) + LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { - IDS_TRUE "Ïðàâäà" - IDS_FALSE "Ëîæü" - IDS_YES "Äà" - IDS_NO "Íåò" - IDS_ON "Âêëþ÷åíî" - IDS_OFF "Âûêëþ÷åíî" + IDS_TRUE "Правда" + IDS_FALSE "Ложь" + IDS_YES "Да" + IDS_NO "Ðет" + IDS_ON "Включено" + IDS_OFF "Выключено" } diff --git a/reactos/dll/win32/oleaut32/oleaut32_Si.rc b/reactos/dll/win32/oleaut32/oleaut32_Si.rc index 365d877045c..32a80adefb6 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Si.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Si.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + #pragma code_page(65001) LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT @@ -31,5 +33,3 @@ STRINGTABLE DISCARDABLE IDS_ON "VkljuÄeno" IDS_OFF "IzkljuÄeno" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/oleaut32/oleaut32_Sv.rc b/reactos/dll/win32/oleaut32/oleaut32_Sv.rc index 387b25eb0c4..4362a068bab 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Sv.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Sv.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Th.rc b/reactos/dll/win32/oleaut32/oleaut32_Th.rc index 22f01f74ee3..8fcf212a969 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Th.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Th.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_THAI, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Tr.rc b/reactos/dll/win32/oleaut32/oleaut32_Tr.rc index cc2f3e6f878..08d841a92a4 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Tr.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Tr.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/oleaut32/oleaut32_Uk.rc b/reactos/dll/win32/oleaut32/oleaut32_Uk.rc index 557b4ec3284..d51b06eb72c 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Uk.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Uk.rc @@ -1,7 +1,9 @@ /* * Ukrainian resources for oleaut32 * - * Copyright 2006 Artem Reznikov + * Copyright 2003 Jon Griffiths + * + * Copyright 2007 Artem Reznikov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -15,17 +17,22 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + +/* UTF-8 */ +#pragma code_page(65001) + LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { - IDS_TRUE "²ñòèíà" - IDS_FALSE "Íåïðàâäà" - IDS_YES "Òàê" - IDS_NO "ͳ" - IDS_ON "Ââ³ìêíåíî" - IDS_OFF "Âèìêíåíî" + IDS_TRUE "ІÑтина" + IDS_FALSE "Ðеправда" + IDS_YES "Так" + IDS_NO "ÐÑ–" + IDS_ON "Ввімкнено" + IDS_OFF "Вимкнено" } diff --git a/reactos/dll/win32/oleaut32/oleaut32_Zh.rc b/reactos/dll/win32/oleaut32/oleaut32_Zh.rc index 320c40ff5dd..bbb9e06433e 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Zh.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Zh.rc @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "resource.h" + /* Chinese text is encoded in UTF-8 */ #pragma code_page(65001) @@ -44,5 +46,3 @@ STRINGTABLE DISCARDABLE IDS_ON "é–‹" IDS_OFF "é—œ" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/oleaut32/oleaut32_ros.diff b/reactos/dll/win32/oleaut32/oleaut32_ros.diff deleted file mode 100644 index 81c42a6eb98..00000000000 --- a/reactos/dll/win32/oleaut32/oleaut32_ros.diff +++ /dev/null @@ -1,74 +0,0 @@ -Index: oleaut32_Ja.rc -=================================================================== ---- oleaut32_Ja.rc (revision 23782) -+++ oleaut32_Ja.rc (working copy) -@@ -0,0 +1,11 @@ -+LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT -+ -+STRINGTABLE DISCARDABLE -+{ -+ IDS_TRUE "True" -+ IDS_FALSE "False" -+ IDS_YES "‚Í‚¢" -+ IDS_NO "‚¢‚¢‚¦" -+ IDS_ON "ƒIƒ“" -+ IDS_OFF "ƒIƒt" -+} -Index: oleaut32_Uk.rc -=================================================================== ---- oleaut32_Uk.rc (revision 23782) -+++ oleaut32_Uk.rc (working copy) -@@ -0,0 +1,31 @@ -+/* -+ * Ukrainian resources for oleaut32 -+ * -+ * Copyright 2006 Artem Reznikov -+ * -+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -+ -+STRINGTABLE DISCARDABLE -+{ -+ IDS_TRUE "²ñòèíà" -+ IDS_FALSE "Íåïðàâäà" -+ IDS_YES "Òàê" -+ IDS_NO "ͳ" -+ IDS_ON "Ââ³ìêíåíî" -+ IDS_OFF "Âèìêíåíî" -+} -Index: oleaut32.rc -=================================================================== ---- oleaut32.rc (revision 23782) -+++ oleaut32.rc (working copy) -@@ -32,8 +32,9 @@ - #include "oleaut32_Es.rc" - #include "oleaut32_Cz.rc" - #include "oleaut32_Fr.rc" - #include "oleaut32_Hu.rc" - #include "oleaut32_It.rc" -+#include "oleaut32_Ja.rc" - #include "oleaut32_Ko.rc" - #include "oleaut32_Nl.rc" - #include "oleaut32_No.rc" -@@ -43,6 +45,7 @@ - #include "oleaut32_Sv.rc" - #include "oleaut32_Th.rc" - #include "oleaut32_Tr.rc" -+#include "oleaut32_Uk.rc" - - /* - * FIXME: diff --git a/reactos/dll/win32/oleaut32/olefont.c b/reactos/dll/win32/oleaut32/olefont.c index a9b2c047abf..df7de87bfc2 100644 --- a/reactos/dll/win32/oleaut32/olefont.c +++ b/reactos/dll/win32/oleaut32/olefont.c @@ -53,6 +53,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); #define FONTPERSIST_UNDERLINE 0x04 #define FONTPERSIST_STRIKETHROUGH 0x08 +static HDC olefont_hdc; /*********************************************************************** * List of the HFONTs it has given out, with each one having a separate @@ -62,10 +63,13 @@ typedef struct _HFONTItem { struct list entry; - /* Reference count for that instance of the class. */ - LONG ref; + /* Reference count of any IFont objects that own this hfont */ + LONG int_refs; - /* Contain the font associated with this object. */ + /* Total reference count of any refs held by the application obtained by AddRefHfont plus any internal refs */ + LONG total_refs; + + /* The font associated with this object. */ HFONT gdiFont; } HFONTItem, *PHFONTItem; @@ -88,6 +92,28 @@ static CRITICAL_SECTION_DEBUG OLEFontImpl_csHFONTLIST_debug = }; static CRITICAL_SECTION OLEFontImpl_csHFONTLIST = { &OLEFontImpl_csHFONTLIST_debug, -1, 0, 0, 0, 0 }; +static HDC get_dc(void) +{ + HDC hdc; + EnterCriticalSection(&OLEFontImpl_csHFONTLIST); + if(!olefont_hdc) + olefont_hdc = CreateCompatibleDC(NULL); + hdc = olefont_hdc; + LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); + return hdc; +} + +static void delete_dc(void) +{ + EnterCriticalSection(&OLEFontImpl_csHFONTLIST); + if(olefont_hdc) + { + DeleteDC(olefont_hdc); + olefont_hdc = NULL; + } + LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); +} + static void HFONTItem_Delete(PHFONTItem item) { DeleteObject(item->gdiFont); @@ -95,6 +121,123 @@ static void HFONTItem_Delete(PHFONTItem item) HeapFree(GetProcessHeap(), 0, item); } +/* Find hfont item entry in the list. Should be called while holding the crit sect */ +static HFONTItem *find_hfontitem(HFONT hfont) +{ + HFONTItem *item; + + LIST_FOR_EACH_ENTRY(item, &OLEFontImpl_hFontList, HFONTItem, entry) + { + if (item->gdiFont == hfont) + return item; + } + return NULL; +} + +/* Add an item to the list with one internal reference */ +static HRESULT add_hfontitem(HFONT hfont) +{ + HFONTItem *new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_item)); + + if(!new_item) return E_OUTOFMEMORY; + + new_item->int_refs = 1; + new_item->total_refs = 1; + new_item->gdiFont = hfont; + EnterCriticalSection(&OLEFontImpl_csHFONTLIST); + list_add_tail(&OLEFontImpl_hFontList,&new_item->entry); + LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); + return S_OK; +} + +static HRESULT inc_int_ref(HFONT hfont) +{ + HFONTItem *item; + HRESULT hr = S_FALSE; + + EnterCriticalSection(&OLEFontImpl_csHFONTLIST); + item = find_hfontitem(hfont); + + if(item) + { + item->int_refs++; + item->total_refs++; + hr = S_OK; + } + LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); + + return hr; +} + +/* decrements the internal ref of a hfont item. If both refs are zero it'll + remove the item from the list and delete the hfont */ +static HRESULT dec_int_ref(HFONT hfont) +{ + HFONTItem *item; + HRESULT hr = S_FALSE; + + EnterCriticalSection(&OLEFontImpl_csHFONTLIST); + item = find_hfontitem(hfont); + + if(item) + { + item->int_refs--; + item->total_refs--; + if(item->int_refs == 0 && item->total_refs == 0) + HFONTItem_Delete(item); + hr = S_OK; + } + LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); + + return hr; +} + +static HRESULT inc_ext_ref(HFONT hfont) +{ + HFONTItem *item; + HRESULT hr = S_FALSE; + + EnterCriticalSection(&OLEFontImpl_csHFONTLIST); + + item = find_hfontitem(hfont); + if(item) + { + item->total_refs++; + hr = S_OK; + } + LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); + + return hr; +} + +static HRESULT dec_ext_ref(HFONT hfont) +{ + HFONTItem *item; + HRESULT hr = S_FALSE; + + EnterCriticalSection(&OLEFontImpl_csHFONTLIST); + + item = find_hfontitem(hfont); + if(item) + { + if(--item->total_refs >= 0) hr = S_OK; + } + LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); + + return hr; +} + +static WCHAR *strdupW(const WCHAR* str) +{ + WCHAR *ret; + DWORD size = (strlenW(str) + 1) * sizeof(WCHAR); + + ret = HeapAlloc(GetProcessHeap(), 0, size); + if(ret) + memcpy(ret, str, size); + return ret; +} + /*********************************************************************** * Declaration of the implementation class for the IFont interface */ @@ -128,7 +271,7 @@ struct OLEFontImpl * Contain the font associated with this object. */ HFONT gdiFont; - + BOOL dirty; /* * Size ratio */ @@ -277,7 +420,8 @@ static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID) CONNECTDATA CD; HRESULT hres; - this->gdiFont = 0; + this->dirty = TRUE; + hres = IConnectionPoint_EnumConnections(this->pPropertyNotifyCP, &pEnum); if (SUCCEEDED(hres)) { @@ -402,7 +546,6 @@ static ULONG WINAPI OLEFontImpl_Release( { OLEFontImpl *this = (OLEFontImpl *)iface; ULONG ret; - PHFONTItem ptr, next; TRACE("(%p)->(ref=%d)\n", this, this->ref); /* Decrease the reference count for current interface */ @@ -412,13 +555,21 @@ static ULONG WINAPI OLEFontImpl_Release( if (ret == 0) { ULONG fontlist_refs = InterlockedDecrement(&ifont_cnt); - /* Check if all HFONT list refs are zero */ + + /* Final IFont object so destroy font cache */ if (fontlist_refs == 0) { + HFONTItem *item, *cursor2; + EnterCriticalSection(&OLEFontImpl_csHFONTLIST); - LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &OLEFontImpl_hFontList, HFONTItem, entry) - HFONTItem_Delete(ptr); + LIST_FOR_EACH_ENTRY_SAFE(item, cursor2, &OLEFontImpl_hFontList, HFONTItem, entry) + HFONTItem_Delete(item); LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); + delete_dc(); + } + else + { + dec_int_ref(this->gdiFont); } OLEFontImpl_Destroy(this); } @@ -426,6 +577,109 @@ static ULONG WINAPI OLEFontImpl_Release( return ret; } +typedef struct +{ + short orig_cs; + short avail_cs; +} enum_data; + +static int CALLBACK font_enum_proc(const LOGFONTW *elf, const TEXTMETRICW *ntm, DWORD type, LPARAM lp) +{ + enum_data *data = (enum_data*)lp; + + if(elf->lfCharSet == data->orig_cs) + { + data->avail_cs = data->orig_cs; + return 0; + } + if(data->avail_cs == -1) data->avail_cs = elf->lfCharSet; + return 1; +} + +static void realize_font(OLEFontImpl *This) +{ + if (This->dirty) + { + LOGFONTW logFont; + INT fontHeight; + WCHAR text_face[LF_FACESIZE]; + HDC hdc = get_dc(); + HFONT old_font; + TEXTMETRICW tm; + + text_face[0] = 0; + + if(This->gdiFont) + { + old_font = SelectObject(hdc, This->gdiFont); + GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face); + SelectObject(hdc, old_font); + dec_int_ref(This->gdiFont); + This->gdiFont = 0; + } + + memset(&logFont, 0, sizeof(LOGFONTW)); + + lstrcpynW(logFont.lfFaceName, This->description.lpstrName, LF_FACESIZE); + logFont.lfCharSet = This->description.sCharset; + + /* If the font name has been changed then enumerate all charsets + and pick one that'll result in the font specified being selected */ + if(text_face[0] && lstrcmpiW(text_face, This->description.lpstrName)) + { + enum_data data; + data.orig_cs = This->description.sCharset; + data.avail_cs = -1; + logFont.lfCharSet = DEFAULT_CHARSET; + EnumFontFamiliesExW(get_dc(), &logFont, font_enum_proc, (LPARAM)&data, 0); + if(data.avail_cs != -1) logFont.lfCharSet = data.avail_cs; + } + + + /* + * The height of the font returned by the get_Size property is the + * height of the font in points multiplied by 10000... Using some + * simple conversions and the ratio given by the application, it can + * be converted to a height in pixels. + * + * Standard ratio is 72 / 2540, or 18 / 635 in lowest terms. + * Ratio is applied here relative to the standard. + */ + + fontHeight = MulDiv( This->description.cySize.s.Lo, This->cyLogical*635, This->cyHimetric*18 ); + + + logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L) - 1 : + (-fontHeight/10000L); + logFont.lfItalic = This->description.fItalic; + logFont.lfUnderline = This->description.fUnderline; + logFont.lfStrikeOut = This->description.fStrikethrough; + logFont.lfWeight = This->description.sWeight; + logFont.lfOutPrecision = OUT_CHARACTER_PRECIS; + logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + logFont.lfQuality = DEFAULT_QUALITY; + logFont.lfPitchAndFamily = DEFAULT_PITCH; + + This->gdiFont = CreateFontIndirectW(&logFont); + This->dirty = FALSE; + + add_hfontitem(This->gdiFont); + + /* Fixup the name and charset properties so that they match the + selected font */ + old_font = SelectObject(get_dc(), This->gdiFont); + GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face); + if(lstrcmpiW(text_face, This->description.lpstrName)) + { + HeapFree(GetProcessHeap(), 0, This->description.lpstrName); + This->description.lpstrName = strdupW(text_face); + } + GetTextMetricsW(hdc, &tm); + This->description.sCharset = tm.tmCharSet; + SelectObject(hdc, old_font); + } +} + /************************************************************************ * OLEFontImpl_get_Name (IFont) * @@ -443,6 +697,8 @@ static HRESULT WINAPI OLEFontImpl_get_Name( if (pname==0) return E_POINTER; + if(this->dirty) realize_font(this); + if (this->description.lpstrName!=0) *pname = SysAllocString(this->description.lpstrName); else @@ -463,6 +719,9 @@ static HRESULT WINAPI OLEFontImpl_put_Name( OLEFontImpl *this = (OLEFontImpl *)iface; TRACE("(%p)->(%p)\n", this, name); + if (!name) + return CTL_E_INVALIDPROPERTYVALUE; + if (this->description.lpstrName==0) { this->description.lpstrName = HeapAlloc(GetProcessHeap(), @@ -504,6 +763,8 @@ static HRESULT WINAPI OLEFontImpl_get_Size( if (psize==0) return E_POINTER; + if(this->dirty) realize_font(this); + psize->s.Hi = 0; psize->s.Lo = this->description.cySize.s.Lo; @@ -545,6 +806,8 @@ static HRESULT WINAPI OLEFontImpl_get_Bold( if (pbold==0) return E_POINTER; + if(this->dirty) realize_font(this); + *pbold = this->description.sWeight > 550; return S_OK; @@ -584,6 +847,8 @@ static HRESULT WINAPI OLEFontImpl_get_Italic( if (pitalic==0) return E_POINTER; + if(this->dirty) realize_font(this); + *pitalic = this->description.fItalic; return S_OK; @@ -625,6 +890,8 @@ static HRESULT WINAPI OLEFontImpl_get_Underline( if (punderline==0) return E_POINTER; + if(this->dirty) realize_font(this); + *punderline = this->description.fUnderline; return S_OK; @@ -666,6 +933,8 @@ static HRESULT WINAPI OLEFontImpl_get_Strikethrough( if (pstrikethrough==0) return E_POINTER; + if(this->dirty) realize_font(this); + *pstrikethrough = this->description.fStrikethrough; return S_OK; @@ -707,6 +976,8 @@ static HRESULT WINAPI OLEFontImpl_get_Weight( if (pweight==0) return E_POINTER; + if(this->dirty) realize_font(this); + *pweight = this->description.sWeight; return S_OK; @@ -748,6 +1019,8 @@ static HRESULT WINAPI OLEFontImpl_get_Charset( if (pcharset==0) return E_POINTER; + if(this->dirty) realize_font(this); + *pcharset = this->description.sCharset; return S_OK; @@ -785,53 +1058,7 @@ static HRESULT WINAPI OLEFontImpl_get_hFont( if (phfont==NULL) return E_POINTER; - /* - * Realize the font if necessary - */ - if (this->gdiFont==0) -{ - LOGFONTW logFont; - INT fontHeight; - CY cySize; - PHFONTItem newEntry; - - /* - * The height of the font returned by the get_Size property is the - * height of the font in points multiplied by 10000... Using some - * simple conversions and the ratio given by the application, it can - * be converted to a height in pixels. - */ - IFont_get_Size(iface, &cySize); - - /* Standard ratio is 72 / 2540, or 18 / 635 in lowest terms. */ - /* Ratio is applied here relative to the standard. */ - fontHeight = MulDiv( cySize.s.Lo, this->cyLogical*635, this->cyHimetric*18 ); - - memset(&logFont, 0, sizeof(LOGFONTW)); - - logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 : - (-fontHeight/10000L); - logFont.lfItalic = this->description.fItalic; - logFont.lfUnderline = this->description.fUnderline; - logFont.lfStrikeOut = this->description.fStrikethrough; - logFont.lfWeight = this->description.sWeight; - logFont.lfCharSet = this->description.sCharset; - logFont.lfOutPrecision = OUT_CHARACTER_PRECIS; - logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; - logFont.lfQuality = DEFAULT_QUALITY; - logFont.lfPitchAndFamily = DEFAULT_PITCH; - strcpyW(logFont.lfFaceName,this->description.lpstrName); - - this->gdiFont = CreateFontIndirectW(&logFont); - - /* Add font to the cache */ - newEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(HFONTItem)); - newEntry->ref = 1; - newEntry->gdiFont = this->gdiFont; - EnterCriticalSection(&OLEFontImpl_csHFONTLIST); - list_add_tail(&OLEFontImpl_hFontList,&newEntry->entry); - LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); - } + if(this->dirty) realize_font(this); *phfont = this->gdiFont; TRACE("Returning %p\n", *phfont); @@ -848,12 +1075,8 @@ static HRESULT WINAPI OLEFontImpl_Clone( IFont** ppfont) { OLEFontImpl* newObject = 0; - LOGFONTW logFont; - INT fontHeight; - CY cySize; - PHFONTItem newEntry; - OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p)\n", this, ppfont); if (ppfont == NULL) @@ -879,36 +1102,12 @@ static HRESULT WINAPI OLEFontImpl_Clone( (1+strlenW(this->description.lpstrName))*2 ); strcpyW(newObject->description.lpstrName, this->description.lpstrName); - /* We need to clone the HFONT too. This is just cut & paste from above */ - IFont_get_Size(iface, &cySize); - fontHeight = MulDiv(cySize.s.Lo, this->cyLogical*635,this->cyHimetric*18); - memset(&logFont, 0, sizeof(LOGFONTW)); + /* Increment internal ref in hfont item list */ + if(newObject->gdiFont) inc_int_ref(newObject->gdiFont); - logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 : - (-fontHeight/10000L); - logFont.lfItalic = this->description.fItalic; - logFont.lfUnderline = this->description.fUnderline; - logFont.lfStrikeOut = this->description.fStrikethrough; - logFont.lfWeight = this->description.sWeight; - logFont.lfCharSet = this->description.sCharset; - logFont.lfOutPrecision = OUT_CHARACTER_PRECIS; - logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; - logFont.lfQuality = DEFAULT_QUALITY; - logFont.lfPitchAndFamily = DEFAULT_PITCH; - strcpyW(logFont.lfFaceName,this->description.lpstrName); - - newObject->gdiFont = CreateFontIndirectW(&logFont); - - /* Add font to the cache */ InterlockedIncrement(&ifont_cnt); - newEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(HFONTItem)); - newEntry->ref = 1; - newEntry->gdiFont = newObject->gdiFont; - EnterCriticalSection(&OLEFontImpl_csHFONTLIST); - list_add_tail(&OLEFontImpl_hFontList,&newEntry->entry); - LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); /* create new connection points */ newObject->pPropertyNotifyCP = NULL; @@ -1021,29 +1220,13 @@ static HRESULT WINAPI OLEFontImpl_AddRefHfont( IFont* iface, HFONT hfont) { - OLEFontImpl *this = (OLEFontImpl *)iface; - PHFONTItem ptr, next; - HRESULT hres = S_FALSE; /* assume not present */ + OLEFontImpl *this = (OLEFontImpl *)iface; - TRACE("(%p)->(%p)\n", this, hfont); + TRACE("(%p)->(%p)\n", this, hfont); - if (!hfont) - return E_INVALIDARG; + if (!hfont) return E_INVALIDARG; - /* Check of the hFont is already in the list */ - EnterCriticalSection(&OLEFontImpl_csHFONTLIST); - LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &OLEFontImpl_hFontList, HFONTItem, entry) - { - if (ptr->gdiFont == hfont) - { - ptr->ref++; - hres = S_OK; - break; - } - } - LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); - - return hres; + return inc_ext_ref(hfont); } /************************************************************************ @@ -1055,34 +1238,13 @@ static HRESULT WINAPI OLEFontImpl_ReleaseHfont( IFont* iface, HFONT hfont) { - OLEFontImpl *this = (OLEFontImpl *)iface; - PHFONTItem ptr, next; - HRESULT hres = S_FALSE; /* assume not present */ + OLEFontImpl *this = (OLEFontImpl *)iface; - TRACE("(%p)->(%p)\n", this, hfont); + TRACE("(%p)->(%p)\n", this, hfont); - if (!hfont) - return E_INVALIDARG; + if (!hfont) return E_INVALIDARG; - /* Check of the hFont is already in the list */ - EnterCriticalSection(&OLEFontImpl_csHFONTLIST); - LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &OLEFontImpl_hFontList, HFONTItem, entry) - { - if ((ptr->gdiFont == hfont) && ptr->ref) - { - /* Remove from cache and delete object if not referenced */ - if (!--ptr->ref) - { - if (ptr->gdiFont == this->gdiFont) - this->gdiFont = NULL; - } - hres = S_OK; - break; - } - } - LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); - - return hres; + return dec_ext_ref(hfont); } /************************************************************************ @@ -1675,7 +1837,7 @@ static HRESULT WINAPI OLEFontImpl_Load( this->description.lpstrName[len] = 0; /* Ensure use of this font causes a new one to be created @@@@ */ - DeleteObject(this->gdiFont); + dec_int_ref(this->gdiFont); this->gdiFont = 0; return S_OK; @@ -2247,6 +2409,7 @@ static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc) * Initializing all the other members. */ newObject->gdiFont = 0; + newObject->dirty = TRUE; newObject->cyLogical = 72L; newObject->cyHimetric = 2540L; newObject->pPropertyNotifyCP = NULL; @@ -2280,9 +2443,6 @@ static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc) HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName); - if (fontDesc->gdiFont!=0) - DeleteObject(fontDesc->gdiFont); - if (fontDesc->pPropertyNotifyCP) IConnectionPoint_Release(fontDesc->pPropertyNotifyCP); if (fontDesc->pFontEventsCP) diff --git a/reactos/dll/win32/oleaut32/olepicture.c b/reactos/dll/win32/oleaut32/olepicture.c index 052aa9a37f4..7a5bc29a4e5 100644 --- a/reactos/dll/win32/oleaut32/olepicture.c +++ b/reactos/dll/win32/oleaut32/olepicture.c @@ -684,7 +684,7 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc, break; case PICTYPE_ICON: FIXME("Not quite correct implementation of rendering icons...\n"); - DrawIcon(hdc,x,y,This->desc.u.icon.hicon); + DrawIconEx(hdc, x, y, This->desc.u.icon.hicon, cx, cy, 0, NULL, DI_NORMAL); break; case PICTYPE_METAFILE: diff --git a/reactos/dll/win32/oleaut32/regsvr.c b/reactos/dll/win32/oleaut32/regsvr.c index 3c5fabc0b20..12f64faa516 100644 --- a/reactos/dll/win32/oleaut32/regsvr.c +++ b/reactos/dll/win32/oleaut32/regsvr.c @@ -21,6 +21,7 @@ #include #include +#define COBJMACROS #include "windef.h" #include "winbase.h" #include "winuser.h" @@ -377,6 +378,32 @@ static LONG register_key_defvalueA( return res; } +/*********************************************************************** + * register_typelib + */ +static HRESULT register_typelib( const WCHAR *name ) +{ + static const WCHAR backslash[] = {'\\',0}; + HRESULT hr; + ITypeLib *typelib; + WCHAR *path; + DWORD len; + + len = GetSystemDirectoryW( NULL, 0 ) + strlenW( name ) + 1; + if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return E_OUTOFMEMORY; + GetSystemDirectoryW( path, len ); + strcatW( path, backslash ); + strcatW( path, name ); + hr = LoadTypeLib( path, &typelib ); + if (SUCCEEDED(hr)) + { + hr = RegisterTypeLib( typelib, path, NULL ); + ITypeLib_Release( typelib ); + } + HeapFree( GetProcessHeap(), 0, path ); + return hr; +} + /*********************************************************************** * coclass list */ @@ -386,9 +413,6 @@ static GUID const CLSID_RecordInfo = { static GUID const CLSID_OldFont = { 0x46763EE0, 0xCAB2, 0x11CE, {0x8C,0x20,0x00,0xAA,0x00,0x51,0xE5,0xD4} }; -static GUID const CLSID_PSFactoryBuffer = { - 0xB196B286, 0xBAB4, 0x101A, {0xB6,0x9C,0x00,0xAA,0x00,0x34,0x1D,0x07} }; - static struct regsvr_coclass const coclass_list[] = { { &CLSID_RecordInfo, "CLSID_RecordInfo", @@ -456,12 +480,6 @@ static struct regsvr_coclass const coclass_list[] = { "Obsolete Font", "OldFont" }, - { &CLSID_PSFactoryBuffer, - "PSFactoryBuffer", - NULL, - "oleaut32.dll", - "Both" - }, { NULL } /* list terminator */ }; @@ -470,7 +488,6 @@ static struct regsvr_coclass const coclass_list[] = { */ #define INTERFACE_ENTRY(interface, clsid16, clsid32) { &IID_##interface, #interface, NULL, sizeof(interface##Vtbl)/sizeof(void*), clsid16, clsid32 } #define LCL_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, NULL) -#define PSFAC_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, &CLSID_PSFactoryBuffer) #define CLSID_INTERFACE_ENTRY(interface,clsid) INTERFACE_ENTRY(interface, clsid, clsid) static struct regsvr_interface const interface_list[] = { @@ -481,43 +498,10 @@ static struct regsvr_interface const interface_list[] = { CLSID_INTERFACE_ENTRY(ITypeComp,&CLSID_PSTypeComp), CLSID_INTERFACE_ENTRY(ITypeInfo,&CLSID_PSTypeInfo), CLSID_INTERFACE_ENTRY(ITypeLib,&CLSID_PSTypeLib), - PSFAC_INTERFACE_ENTRY(IAdviseSinkEx), - PSFAC_INTERFACE_ENTRY(IClassFactory2), - PSFAC_INTERFACE_ENTRY(IConnectionPoint), - PSFAC_INTERFACE_ENTRY(IConnectionPointContainer), - PSFAC_INTERFACE_ENTRY(ICreateErrorInfo), - PSFAC_INTERFACE_ENTRY(IEnumConnectionPoints), - PSFAC_INTERFACE_ENTRY(IEnumConnections), - PSFAC_INTERFACE_ENTRY(IEnumOleUndoUnits), - PSFAC_INTERFACE_ENTRY(IErrorInfo), - PSFAC_INTERFACE_ENTRY(IErrorLog), - PSFAC_INTERFACE_ENTRY(IFont), - PSFAC_INTERFACE_ENTRY(IObjectWithSite), - PSFAC_INTERFACE_ENTRY(IOleControl), - PSFAC_INTERFACE_ENTRY(IOleControlSite), - PSFAC_INTERFACE_ENTRY(IOleInPlaceSiteEx), - PSFAC_INTERFACE_ENTRY(IOleParentUndoUnit), - PSFAC_INTERFACE_ENTRY(IOleUndoManager), - PSFAC_INTERFACE_ENTRY(IOleUndoUnit), - PSFAC_INTERFACE_ENTRY(IPerPropertyBrowsing), - PSFAC_INTERFACE_ENTRY(IPersistMemory), - PSFAC_INTERFACE_ENTRY(IPersistPropertyBag), - PSFAC_INTERFACE_ENTRY(IPersistPropertyBag2), - PSFAC_INTERFACE_ENTRY(IPersistStreamInit), - PSFAC_INTERFACE_ENTRY(IPicture), - PSFAC_INTERFACE_ENTRY(IPointerInactive), - PSFAC_INTERFACE_ENTRY(IPropertyBag), - PSFAC_INTERFACE_ENTRY(IPropertyBag2), - PSFAC_INTERFACE_ENTRY(IPropertyNotifySink), - PSFAC_INTERFACE_ENTRY(IPropertyPage), - PSFAC_INTERFACE_ENTRY(IPropertyPage2), - PSFAC_INTERFACE_ENTRY(IPropertyPageSite), - PSFAC_INTERFACE_ENTRY(IProvideClassInfo), - PSFAC_INTERFACE_ENTRY(IProvideClassInfo2), - PSFAC_INTERFACE_ENTRY(IProvideMultipleClassInfo), - PSFAC_INTERFACE_ENTRY(IQuickActivate), - PSFAC_INTERFACE_ENTRY(ISimpleFrameSite), - PSFAC_INTERFACE_ENTRY(ISpecifyPropertyPages), + INTERFACE_ENTRY(ISupportErrorInfo,NULL,&CLSID_PSDispatch), + INTERFACE_ENTRY(ITypeFactory,NULL,&CLSID_PSDispatch), + INTERFACE_ENTRY(ITypeInfo2,NULL,&CLSID_PSDispatch), + INTERFACE_ENTRY(ITypeLib2,NULL,&CLSID_PSDispatch), { NULL } /* list terminator */ }; @@ -538,6 +522,13 @@ HRESULT WINAPI DllRegisterServer(void) hr = register_coclasses(coclass_list); if (SUCCEEDED(hr)) hr = register_interfaces(interface_list); + if (SUCCEEDED(hr)) + { + const WCHAR stdole32W[] = {'s','t','d','o','l','e','3','2','.','t','l','b',0}; + const WCHAR stdole2W[] = {'s','t','d','o','l','e','2','.','t','l','b',0}; + hr = register_typelib( stdole2W ); + if (SUCCEEDED(hr)) hr = register_typelib( stdole32W ); + } return hr; } diff --git a/reactos/dll/win32/oleaut32/tmarshal.c b/reactos/dll/win32/oleaut32/tmarshal.c index 72358503f8d..26babdbcfde 100644 --- a/reactos/dll/win32/oleaut32/tmarshal.c +++ b/reactos/dll/win32/oleaut32/tmarshal.c @@ -615,8 +615,6 @@ serialize_param( vartype = VT_SAFEARRAY; switch (vartype) { - case VT_EMPTY: /* nothing. empty variant for instance */ - return S_OK; case VT_I8: case VT_UI8: case VT_R8: @@ -652,56 +650,23 @@ serialize_param( if (writeit) hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); return hres; - case VT_I4|VT_BYREF: - hres = S_OK; - if (debugout) TRACE_(olerelay)("&0x%x\n",*arg); - if (writeit) - hres = xbuf_add(buf,(LPBYTE)(DWORD*)*arg,sizeof(DWORD)); - /* do not dealloc at this time */ - return hres; case VT_VARIANT: { - TYPEDESC tdesc2; - VARIANT *vt = (VARIANT*)arg; - DWORD vttype = V_VT(vt); - - if (debugout) TRACE_(olerelay)("Vt(%s%s)(",debugstr_vt(vttype),debugstr_vf(vttype)); - tdesc2.vt = vttype; - if (writeit) { - hres = xbuf_add(buf,(LPBYTE)&vttype,sizeof(vttype)); - if (hres) return hres; - } - /* need to recurse since we need to free the stuff */ - hres = serialize_param(tinfo,writeit,debugout,dealloc,&tdesc2,(DWORD*)&(V_I4(vt)),buf); - if (debugout) TRACE_(olerelay)(")"); - return hres; - } - case VT_BSTR|VT_BYREF: { - if (debugout) TRACE_(olerelay)("[byref]'%s'", *(BSTR*)*arg ? relaystr(*((BSTR*)*arg)) : ""); - if (writeit) { - /* ptr to ptr to magic widestring, basically */ - BSTR *bstr = (BSTR *) *arg; - DWORD len; - if (!*bstr) { - /* -1 means "null string" which is equivalent to empty string */ - len = -1; - hres = xbuf_add(buf, (LPBYTE)&len,sizeof(DWORD)); - if (hres) return hres; - } else { - len = *((DWORD*)*bstr-1)/sizeof(WCHAR); - hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD)); - if (hres) return hres; - hres = xbuf_add(buf,(LPBYTE)*bstr,len * sizeof(WCHAR)); - if (hres) return hres; - } + if (debugout) TRACE_(olerelay)("Vt(%s%s)(",debugstr_vt(V_VT((VARIANT *)arg)),debugstr_vf(V_VT((VARIANT *)arg))); + if (writeit) + { + ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); + ULONG size = VARIANT_UserSize(&flags, buf->curoff, (VARIANT *)arg); + xbuf_resize(buf, size); + VARIANT_UserMarshal(&flags, buf->base + buf->curoff, (VARIANT *)arg); + buf->curoff = size; } - - if (dealloc && arg) { - BSTR *str = *((BSTR **)arg); - SysFreeString(*str); + if (dealloc) + { + ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); + VARIANT_UserFree(&flags, (VARIANT *)arg); } return S_OK; } - case VT_BSTR: { if (debugout) { if (*arg) @@ -709,25 +674,20 @@ serialize_param( else TRACE_(olerelay)(""); } - if (writeit) { - BSTR bstr = (BSTR)*arg; - DWORD len; - if (!bstr) { - len = -1; - hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD)); - if (hres) return hres; - } else { - len = *((DWORD*)bstr-1)/sizeof(WCHAR); - hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD)); - if (hres) return hres; - hres = xbuf_add(buf,(LPBYTE)bstr,len * sizeof(WCHAR)); - if (hres) return hres; - } - } - - if (dealloc && arg) - SysFreeString((BSTR)*arg); - return S_OK; + if (writeit) + { + ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); + ULONG size = BSTR_UserSize(&flags, buf->curoff, (BSTR *)arg); + xbuf_resize(buf, size); + BSTR_UserMarshal(&flags, buf->base + buf->curoff, (BSTR *)arg); + buf->curoff = size; + } + if (dealloc) + { + ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); + BSTR_UserFree(&flags, (BSTR *)arg); + } + return S_OK; } case VT_PTR: { DWORD cookie; @@ -888,12 +848,14 @@ serialize_param( if (debugout) TRACE_(olerelay)("(vt %s)",debugstr_vt(adesc->tdescElem.vt)); if (debugout) TRACE_(olerelay)("["); for (i=0;itdescElem, (DWORD*)((LPBYTE)arg+i*_xsize(&adesc->tdescElem, tinfo)), buf); + hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)), buf); if (hres) return hres; if (debugout && (ibase + buf->curoff, (LPSAFEARRAY *)arg); buf->curoff = size; } + if (dealloc) + { + ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); + LPSAFEARRAY_UserFree(&flags, (LPSAFEARRAY *)arg); + } return S_OK; } default: @@ -934,34 +901,15 @@ deserialize_param( while (1) { switch (vartype) { - case VT_EMPTY: - if (debugout) TRACE_(olerelay)("\n"); - return S_OK; - case VT_NULL: - if (debugout) TRACE_(olerelay)("\n"); - return S_OK; case VT_VARIANT: { - VARIANT *vt = (VARIANT*)arg; - - if (readit) { - DWORD vttype; - TYPEDESC tdesc2; - hres = xbuf_get(buf,(LPBYTE)&vttype,sizeof(vttype)); - if (hres) { - FIXME("vt type not read?\n"); - return hres; - } - memset(&tdesc2,0,sizeof(tdesc2)); - tdesc2.vt = vttype; - V_VT(vt) = vttype; - if (debugout) TRACE_(olerelay)("Vt(%s%s)(",debugstr_vt(vttype),debugstr_vf(vttype)); - hres = deserialize_param(tinfo, readit, debugout, alloc, &tdesc2, (DWORD*)&(V_I4(vt)), buf); - TRACE_(olerelay)(")"); - return hres; - } else { - VariantInit(vt); - return S_OK; + if (readit) + { + ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); + unsigned char *buffer; + buffer = VARIANT_UserUnmarshal(&flags, buf->base + buf->curoff, (VARIANT *)arg); + buf->curoff = buffer - buf->base; } + return S_OK; } case VT_I8: case VT_UI8: @@ -1006,76 +954,14 @@ deserialize_param( } if (debugout) TRACE_(olerelay)("%02x",*arg & 0xff); return hres; - case VT_I4|VT_BYREF: - hres = S_OK; - if (alloc) - *arg = (DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD)); - if (readit) { - hres = xbuf_get(buf,(LPBYTE)*arg,sizeof(DWORD)); - if (hres) ERR("Failed to read integer 4 byte\n"); - } - if (debugout) TRACE_(olerelay)("&0x%x",*(DWORD*)*arg); - return hres; - case VT_BSTR|VT_BYREF: { - BSTR **bstr = (BSTR **)arg; - WCHAR *str; - DWORD len; - - if (readit) { - hres = xbuf_get(buf,(LPBYTE)&len,sizeof(DWORD)); - if (hres) { - ERR("failed to read bstr klen\n"); - return hres; - } - if (len == -1) { - *bstr = CoTaskMemAlloc(sizeof(BSTR *)); - **bstr = NULL; - if (debugout) TRACE_(olerelay)(""); - } else { - str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR)); - hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR)); - if (hres) { - ERR("Failed to read BSTR.\n"); - HeapFree(GetProcessHeap(),0,str); - return hres; - } - *bstr = CoTaskMemAlloc(sizeof(BSTR *)); - **bstr = SysAllocStringLen(str,len); - if (debugout) TRACE_(olerelay)("%s",relaystr(str)); - HeapFree(GetProcessHeap(),0,str); - } - } else { - *bstr = NULL; - } - return S_OK; - } case VT_BSTR: { - WCHAR *str; - DWORD len; - - if (readit) { - hres = xbuf_get(buf,(LPBYTE)&len,sizeof(DWORD)); - if (hres) { - ERR("failed to read bstr klen\n"); - return hres; - } - if (len == -1) { - *arg = 0; - if (debugout) TRACE_(olerelay)(""); - } else { - str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR)); - hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR)); - if (hres) { - ERR("Failed to read BSTR.\n"); - HeapFree(GetProcessHeap(),0,str); - return hres; - } - *arg = (DWORD)SysAllocStringLen(str,len); - if (debugout) TRACE_(olerelay)("%s",relaystr(str)); - HeapFree(GetProcessHeap(),0,str); - } - } else { - *arg = 0; + if (readit) + { + ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); + unsigned char *buffer; + buffer = BSTR_UserUnmarshal(&flags, buf->base + buf->curoff, (BSTR *)arg); + buf->curoff = buffer - buf->base; + if (debugout) TRACE_(olerelay)("%s",debugstr_w(*(BSTR *)arg)); } return S_OK; } @@ -1247,6 +1133,7 @@ deserialize_param( if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it work?\n"); for (i=0;icDims;i++) arrsize *= adesc->rgbounds[i].cElements; + *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize); for (i=0;itdescElem, - (DWORD*)((LPBYTE)(arg)+i*_xsize(&adesc->tdescElem, tinfo)), + (DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)), buf ); return S_OK; @@ -2037,6 +1924,7 @@ static HRESULT WINAPI TMStubImpl_Invoke( LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf) { +#ifdef __i386__ int i; const FUNCDESC *fdesc; TMStubImpl *This = (TMStubImpl *)iface; @@ -2103,7 +1991,7 @@ TMStubImpl_Invoke( nrofargs = 0; for (i=0;icParams;i++) nrofargs += _argsize(&fdesc->lprgelemdescParam[i].tdesc, tinfo); - args = HeapAlloc(GetProcessHeap(),0,(nrofargs+1)*sizeof(DWORD)); + args = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(nrofargs+1)*sizeof(DWORD)); if (!args) { hres = E_OUTOFMEMORY; @@ -2201,6 +2089,10 @@ exit: TRACE("returning\n"); return hres; +#else + FIXME( "not implemented on non-i386\n" ); + return E_FAIL; +#endif } static LPRPCSTUBBUFFER WINAPI diff --git a/reactos/dll/win32/oleaut32/typelib.c b/reactos/dll/win32/oleaut32/typelib.c index 887c6bebc9e..445eac5c51e 100644 --- a/reactos/dll/win32/oleaut32/typelib.c +++ b/reactos/dll/win32/oleaut32/typelib.c @@ -552,7 +552,9 @@ HRESULT WINAPI RegisterTypeLib( LPOLESTR doc; /* Set the human-readable name of the typelib */ - if (SUCCEEDED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL))) + if (FAILED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL))) + res = E_FAIL; + else if (doc) { if (RegSetValueExW(key, NULL, 0, REG_SZ, (BYTE *)doc, (lstrlenW(doc)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS) @@ -560,8 +562,6 @@ HRESULT WINAPI RegisterTypeLib( SysFreeString(doc); } - else - res = E_FAIL; /* Make up the name of the typelib path subkey */ if (!get_lcid_subkey( attr->lcid, attr->syskind, tmp )) res = E_FAIL; @@ -1013,7 +1013,7 @@ typedef struct tagTLBFuncDesc int helpcontext; int HelpStringContext; BSTR HelpString; - BSTR Entry; /* if its Hiword==0, it numeric; -1 is not present*/ + BSTR Entry; /* if IS_INTRESOURCE true, it's numeric; if -1 it isn't present */ int ctCustData; TLBCustData * pCustData; /* linked list to cust data; */ struct tagTLBFuncDesc * next; @@ -1048,7 +1048,7 @@ typedef struct tagITypeInfoImpl const ITypeInfo2Vtbl *lpVtbl; const ITypeCompVtbl *lpVtblTypeComp; LONG ref; - BOOL no_free_data; /* don't free data structures */ + BOOL not_attached_to_typelib; TYPEATTR TypeAttr ; /* _lots_ of type information. */ ITypeLibImpl * pTypeLib; /* back pointer to typelib */ int index; /* index in this typelib; */ @@ -1085,6 +1085,7 @@ static const ITypeInfo2Vtbl tinfvt; static const ITypeCompVtbl tcompvt; static ITypeInfo2 * ITypeInfo_Constructor(void); +static void ITypeInfo_fnDestroy(ITypeInfoImpl *This); typedef struct tagTLBContext { @@ -1898,8 +1899,8 @@ MSFT_DoFuncs(TLBContext* pcx, { if ( pFuncRec->FKCCIC & 0x2000 ) { - if (HIWORD(pFuncRec->OptAttr[2]) != 0) - ERR("ordinal 0x%08x invalid, HIWORD != 0\n", pFuncRec->OptAttr[2]); + if (!IS_INTRESOURCE(pFuncRec->OptAttr[2])) + ERR("ordinal 0x%08x invalid, IS_INTRESOURCE is false\n", pFuncRec->OptAttr[2]); (*pptfd)->Entry = (BSTR)pFuncRec->OptAttr[2]; } else @@ -2492,7 +2493,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid, /* Find resource */ typeInfo = (NE_TYPEINFO *)(resTab + 2); - if (HIWORD(typeid) != 0) /* named type */ + if (!IS_INTRESOURCE(typeid)) /* named type */ { BYTE len = strlen( typeid ); while (typeInfo->type_id) @@ -2523,7 +2524,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid, found_type: nameInfo = (NE_NAMEINFO *)(typeInfo + 1); - if (HIWORD(resid) != 0) /* named resource */ + if (!IS_INTRESOURCE(resid)) /* named resource */ { BYTE len = strlen( resid ); for (count = typeInfo->count; count > 0; count--, nameInfo++) @@ -2947,7 +2948,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) if(td[1]<0) pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem.vt = td[0] & VT_TYPEMASK; else - pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem = stndTypeDesc[td[0]/8]; + pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem = cx.pLibInfo->pTypeDesc[td[0]/(2*sizeof(INT))]; pTypeLibImpl->pTypeDesc[i].u.lpadesc->cDims = td[2]; @@ -2991,6 +2992,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) name = TLB_Alloc(size+1); MSFT_Read(name, size, &cx, DO_NOT_SEEK); (*ppImpLib)->name = TLB_MultiByteToBSTR(name); + TLB_Free(name); MSFT_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx); offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & ~3; @@ -3676,6 +3678,9 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, if (pTITail->funcs_off != 0xffff) SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); + if (pTITail->impls_off != 0xffff) + SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup); + /* this is necessary to cope with MSFT typelibs that set cFuncs to the number * of dispinterface functions including the IDispatch ones, so * ITypeInfo::GetFuncDesc takes the real value for cFuncs from cbSizeVft */ @@ -3935,6 +3940,9 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) (*ppTypeInfoImpl)->TypeAttr.wTypeFlags = (pTIHeader->typeflags1 >> 3) | (pTIHeader->typeflags2 << 5); + if((*ppTypeInfoImpl)->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL) + (*ppTypeInfoImpl)->TypeAttr.typekind = TKIND_DISPATCH; + if((pTIHeader->typeflags1 & 7) != 2) FIXME_(typelib)("typeflags1 = %02x\n", pTIHeader->typeflags1); if(pTIHeader->typeflags3 != 2) @@ -4083,6 +4091,7 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface) TLBRefType *ref_type; void *cursor2; int i; + ITypeInfoImpl *pTI, *pTINext; /* remove cache entry */ if(This->path) @@ -4139,8 +4148,11 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface) TLB_Free(ref_type); } - if (This->pTypeInfo) /* can be NULL */ - ITypeInfo_Release((ITypeInfo*) This->pTypeInfo); + for (pTI = This->pTypeInfo; pTI; pTI = pTINext) + { + pTINext = pTI->next; + ITypeInfo_fnDestroy(pTI); + } HeapFree(GetProcessHeap(),0,This); return 0; } @@ -4835,8 +4847,29 @@ static HRESULT WINAPI ITypeLibComp_fnBindType( ITypeInfo ** ppTInfo, ITypeComp ** ppTComp) { - FIXME("(%s, %x, %p, %p): stub\n", debugstr_w(szName), lHash, ppTInfo, ppTComp); - return E_NOTIMPL; + ITypeLibImpl *This = impl_from_ITypeComp(iface); + ITypeInfoImpl *pTypeInfo; + + TRACE("(%s, %x, %p, %p)\n", debugstr_w(szName), lHash, ppTInfo, ppTComp); + + for (pTypeInfo = This->pTypeInfo; pTypeInfo; pTypeInfo = pTypeInfo->next) + { + /* FIXME: should use lHash to do the search */ + if (pTypeInfo->Name && !strcmpW(pTypeInfo->Name, szName)) + { + TRACE("returning %p\n", pTypeInfo); + *ppTInfo = (ITypeInfo *)&pTypeInfo->lpVtbl; + ITypeInfo_AddRef(*ppTInfo); + *ppTComp = (ITypeComp *)&pTypeInfo->lpVtblTypeComp; + ITypeComp_AddRef(*ppTComp); + return S_OK; + } + } + + TRACE("not found\n"); + *ppTInfo = NULL; + *ppTComp = NULL; + return S_OK; } static const ITypeCompVtbl tlbtcvt = @@ -4860,7 +4893,7 @@ static ITypeInfo2 * ITypeInfo_Constructor(void) { pTypeInfoImpl->lpVtbl = &tinfvt; pTypeInfoImpl->lpVtblTypeComp = &tcompvt; - pTypeInfoImpl->ref=1; + pTypeInfoImpl->ref = 0; pTypeInfoImpl->hreftype = -1; pTypeInfoImpl->TypeAttr.memidConstructor = MEMBERID_NIL; pTypeInfoImpl->TypeAttr.memidDestructor = MEMBERID_NIL; @@ -4902,12 +4935,78 @@ static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface) ITypeInfoImpl *This = (ITypeInfoImpl *)iface; ULONG ref = InterlockedIncrement(&This->ref); - ITypeLib2_AddRef((ITypeLib2*)This->pTypeLib); - TRACE("(%p)->ref is %u\n",This, ref); + + if (ref == 1 /* incremented from 0 */) + ITypeLib2_AddRef((ITypeLib2*)This->pTypeLib); + return ref; } +static void ITypeInfo_fnDestroy(ITypeInfoImpl *This) +{ + TLBFuncDesc *pFInfo, *pFInfoNext; + TLBVarDesc *pVInfo, *pVInfoNext; + TLBImplType *pImpl, *pImplNext; + + TRACE("destroying ITypeInfo(%p)\n",This); + + SysFreeString(This->Name); + This->Name = NULL; + + SysFreeString(This->DocString); + This->DocString = NULL; + + SysFreeString(This->DllName); + This->DllName = NULL; + + for (pFInfo = This->funclist; pFInfo; pFInfo = pFInfoNext) + { + INT i; + for(i = 0;i < pFInfo->funcdesc.cParams; i++) + { + ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[i]; + if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) + { + VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue); + TLB_Free(elemdesc->u.paramdesc.pparamdescex); + } + SysFreeString(pFInfo->pParamDesc[i].Name); + } + TLB_Free(pFInfo->funcdesc.lprgelemdescParam); + TLB_Free(pFInfo->pParamDesc); + TLB_FreeCustData(pFInfo->pCustData); + if (!IS_INTRESOURCE(pFInfo->Entry) && pFInfo->Entry != (BSTR)-1) + SysFreeString(pFInfo->Entry); + SysFreeString(pFInfo->HelpString); + SysFreeString(pFInfo->Name); + + pFInfoNext = pFInfo->next; + TLB_Free(pFInfo); + } + for (pVInfo = This->varlist; pVInfo; pVInfo = pVInfoNext) + { + if (pVInfo->vardesc.varkind == VAR_CONST) + { + VariantClear(pVInfo->vardesc.u.lpvarValue); + TLB_Free(pVInfo->vardesc.u.lpvarValue); + } + TLB_FreeCustData(pVInfo->pCustData); + SysFreeString(pVInfo->Name); + pVInfoNext = pVInfo->next; + TLB_Free(pVInfo); + } + for (pImpl = This->impltypelist; pImpl; pImpl = pImplNext) + { + TLB_FreeCustData(pImpl->pCustData); + pImplNext = pImpl->next; + TLB_Free(pImpl); + } + TLB_FreeCustData(This->pCustData); + + HeapFree(GetProcessHeap(), 0, This); +} + /* ITypeInfo::Release */ static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface) @@ -4917,82 +5016,15 @@ static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface) TRACE("(%p)->(%u)\n",This, ref); - if (ref) { - /* We don't release ITypeLib when ref=0 because - it means that function is called by ITypeLib2_Release */ - ITypeLib2_Release((ITypeLib2*)This->pTypeLib); - } else { - TLBFuncDesc *pFInfo, *pFInfoNext; - TLBVarDesc *pVInfo, *pVInfoNext; - TLBImplType *pImpl, *pImplNext; - - TRACE("destroying ITypeInfo(%p)\n",This); - - if (This->no_free_data) - goto finish_free; - - SysFreeString(This->Name); - This->Name = NULL; - - SysFreeString(This->DocString); - This->DocString = NULL; - - SysFreeString(This->DllName); - This->DllName = NULL; - - for (pFInfo = This->funclist; pFInfo; pFInfo = pFInfoNext) - { - INT i; - for(i = 0;i < pFInfo->funcdesc.cParams; i++) - { - ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[i]; - if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) - { - VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue); - TLB_Free(elemdesc->u.paramdesc.pparamdescex); - } - SysFreeString(pFInfo->pParamDesc[i].Name); - } - TLB_Free(pFInfo->funcdesc.lprgelemdescParam); - TLB_Free(pFInfo->pParamDesc); - TLB_FreeCustData(pFInfo->pCustData); - if (HIWORD(pFInfo->Entry) != 0 && pFInfo->Entry != (BSTR)-1) - SysFreeString(pFInfo->Entry); - SysFreeString(pFInfo->HelpString); - SysFreeString(pFInfo->Name); - - pFInfoNext = pFInfo->next; - TLB_Free(pFInfo); - } - for (pVInfo = This->varlist; pVInfo; pVInfo = pVInfoNext) - { - if (pVInfo->vardesc.varkind == VAR_CONST) - { - VariantClear(pVInfo->vardesc.u.lpvarValue); - TLB_Free(pVInfo->vardesc.u.lpvarValue); - } - TLB_FreeCustData(pVInfo->pCustData); - SysFreeString(pVInfo->Name); - pVInfoNext = pVInfo->next; - TLB_Free(pVInfo); - } - for(pImpl = This->impltypelist; pImpl; pImpl = pImplNext) - { - TLB_FreeCustData(pImpl->pCustData); - pImplNext = pImpl->next; - TLB_Free(pImpl); - } - TLB_FreeCustData(This->pCustData); - -finish_free: - if (This->next) - { - ITypeInfo_Release((ITypeInfo*)This->next); - } - - HeapFree(GetProcessHeap(),0,This); - return 0; + if (!ref) + { + BOOL not_attached_to_typelib = This->not_attached_to_typelib; + ITypeLib2_Release((ITypeLib2*)This->pTypeLib); + if (not_attached_to_typelib) + HeapFree(GetProcessHeap(), 0, This); + /* otherwise This will be freed when typelib is freed */ } + return ref; } @@ -5345,7 +5377,7 @@ static HRESULT TLB_AllocAndInitVarDesc( const VARDESC *src, VARDESC **dest_ptr ) hr = VariantCopy(dest->u.lpvarValue, src->u.lpvarValue); if (FAILED(hr)) { - SysFreeString((BSTR)dest_ptr); + SysFreeString((BSTR)dest); return hr; } } @@ -5476,8 +5508,7 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( */ if( This->TypeAttr.typekind != TKIND_DISPATCH) return E_INVALIDARG; - if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDISPATCHABLE && - This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL ) + if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL) { *pRefType = -1; } @@ -5600,6 +5631,41 @@ static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface, return DISP_E_UNKNOWNNAME; } + +#ifdef __i386__ + +extern DWORD CDECL call_method( void *func, int nb_args, const DWORD *args ); +__ASM_GLOBAL_FUNC( call_method, + "pushl %ebp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") + __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") + "movl %esp,%ebp\n\t" + __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") + "pushl %esi\n\t" + __ASM_CFI(".cfi_rel_offset %esi,-4\n\t") + "pushl %edi\n\t" + __ASM_CFI(".cfi_rel_offset %edi,-8\n\t") + "movl 12(%ebp),%edx\n\t" + "shll $2,%edx\n\t" + "jz 1f\n\t" + "subl %edx,%esp\n\t" + "andl $~15,%esp\n\t" + "movl 12(%ebp),%ecx\n\t" + "movl 16(%ebp),%esi\n\t" + "movl %esp,%edi\n\t" + "cld\n\t" + "rep; movsl\n" + "1:\tcall *8(%ebp)\n\t" + "leal -8(%ebp),%esp\n\t" + "popl %edi\n\t" + __ASM_CFI(".cfi_same_value %edi\n\t") + "popl %esi\n\t" + __ASM_CFI(".cfi_same_value %esi\n\t") + "popl %ebp\n\t" + __ASM_CFI(".cfi_def_cfa %esp,4\n\t") + __ASM_CFI(".cfi_same_value %ebp\n\t") + "ret" ) + /* ITypeInfo::Invoke * * Invokes a method, or accesses a property of an object, that implements the @@ -5618,106 +5684,8 @@ _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) { switch (callconv) { case CC_STDCALL: - - switch (nrargs) { - case 0: - res = func(); - break; - case 1: - res = func(args[0]); - break; - case 2: - res = func(args[0],args[1]); - break; - case 3: - res = func(args[0],args[1],args[2]); - break; - case 4: - res = func(args[0],args[1],args[2],args[3]); - break; - case 5: - res = func(args[0],args[1],args[2],args[3],args[4]); - break; - case 6: - res = func(args[0],args[1],args[2],args[3],args[4],args[5]); - break; - case 7: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6]); - break; - case 8: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]); - break; - case 9: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]); - break; - case 10: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9]); - break; - case 11: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10]); - break; - case 12: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11]); - break; - case 13: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12]); - break; - case 14: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13]); - break; - case 15: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14]); - break; - case 16: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15]); - break; - case 17: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16]); - break; - case 18: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17]); - break; - case 19: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18]); - break; - case 20: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19]); - break; - case 21: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20]); - break; - case 22: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21]); - break; - case 23: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22]); - break; - case 24: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23]); - break; - case 25: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24]); - break; - case 26: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25]); - break; - case 27: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26]); - break; - case 28: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27]); - break; - case 29: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27],args[28]); - break; - case 30: - res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27],args[28],args[29]); - break; - default: - FIXME("unsupported number of arguments %d in stdcall\n",nrargs); - res = -1; - break; - } + case CC_CDECL: + res = call_method( func, nrargs, args ); break; default: FIXME("unsupported calling convention %d\n",callconv); @@ -5754,6 +5722,7 @@ static int _dispargsize(VARTYPE vt) return 1; } } +#endif /* __i386__ */ static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt) { @@ -5933,6 +5902,7 @@ DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals, VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult) { +#ifdef __i386__ int argsize, argspos; UINT i; DWORD *args; @@ -5988,9 +5958,13 @@ DispCallFunc( V_VT(pvargResult) = vtReturn; V_UI4(pvargResult) = hres; } - HeapFree(GetProcessHeap(),0,args); return S_OK; +#else + FIXME( "(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d)): not implemented for this CPU\n", + pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult)); + return E_NOTIMPL; +#endif } #define INVBUF_ELEMENT_SIZE \ @@ -6177,7 +6151,8 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( else { VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams); - hres = VariantCopy(&missing_arg[i], src_arg); + if (wParamFlags & PARAMFLAG_FIN) + hres = VariantCopy(&missing_arg[i], src_arg); V_VARIANTREF(&rgvarg[i]) = &missing_arg[i]; } V_VT(&rgvarg[i]) = rgvt[i]; @@ -6215,8 +6190,10 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg)) { VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams); - V_VT(&missing_arg[i]) = V_VT(src_arg); - hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF); + if (wParamFlags & PARAMFLAG_FIN) + hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF); + else + V_VT(&missing_arg[i]) = rgvt[i] & ~VT_BYREF; V_BYREF(&rgvarg[i]) = &V_NONE(&missing_arg[i]); V_VT(&rgvarg[i]) = rgvt[i]; } @@ -6299,6 +6276,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( for (i = 0; i < func_desc->cParams; i++) { USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags; + VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams); if (wParamFlags & PARAMFLAG_FLCID) continue; @@ -6317,33 +6295,23 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( hres = VariantCopyInd(pVarResult, prgpvarg[i]); } - /* free data stored in varresult. Note that - * VariantClear doesn't do what we want because we are - * working with byref types. */ - /* FIXME: clear safearrays, bstrs, records and - * variants here too */ - if ((V_VT(prgpvarg[i]) == (VT_UNKNOWN | VT_BYREF)) || - (V_VT(prgpvarg[i]) == (VT_DISPATCH | VT_BYREF))) - { - if(*V_UNKNOWNREF(prgpvarg[i])) - IUnknown_Release(*V_UNKNOWNREF(prgpvarg[i])); - } - break; + VARIANT_ClearInd(prgpvarg[i]); } else if (vargs_converted < pDispParams->cArgs) { + VARIANTARG *arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted]; if (wParamFlags & PARAMFLAG_FOUT) { - VARIANTARG *arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted]; - - if ((rgvt[i] == VT_BYREF) && (V_VT(arg) != VT_BYREF)) + if ((rgvt[i] & VT_BYREF) && !(V_VT(arg) & VT_BYREF)) + { hres = VariantChangeType(arg, &rgvarg[i], 0, V_VT(arg)); - if (FAILED(hres)) - { - ERR("failed to convert param %d to vt %d\n", i, - V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted])); - break; + if (FAILED(hres)) + { + ERR("failed to convert param %d to vt %d\n", i, + V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted])); + break; + } } } else if (V_VT(prgpvarg[i]) == (VT_VARIANT | VT_ARRAY) && @@ -6382,6 +6350,8 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( if (wParamFlags & PARAMFLAG_FHASDEFAULT) VariantClear(&rgvarg[i]); } + + VariantClear(&missing_arg[i]); } if ((V_VT(&varresult) == VT_ERROR) && FAILED(V_ERROR(&varresult))) @@ -6601,7 +6571,7 @@ static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid if (pBstrDllName) *pBstrDllName = SysAllocString(This->DllName); - if (HIWORD(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) { + if (!IS_INTRESOURCE(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) { if (pBstrName) *pBstrName = SysAllocString(pFDesc->Entry); if (pwOrdinal) @@ -6689,20 +6659,18 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( *ppTInfo = (ITypeInfo*) pTypeInfoImpl; - /* we use data structures from This, so we need to keep a reference - * to it to stop it being destroyed and signal to the new instance to + /* the AddRef implicitly adds a reference to the parent typelib, which + * stops the copied data from being destroyed until the new typeinfo's + * refcount goes to zero, but we need to signal to the new instance to * not free its data structures when it is destroyed */ - pTypeInfoImpl->no_free_data = TRUE; - pTypeInfoImpl->next = This; - ITypeInfo_AddRef((ITypeInfo*) This); + pTypeInfoImpl->not_attached_to_typelib = TRUE; ITypeInfo_AddRef(*ppTInfo); result = S_OK; } else if ((hRefType != -1) && (hRefType & DISPATCH_HREF_MASK) && - (This->TypeAttr.typekind == TKIND_DISPATCH) && - (This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL)) + (This->TypeAttr.typekind == TKIND_DISPATCH)) { HREFTYPE href_dispatch = hRefType; result = ITypeInfoImpl_GetDispatchRefTypeInfo((ITypeInfo *)iface, &href_dispatch, ppTInfo); diff --git a/reactos/dll/win32/oleaut32/typelib.h b/reactos/dll/win32/oleaut32/typelib.h index 1fe8ecf7619..058c6a2db8c 100644 --- a/reactos/dll/win32/oleaut32/typelib.h +++ b/reactos/dll/win32/oleaut32/typelib.h @@ -155,6 +155,7 @@ typedef struct tagMSFT_TypeInfoBase { INT datatype2; /* if 0x8000, entry above is valid */ /* actually dunno */ /* else it is zero? */ + /* if interface: inheritance level | no of inherited funcs */ INT res18; /* always? 0 */ /*060*/ INT res19; /* always? -1 */ } MSFT_TypeInfoBase; @@ -413,7 +414,7 @@ typedef struct { /*0e*/ DWORD res0e; /* 0xffffffff */ /*12*/ WORD major_version; /* major version number */ /*14*/ WORD minor_version; /* minor version number */ -/*16*/ DWORD res16; /* 0xfffe0000 */ +/*16*/ DWORD res16; /* 0xfffe0000 or 0xfffc0000 (on dual interfaces?) */ /*1a*/ BYTE typeflags1;/* 0x02 | top 5 bits hold l5sbs of TYPEFLAGS */ /*1b*/ BYTE typeflags2;/* TYPEFLAGS >> 5 */ /*1c*/ BYTE typeflags3;/* 0x02*/ diff --git a/reactos/dll/win32/oleaut32/typelib2.c b/reactos/dll/win32/oleaut32/typelib2.c index 0f641d4103c..4544317a512 100644 --- a/reactos/dll/win32/oleaut32/typelib2.c +++ b/reactos/dll/win32/oleaut32/typelib2.c @@ -43,6 +43,7 @@ #include "windef.h" #include "winbase.h" #include "winnls.h" +#include "winreg.h" #include "winuser.h" #include "wine/unicode.h" @@ -116,6 +117,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(typelib2); /*================== Implementation Structures ===================================*/ +/* Used for storing cyclic list. Tail address is kept */ +typedef struct tagCyclicList { + struct tagCyclicList *next; + int indice; + int name; + + union { + int val; + int *data; + }u; +} CyclicList; + enum MSFT_segment_index { MSFT_SEG_TYPEINFO = 0, /* type information */ MSFT_SEG_IMPORTINFO, /* import information */ @@ -157,6 +170,9 @@ typedef struct tagICreateTypeLib2Impl char *typelib_segment_data[MSFT_SEG_MAX]; int typelib_segment_block_length[MSFT_SEG_MAX]; + int typelib_guids; /* Number of defined typelib guids */ + int typeinfo_guids; /* Number of defined typeinfo guids */ + INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */ INT *typelib_namehash_segment; @@ -181,13 +197,7 @@ typedef struct tagICreateTypeInfo2Impl ICreateTypeLib2Impl *typelib; MSFT_TypeInfoBase *typeinfo; - INT *typedata; - int typedata_allocated; - int typedata_length; - - int indices[42]; - int names[42]; - int offsets[42]; + struct tagCyclicList *typedata; /* tail of cyclic list */ int datawidth; @@ -388,6 +398,27 @@ static int ctl2_encode_name( return (length + 7) & ~3; } +/**************************************************************************** + * ctl2_decode_name + * + * Converts string stored in typelib data to unicode. + */ +static void ctl2_decode_name( + char *data, /* [I] String to be decoded */ + WCHAR **string) /* [O] Decoded string */ +{ + int i, length; + static WCHAR converted_string[0x104]; + + length = data[0]; + + for(i=0; i>= 2; + + for(i=0; itypekind = (This->typelib_header.nrtypeinfos - 1) << 16; typeinfo->memoffset = -1; /* should be EOF if no elements */ typeinfo->res2 = 0; - typeinfo->res3 = -1; + typeinfo->res3 = 0; typeinfo->res4 = 3; typeinfo->res5 = 0; typeinfo->cElement = 0; @@ -662,19 +716,20 @@ static int ctl2_alloc_string( * Failure: -1 (this is invariably an out of memory condition). */ static int ctl2_alloc_importinfo( - ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ - MSFT_ImpInfo *impinfo) /* [I] The import information to store. */ + ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ + MSFT_ImpInfo *impinfo) /* [I] The import information to store. */ { int offset; MSFT_ImpInfo *impinfo_space; - for (offset = 0; - offset < This->typelib_segdir[MSFT_SEG_IMPORTINFO].length; - offset += sizeof(MSFT_ImpInfo)) { - if (!memcmp(&(This->typelib_segment_data[MSFT_SEG_IMPORTINFO][offset]), - impinfo, sizeof(MSFT_ImpInfo))) { - return offset; - } + impinfo_space = (MSFT_ImpInfo*)&This->typelib_segment_data[MSFT_SEG_IMPORTINFO][0]; + for (offset=0; offsettypelib_segdir[MSFT_SEG_IMPORTINFO].length; + offset+=sizeof(MSFT_ImpInfo)) { + if(impinfo_space->oImpFile == impinfo->oImpFile + && impinfo_space->oGuid == impinfo->oGuid) + return offset; + + impinfo_space += 1; } impinfo->flags |= This->typelib_header.nimpinfos++; @@ -701,6 +756,7 @@ static int ctl2_alloc_importinfo( static int ctl2_alloc_importfile( ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ int guidoffset, /* [I] The offset to the GUID for the imported library. */ + LCID lcid, /* [I] The LCID of imported library. */ int major_version, /* [I] The major version number of the imported library. */ int minor_version, /* [I] The minor version number of the imported library. */ const WCHAR *filename) /* [I] The filename of the imported library. */ @@ -726,7 +782,7 @@ static int ctl2_alloc_importfile( importfile = (MSFT_ImpFile *)&This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset]; importfile->guid = guidoffset; - importfile->lcid = This->typelib_header.lcid2; + importfile->lcid = lcid; importfile->version = major_version | (minor_version << 16); memcpy(importfile->filename, encoded_string, length); @@ -1103,6 +1159,131 @@ static HRESULT ctl2_find_typeinfo_from_offset( return TYPE_E_ELEMENTNOTFOUND; } +/**************************************************************************** + * ctl2_add_default_value + * + * Adds default value of an argument + * + * RETURNS + * + * Success: S_OK + * Failure: Error code from winerror.h + */ +static HRESULT ctl2_add_default_value( + ICreateTypeLib2Impl *This, /* [I] The typelib to allocate data in */ + int *encoded_value, /* [O] The encoded default value or data offset */ + VARIANT *value, /* [I] Default value to be encoded */ + VARTYPE arg_type) /* [I] Argument type */ +{ + VARIANT v; + HRESULT hres; + + TRACE("%p %d %d\n", This, V_VT(value), arg_type); + + if(arg_type == VT_INT) + arg_type = VT_I4; + if(arg_type == VT_UINT) + arg_type = VT_UI4; + + v = *value; + if(V_VT(value) != arg_type) { + hres = VariantChangeType(&v, value, 0, arg_type); + if(FAILED(hres)) + return hres; + } + + /* Check if default value can be stored in encoded_value */ + switch(arg_type) { + int mask = 0; + case VT_I4: + case VT_UI4: + mask = 0x3ffffff; + if(V_UI4(&v)>0x3ffffff) + break; + case VT_I1: + case VT_UI1: + case VT_BOOL: + if(!mask) + mask = 0xff; + case VT_I2: + case VT_UI2: + if(!mask) + mask = 0xffff; + *encoded_value = (V_UI4(&v)&mask) | ((0x80+0x4*arg_type)<<24); + return S_OK; + } + + switch(arg_type) { + case VT_I4: + case VT_R4: + case VT_UI4: + case VT_INT: + case VT_UINT: + case VT_HRESULT: + case VT_PTR: { + /* Construct the data to be allocated */ + int data[2]; + data[0] = arg_type + (V_UI4(&v)<<16); + data[1] = (V_UI4(&v)>>16) + 0x57570000; + + /* Check if the data was already allocated */ + /* Currently the structures doesn't allow to do it in a nice way */ + for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-8; *encoded_value+=4) + if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8)) + return S_OK; + + /* Allocate the data */ + *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, 8, 0); + if(*encoded_value == -1) + return E_OUTOFMEMORY; + + memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8); + return S_OK; + } + case VT_BSTR: { + /* Construct the data */ + int i, len = (6+SysStringLen(V_BSTR(&v))+3) & ~0x3; + char *data = HeapAlloc(GetProcessHeap(), 0, len); + + if(!data) + return E_OUTOFMEMORY; + + *((unsigned short*)data) = arg_type; + *((unsigned*)(data+2)) = SysStringLen(V_BSTR(&v)); + for(i=0; itypelib_segdir[MSFT_SEG_CUSTDATA].length-len; *encoded_value+=4) + if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len)) { + HeapFree(GetProcessHeap(), 0, data); + return S_OK; + } + + /* Allocate the data */ + *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, len, 0); + if(*encoded_value == -1) { + HeapFree(GetProcessHeap(), 0, data); + return E_OUTOFMEMORY; + } + + memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len); + HeapFree(GetProcessHeap(), 0, data); + return S_OK; + } + default: + FIXME("Argument type not yet handled\n"); + return E_NOTIMPL; + } +} + /*================== ICreateTypeInfo2 Implementation ===================================*/ /****************************************************************************** @@ -1170,7 +1351,8 @@ static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface) if (!ref) { if (This->typelib) { ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)This->typelib); - This->typelib = NULL; + /* Keep This->typelib reference to make stored ICreateTypeInfo structure valid */ + /* This->typelib = NULL; */ } /* ICreateTypeLib2 frees all ICreateTypeInfos when it releases. */ @@ -1239,7 +1421,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, U guidoffset = ctl2_alloc_guid(This->typelib, &foo); if (guidoffset == -1) return E_OUTOFMEMORY; - fileoffset = ctl2_alloc_importfile(This->typelib, guidoffset, 2, 0, stdole2tlb); + fileoffset = ctl2_alloc_importfile(This->typelib, guidoffset, + This->typelib->typelib_header.lcid2, 2, 0, stdole2tlb); if (fileoffset == -1) return E_OUTOFMEMORY; foo.guid = IID_IDispatch; @@ -1340,10 +1523,10 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo( TRACE("(%p,%p,%p)\n", iface, pTInfo, phRefType); + if(!pTInfo || !phRefType) + return E_INVALIDARG; + /* - * If this is one of ours, we set *phRefType to the TYPEINFO offset of - * the referred TypeInfo. Otherwise, we presumably have more magic to do. - * * Unfortunately, we can't rely on the passed-in TypeInfo even having the * same internal structure as one of ours. It could be from another * implementation of ITypeInfo. So we need to do the following... @@ -1355,9 +1538,94 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo( } if (container == (ITypeLib *)&This->typelib->lpVtblTypeLib2) { + /* Process locally defined TypeInfo */ *phRefType = This->typelib->typelib_typeinfo_offsets[index]; } else { - FIXME("(%p,%p,%p), pTInfo from different typelib.\n", iface, pTInfo, phRefType); + static const WCHAR regkey[] = {'T','y','p','e','L','i','b','\\','{', + '%','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', + '}','\\','%','d','.','%','d','\\','0','\\','w','i','n','3','2',0}; + + WCHAR name[MAX_PATH], *p; + TLIBATTR *tlibattr; + TYPEATTR *typeattr; + MSFT_GuidEntry guid, *check_guid; + MSFT_ImpInfo impinfo; + int guid_offset, import_offset; + DWORD len; + HRESULT hres; + + /* Allocate container GUID */ + hres = ITypeLib_GetLibAttr(container, &tlibattr); + if(FAILED(hres)) + return hres; + + guid.guid = tlibattr->guid; + guid.hreftype = This->typelib->typelib_guids*12+2; + guid.next_hash = -1; + + guid_offset = ctl2_alloc_guid(This->typelib, &guid); + if(guid_offset == -1) { + ITypeLib_ReleaseTLibAttr(container, tlibattr); + return E_OUTOFMEMORY; + } + + check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset]; + if(check_guid->hreftype == guid.hreftype) + This->typelib->typelib_guids++; + + /* Get import file name */ + /* Check HKEY_CLASSES_ROOT\TypeLib\{GUID}\{Ver}\0\win32 */ + len = MAX_PATH; + sprintfW(name, regkey, guid.guid.Data1, guid.guid.Data2, + guid.guid.Data3, guid.guid.Data4[0], guid.guid.Data4[1], + guid.guid.Data4[2], guid.guid.Data4[3], guid.guid.Data4[4], + guid.guid.Data4[5], guid.guid.Data4[6], guid.guid.Data4[7], + tlibattr->wMajorVerNum, tlibattr->wMinorVerNum); + + if(RegGetValueW(HKEY_CLASSES_ROOT, name, NULL, RRF_RT_REG_SZ, NULL, name, &len)!=ERROR_SUCCESS + || (p=strrchrW(name, '\\'))==NULL) { + ERR("Error guessing typelib filename\n"); + ITypeLib_ReleaseTLibAttr(container, tlibattr); + return E_NOTIMPL; + } + memmove(name, p+1, strlenW(p)*sizeof(WCHAR)); + + /* Import file */ + import_offset = ctl2_alloc_importfile(This->typelib, guid_offset, + tlibattr->lcid, tlibattr->wMajorVerNum, tlibattr->wMinorVerNum, name); + ITypeLib_ReleaseTLibAttr(container, tlibattr); + + if(import_offset == -1) + return E_OUTOFMEMORY; + + /* Allocate referenced guid */ + hres = ITypeInfo_GetTypeAttr(pTInfo, &typeattr); + if(FAILED(hres)) + return hres; + + guid.guid = typeattr->guid; + guid.hreftype = This->typelib->typeinfo_guids*12+1; + guid.next_hash = -1; + ITypeInfo_ReleaseTypeAttr(pTInfo, typeattr); + + guid_offset = ctl2_alloc_guid(This->typelib, &guid); + if(guid_offset == -1) + return E_OUTOFMEMORY; + + check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset]; + if(check_guid->hreftype == guid.hreftype) + This->typelib->typeinfo_guids++; + + /* Allocate importinfo */ + impinfo.flags = ((This->typeinfo->typekind&0xf)<<24) | MSFT_IMPINFO_OFFSET_IS_GUID; + impinfo.oImpFile = import_offset; + impinfo.oGuid = guid_offset; + *phRefType = ctl2_alloc_importinfo(This->typelib, &impinfo)+1; + + if(!memcmp(&guid.guid, &IID_IDispatch, sizeof(GUID))) + This->typelib->typelib_header.dispatchpos = *phRefType; } ITypeLib_Release(container); @@ -1376,71 +1644,131 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( { ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; - int offset; + CyclicList *iter, *insert; int *typedata; - int i; + int i, num_defaults = 0; int decoded_size; + HRESULT hres; + + TRACE("(%p,%d,%p)\n", iface, index, pFuncDesc); + + if(!pFuncDesc || (pFuncDesc->memid>0x7fffffff && pFuncDesc->memid!=MEMBERID_NIL)) + return E_INVALIDARG; + + TRACE("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid, + pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind, + pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams, + pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes, + pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags); + + switch(This->typeinfo->typekind&0xf) { + case TKIND_MODULE: + if(pFuncDesc->funckind != FUNC_STATIC) + return TYPE_E_BADMODULEKIND; + break; + case TKIND_DISPATCH: + if(pFuncDesc->funckind != FUNC_DISPATCH) + return TYPE_E_BADMODULEKIND; + break; + default: + if(pFuncDesc->funckind != FUNC_PUREVIRTUAL) + return TYPE_E_BADMODULEKIND; + } + + if(This->typeinfo->cElementinvkind&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) && + !pFuncDesc->cParams) + return TYPE_E_INCONSISTENTPROPFUNCS; + + /* get number of arguments with default values specified */ + for (i = 0; i < pFuncDesc->cParams; i++) + if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) + num_defaults++; - FIXME("(%p,%d,%p), stub!\n", iface, index, pFuncDesc); - FIXME("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid, pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind, pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams, pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes, pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags); -/* FIXME("{%d, %d}\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt, pFuncDesc->lprgelemdescParam[1].tdesc.vt); */ -/* return E_OUTOFMEMORY; */ - if (!This->typedata) { - This->typedata = HeapAlloc(GetProcessHeap(), 0, 0x2000); - This->typedata[0] = 0; + This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList)); + if(!This->typedata) + return E_OUTOFMEMORY; + + This->typedata->next = This->typedata; + This->typedata->u.val = 0; } /* allocate type data space for us */ - offset = This->typedata[0]; - This->typedata[0] += 0x18 + (pFuncDesc->cParams * 12); - typedata = This->typedata + (offset >> 2) + 1; + insert = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList)); + if(!insert) + return E_OUTOFMEMORY; + insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[6])+sizeof(int[(num_defaults?4:3)])*pFuncDesc->cParams); + if(!insert->u.data) { + HeapFree(GetProcessHeap(), 0, insert); + return E_OUTOFMEMORY; + } /* fill out the basic type information */ - typedata[0] = (0x18 + (pFuncDesc->cParams * 12)) | (index << 16); + typedata = insert->u.data; + typedata[0] = 0x18 + pFuncDesc->cParams*(num_defaults?16:12); ctl2_encode_typedesc(This->typelib, &pFuncDesc->elemdescFunc.tdesc, &typedata[1], NULL, NULL, &decoded_size); typedata[2] = pFuncDesc->wFuncFlags; typedata[3] = ((sizeof(FUNCDESC) + decoded_size) << 16) | This->typeinfo->cbSizeVft; - typedata[4] = (index << 16) | (pFuncDesc->callconv << 8) | 9; + typedata[4] = (pFuncDesc->callconv << 8) | (pFuncDesc->invkind << 3) | pFuncDesc->funckind; + if(num_defaults) typedata[4] |= 0x1000; typedata[5] = pFuncDesc->cParams; /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */ /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */ typedata[3] += (sizeof(ELEMDESC) * pFuncDesc->cParams) << 16; + typedata[3] += (sizeof(PARAMDESCEX) * num_defaults) << 16; + /* add default values */ + if(num_defaults) { + for (i = 0; i < pFuncDesc->cParams; i++) + if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) { + hres = ctl2_add_default_value(This->typelib, typedata+6+i, + &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue, + pFuncDesc->lprgelemdescParam[i].tdesc.vt); + + if(FAILED(hres)) { + HeapFree(GetProcessHeap(), 0, insert->u.data); + HeapFree(GetProcessHeap(), 0, insert); + return hres; + } + } else + typedata[6+i] = 0xffffffff; + + num_defaults = pFuncDesc->cParams; + } + + /* add arguments */ for (i = 0; i < pFuncDesc->cParams; i++) { - ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc, &typedata[6+(i*3)], NULL, NULL, &decoded_size); - typedata[7+(i*3)] = -1; - typedata[8+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags; + ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc, + &typedata[6+num_defaults+(i*3)], NULL, NULL, &decoded_size); + typedata[7+num_defaults+(i*3)] = -1; + typedata[8+num_defaults+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags; typedata[3] += decoded_size << 16; - -#if 0 - /* FIXME: Doesn't work. Doesn't even come up with usable VTs for varDefaultValue. */ - if (pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) { - ctl2_alloc_custdata(This->typelib, &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue); - } -#endif } /* update the index data */ - This->indices[index] = ((0x6000 | This->typeinfo->cImplTypes) << 16) | index; - This->names[index] = -1; - This->offsets[index] = offset; + insert->indice = pFuncDesc->memid; + insert->name = -1; - /* ??? */ - if (!This->typeinfo->res2) This->typeinfo->res2 = 0x20; - This->typeinfo->res2 <<= 1; + /* insert type data to list */ + if(index == This->typeinfo->cElement) { + insert->next = This->typedata->next; + This->typedata->next = insert; + This->typedata = insert; + } else { + iter = This->typedata->next; + for(i=0; inext; - /* ??? */ - if (This->typeinfo->res3 == -1) This->typeinfo->res3 = 0; - This->typeinfo->res3 += 0x38; + insert->next = iter->next; + iter->next = insert; + } - /* ??? */ - if (index < 2) This->typeinfo->res2 += pFuncDesc->cParams << 4; - This->typeinfo->res3 += pFuncDesc->cParams << 4; - - /* adjust size of VTBL */ - This->typeinfo->cbSizeVft += 4; + /* update type data size */ + This->typedata->next->u.val += 0x18 + pFuncDesc->cParams*(num_defaults?16:12); /* Increment the number of function elements */ This->typeinfo->cElement += 1; @@ -1497,23 +1825,18 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType( } else if ((This->typeinfo->typekind & 15) == TKIND_DISPATCH) { FIXME("dispatch case unhandled.\n"); } else if ((This->typeinfo->typekind & 15) == TKIND_INTERFACE) { - if (This->typeinfo->cImplTypes) { - return (index == 1)? TYPE_E_BADMODULEKIND: TYPE_E_ELEMENTNOTFOUND; - } + if (This->typeinfo->cImplTypes && index==1) + return TYPE_E_BADMODULEKIND; - if (index != 0) return TYPE_E_ELEMENTNOTFOUND; + if( index != 0) return TYPE_E_ELEMENTNOTFOUND; - This->typeinfo->cImplTypes++; - - /* hacked values for IDispatch only, and maybe only for stdole. */ - This->typeinfo->cbSizeVft += 0x0c; /* hack */ - This->typeinfo->datatype1 = hRefType; - This->typeinfo->datatype2 = (3 << 16) | 1; /* ? */ + This->typeinfo->datatype1 = hRefType; } else { FIXME("AddImplType unsupported on typekind %d\n", This->typeinfo->typekind & 15); return E_OUTOFMEMORY; } + This->typeinfo->cImplTypes++; return S_OK; } @@ -1614,7 +1937,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( VARDESC* pVarDesc) { ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; - int offset; + + CyclicList *insert; INT *typedata; int var_datawidth; int var_alignment; @@ -1633,14 +1957,30 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( } if (!This->typedata) { - This->typedata = HeapAlloc(GetProcessHeap(), 0, 0x2000); - This->typedata[0] = 0; + This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList)); + if(!This->typedata) + return E_OUTOFMEMORY; + + This->typedata->next = This->typedata; + This->typedata->u.val = 0; } /* allocate type data space for us */ - offset = This->typedata[0]; - This->typedata[0] += 0x14; - typedata = This->typedata + (offset >> 2) + 1; + insert = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList)); + if(!insert) + return E_OUTOFMEMORY; + insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[5])); + if(!insert->u.data) { + HeapFree(GetProcessHeap(), 0, insert); + return E_OUTOFMEMORY; + } + + insert->next = This->typedata->next; + This->typedata->next = insert; + This->typedata = insert; + + This->typedata->next->u.val += 0x14; + typedata = This->typedata->u.data; /* fill out the basic type information */ typedata[0] = 0x14 | (index << 16); @@ -1648,9 +1988,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( typedata[3] = (sizeof(VARDESC) << 16) | 0; /* update the index data */ - This->indices[index] = 0x40000000 + index; - This->names[index] = -1; - This->offsets[index] = offset; + insert->indice = 0x40000000 + index; + insert->name = -1; /* figure out type widths and whatnot */ ctl2_encode_typedesc(This->typelib, &pVarDesc->elemdescVar.tdesc, @@ -1707,28 +2046,50 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames( UINT cNames) { ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; - - UINT i; - int offset; + CyclicList *iter = NULL, *iter2; + int offset, len, i=0; char *namedata; - FIXME("(%p,%d,%s,%d), stub!\n", iface, index, debugstr_w(*rgszNames), cNames); + TRACE("(%p %d %p %d)\n", iface, index, rgszNames, cNames); - offset = ctl2_alloc_name(This->typelib, rgszNames[0]); - This->names[index] = offset; + if(!rgszNames) + return E_INVALIDARG; - namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset; - namedata[9] &= ~0x10; - if (*((INT *)namedata) == -1) { - *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16]; + if(index >= This->typeinfo->cElement || !cNames) + return TYPE_E_ELEMENTNOTFOUND; + + len = ctl2_encode_name(This->typelib, rgszNames[0], &namedata); + for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) { + if(i == index) + iter = iter2; + else if(iter2->name!=-1 && !memcmp(namedata, + This->typelib->typelib_segment_data[MSFT_SEG_NAME]+iter2->name+8, len)) + return TYPE_E_AMBIGUOUSNAME; + + i++; } - for (i = 1; i < cNames; i++) { - /* FIXME: Almost certainly easy to break */ - int *paramdata = &This->typedata[This->offsets[index] >> 2]; + /* cNames == cParams for put or putref accessor, cParams+1 otherwise */ + if(cNames != iter->u.data[5] + ((iter->u.data[4]>>3)&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF) ? 0 : 1)) + return TYPE_E_ELEMENTNOTFOUND; + offset = ctl2_alloc_name(This->typelib, rgszNames[0]); + if(offset == -1) + return E_OUTOFMEMORY; + + iter->name = offset; + + namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset; + *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16]; + + if(iter->u.data[4]&0x1000) + len = iter->u.data[5]; + else + len = 0; + + for (i = 1; i < cNames; i++) { offset = ctl2_alloc_name(This->typelib, rgszNames[i]); - paramdata[(i * 3) + 5] = offset; + iter->u.data[(i*3) + 4 + len] = offset; } return S_OK; @@ -1745,7 +2106,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName( LPOLESTR szName) { ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; - int offset; + CyclicList *iter; + int offset, i; char *namedata; TRACE("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szName)); @@ -1766,8 +2128,12 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName( if ((This->typeinfo->typekind & 15) == TKIND_ENUM) { namedata[9] |= 0x20; } - This->names[index] = offset; + iter = This->typedata->next->next; + for(i=0; inext; + + iter->name = offset; return S_OK; } @@ -1912,8 +2278,161 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc( static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( ICreateTypeInfo2* iface) { - TRACE("(%p), stub!\n", iface); -/* return E_OUTOFMEMORY; */ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + CyclicList *iter, *iter2, **typedata; + HREFTYPE hreftype; + HRESULT hres; + int i; + + TRACE("(%p)\n", iface); + + if((This->typeinfo->typekind&0xf) == TKIND_COCLASS) + return S_OK; + + /* Validate inheritance */ + This->typeinfo->datatype2 = 0; + hreftype = This->typeinfo->datatype1; + + /* Process internally defined interfaces */ + for(i=0; itypelib->typelib_header.nrtypeinfos; i++) { + MSFT_TypeInfoBase *header; + + if(hreftype&1) + break; + + header = (MSFT_TypeInfoBase*)&(This->typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][hreftype]); + This->typeinfo->datatype2 += (header->cElement<<16) + 1; + hreftype = header->datatype1; + } + if(i == This->typelib->typelib_header.nrtypeinfos) + return TYPE_E_CIRCULARTYPE; + + /* Process externally defined interfaces */ + if(hreftype != -1) { + ITypeInfo *cur, *next; + TYPEATTR *typeattr; + + hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&next); + if(FAILED(hres)) + return hres; + + hres = ITypeInfo_GetRefTypeInfo(next, hreftype, &cur); + if(FAILED(hres)) + return hres; + + ITypeInfo_Release(next); + + while(1) { + hres = ITypeInfo_GetTypeAttr(cur, &typeattr); + if(FAILED(hres)) + return hres; + + if(!memcmp(&typeattr->guid, &IID_IDispatch, sizeof(IDispatch))) + This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE; + + This->typeinfo->datatype2 += (typeattr->cFuncs<<16) + 1; + ITypeInfo_ReleaseTypeAttr(cur, typeattr); + + hres = ITypeInfo_GetRefTypeOfImplType(cur, 0, &hreftype); + if(hres == TYPE_E_ELEMENTNOTFOUND) + break; + if(FAILED(hres)) + return hres; + + hres = ITypeInfo_GetRefTypeInfo(cur, hreftype, &next); + if(FAILED(hres)) + return hres; + + ITypeInfo_Release(cur); + cur = next; + } + } + + This->typeinfo->cbSizeVft = (This->typeinfo->datatype2>>16) * 4; + if(!This->typedata) + return S_OK; + + typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList*)*(This->typeinfo->cElement&0xffff)); + if(!typedata) + return E_OUTOFMEMORY; + + /* Assign IDs and VTBL entries */ + i = 0; + for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) { + /* Assign MEMBERID if MEMBERID_NIL was specified */ + if(iter->indice == MEMBERID_NIL) { + iter->indice = 0x60000000 + i + (This->typeinfo->datatype2<<16); + + for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) { + if(iter == iter2) continue; + if(iter2->indice == iter->indice) { + iter->indice = 0x5fffffff + This->typeinfo->cElement + i + (This->typeinfo->datatype2<<16); + + for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) { + if(iter == iter2) continue; + if(iter2->indice == iter->indice) + return E_ACCESSDENIED; + } + + break; + } + } + } + + typedata[i] = iter; + + iter->u.data[0] = (iter->u.data[0]&0xffff) | (i<<16); + + if((This->typeinfo->typekind&0xf) != TKIND_MODULE) { + iter->u.data[3] = (iter->u.data[3]&0xffff0000) | This->typeinfo->cbSizeVft; + This->typeinfo->cbSizeVft += 4; + } + + /* Construct a list of elements with the same memberid */ + iter->u.data[4] = (iter->u.data[4]&0xffff) | (i<<16); + for(iter2=This->typedata->next->next; iter2!=iter; iter2=iter2->next) { + if(iter->indice == iter2->indice) { + int v1, v2; + + v1 = iter->u.data[4] >> 16; + v2 = iter2->u.data[4] >> 16; + + iter->u.data[4] = (iter->u.data[4]&0xffff) | (v2<<16); + iter2->u.data[4] = (iter2->u.data[4]&0xffff) | (v1<<16); + break; + } + } + + i++; + } + + for(i=0; i<(This->typeinfo->cElement&0xffff); i++) { + if(typedata[i]->u.data[4]>>16 > i) { + int inv; + + inv = (typedata[i]->u.data[4]>>3) & 0xf; + i = typedata[i]->u.data[4] >> 16; + + while(i > typedata[i]->u.data[4]>>16) { + int invkind = (typedata[i]->u.data[4]>>3) & 0xf; + + if(inv & invkind) { + HeapFree(GetProcessHeap(), 0, typedata); + return TYPE_E_DUPLICATEID; + } + + i = typedata[i]->u.data[4] >> 16; + inv |= invkind; + } + + if(inv & INVOKE_FUNC) { + HeapFree(GetProcessHeap(), 0, typedata); + return TYPE_E_INCONSISTENTPROPFUNCS; + } + } + } + + HeapFree(GetProcessHeap(), 0, typedata); return S_OK; } @@ -2243,8 +2762,45 @@ static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr( ITypeInfo2* iface, TYPEATTR** ppTypeAttr) { - FIXME("(%p,%p), stub!\n", iface, ppTypeAttr); - return E_OUTOFMEMORY; + ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); + HRESULT hres; + + TRACE("(%p,%p)\n", iface, ppTypeAttr); + + if(!ppTypeAttr) + return E_INVALIDARG; + + hres = ICreateTypeInfo_LayOut((ICreateTypeInfo*)This); + if(FAILED(hres)) + return hres; + + *ppTypeAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TYPEATTR)); + if(!*ppTypeAttr) + return E_OUTOFMEMORY; + + if(This->typeinfo->posguid != -1) { + MSFT_GuidEntry *guid; + + guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][This->typeinfo->posguid]; + (*ppTypeAttr)->guid = guid->guid; + } + + (*ppTypeAttr)->lcid = This->typelib->typelib_header.lcid; + (*ppTypeAttr)->cbSizeInstance = This->typeinfo->size; + (*ppTypeAttr)->typekind = This->typeinfo->typekind&0xf; + (*ppTypeAttr)->cFuncs = This->typeinfo->cElement&0xffff; + (*ppTypeAttr)->cVars = This->typeinfo->cElement>>16; + (*ppTypeAttr)->cImplTypes = This->typeinfo->cImplTypes; + (*ppTypeAttr)->cbSizeVft = This->typeinfo->cbSizeVft; + (*ppTypeAttr)->cbAlignment = (This->typeinfo->typekind>>11) & 0x1f; + (*ppTypeAttr)->wTypeFlags = This->typeinfo->flags; + (*ppTypeAttr)->wMajorVerNum = This->typeinfo->version&0xffff; + (*ppTypeAttr)->wMinorVerNum = This->typeinfo->version>>16; + + if((*ppTypeAttr)->typekind == TKIND_ALIAS) + FIXME("TKIND_ALIAS handling not implemented\n"); + + return S_OK; } /****************************************************************************** @@ -2314,8 +2870,35 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeOfImplType( UINT index, HREFTYPE* pRefType) { - FIXME("(%p,%d,%p), stub!\n", iface, index, pRefType); - return E_OUTOFMEMORY; + ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); + MSFT_RefRecord *ref; + int offset; + + TRACE("(%p,%d,%p)\n", iface, index, pRefType); + + if(!pRefType) + return E_INVALIDARG; + + if(index == -1) { + FIXME("Dual interfaces not handled yet\n"); + return E_NOTIMPL; + } + + if(index >= This->typeinfo->cImplTypes) + return TYPE_E_ELEMENTNOTFOUND; + + if((This->typeinfo->typekind&0xf) == TKIND_INTERFACE) { + *pRefType = This->typeinfo->datatype1 + 2; + return S_OK; + } + + offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index); + if(offset == -1) + return TYPE_E_ELEMENTNOTFOUND; + + ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset]; + *pRefType = ref->reftype; + return S_OK; } /****************************************************************************** @@ -2328,8 +2911,30 @@ static HRESULT WINAPI ITypeInfo2_fnGetImplTypeFlags( UINT index, INT* pImplTypeFlags) { - FIXME("(%p,%d,%p), stub!\n", iface, index, pImplTypeFlags); - return E_OUTOFMEMORY; + ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); + int offset; + MSFT_RefRecord *ref; + + TRACE("(%p,%d,%p)\n", iface, index, pImplTypeFlags); + + if(!pImplTypeFlags) + return E_INVALIDARG; + + if(index >= This->typeinfo->cImplTypes) + return TYPE_E_ELEMENTNOTFOUND; + + if((This->typeinfo->typekind&0xf) != TKIND_COCLASS) { + *pImplTypeFlags = 0; + return S_OK; + } + + offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index); + if(offset == -1) + return TYPE_E_ELEMENTNOTFOUND; + + ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset]; + *pImplTypeFlags = ref->flags; + return S_OK; } /****************************************************************************** @@ -2410,8 +3015,54 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo( HREFTYPE hRefType, ITypeInfo** ppTInfo) { - FIXME("(%p,%d,%p), stub!\n", iface, hRefType, ppTInfo); - return E_OUTOFMEMORY; + ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); + + TRACE("(%p,%d,%p)\n", iface, hRefType, ppTInfo); + + if(!ppTInfo) + return E_INVALIDARG; + + if(hRefType&1) { + ITypeLib *tl; + MSFT_ImpInfo *impinfo; + MSFT_ImpFile *impfile; + MSFT_GuidEntry *guid; + WCHAR *filename; + HRESULT hres; + + if((hRefType&(~0x3)) >= This->typelib->typelib_segdir[MSFT_SEG_IMPORTINFO].length) + return E_FAIL; + + impinfo = (MSFT_ImpInfo*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO][hRefType&(~0x3)]; + impfile = (MSFT_ImpFile*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][impinfo->oImpFile]; + guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo->oGuid]; + + ctl2_decode_string(impfile->filename, &filename); + + hres = LoadTypeLib(filename, &tl); + if(FAILED(hres)) + return hres; + + hres = ITypeLib_GetTypeInfoOfGuid(tl, &guid->guid, ppTInfo); + + ITypeLib_Release(tl); + return hres; + } else { + ICreateTypeInfo2Impl *iter; + int i = 0; + + for(iter=This->typelib->typeinfos; iter; iter=iter->next_typeinfo) { + if(This->typelib->typelib_typeinfo_offsets[i] == (hRefType&(~0x3))) { + *ppTInfo = (ITypeInfo*)&iter->lpVtblTypeInfo2; + + ITypeLib_AddRef(*ppTInfo); + return S_OK; + } + i++; + } + } + + return E_FAIL; } /****************************************************************************** @@ -2488,7 +3139,9 @@ static void WINAPI ITypeInfo2_fnReleaseTypeAttr( ITypeInfo2* iface, TYPEATTR* pTypeAttr) { - FIXME("(%p,%p), stub!\n", iface, pTypeAttr); + TRACE("(%p,%p)\n", iface, pTypeAttr); + + HeapFree(GetProcessHeap(), 0, pTypeAttr); } /****************************************************************************** @@ -3049,7 +3702,21 @@ static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface) while (This->typeinfos) { ICreateTypeInfo2Impl *typeinfo = This->typeinfos; This->typeinfos = typeinfo->next_typeinfo; - HeapFree(GetProcessHeap(), 0, typeinfo->typedata); + if(typeinfo->typedata) { + CyclicList *iter, *rem; + + rem = typeinfo->typedata->next; + typeinfo->typedata->next = NULL; + iter = rem->next; + HeapFree(GetProcessHeap(), 0, rem); + + while(iter) { + rem = iter; + iter = iter->next; + HeapFree(GetProcessHeap(), 0, rem->u.data); + HeapFree(GetProcessHeap(), 0, rem); + } + } HeapFree(GetProcessHeap(), 0, typeinfo); } @@ -3073,9 +3740,14 @@ static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo( ICreateTypeInfo **ppCTInfo) { ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + char *name; TRACE("(%p,%s,%d,%p)\n", iface, debugstr_w(szName), tkind, ppCTInfo); + ctl2_encode_name(This, szName, &name); + if(ctl2_find_name(This, name) != -1) + return TYPE_E_NAMECONFLICT; + *ppCTInfo = (ICreateTypeInfo *)ICreateTypeInfo2_Constructor(This, szName, tkind); if (!*ppCTInfo) return E_OUTOFMEMORY; @@ -3260,17 +3932,25 @@ static int ctl2_write_segment(ICreateTypeLib2Impl *This, HANDLE hFile, int segme return -1; } -static void ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize) +static HRESULT ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize) { ICreateTypeInfo2Impl *typeinfo; + HRESULT hres; for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { - typeinfo->typeinfo->memoffset = filesize; - if (typeinfo->typedata) { - ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo); - filesize += typeinfo->typedata[0] + ((typeinfo->typeinfo->cElement >> 16) * 12) + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4; - } + typeinfo->typeinfo->memoffset = filesize; + + hres = ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo); + if(FAILED(hres)) + return hres; + + if (typeinfo->typedata) + filesize += typeinfo->typedata->next->u.val + + ((typeinfo->typeinfo->cElement >> 16) * 12) + + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4; } + + return S_OK; } static int ctl2_finalize_segment(ICreateTypeLib2Impl *This, int filepos, int segment) @@ -3289,12 +3969,26 @@ static void ctl2_write_typeinfos(ICreateTypeLib2Impl *This, HANDLE hFile) ICreateTypeInfo2Impl *typeinfo; for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { + CyclicList *iter; + int offset = 0; + if (!typeinfo->typedata) continue; - ctl2_write_chunk(hFile, typeinfo->typedata, typeinfo->typedata[0] + 4); - ctl2_write_chunk(hFile, typeinfo->indices, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4); - ctl2_write_chunk(hFile, typeinfo->names, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4); - ctl2_write_chunk(hFile, typeinfo->offsets, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4); + iter = typeinfo->typedata->next; + ctl2_write_chunk(hFile, &iter->u.val, sizeof(int)); + for(iter=iter->next; iter!=typeinfo->typedata->next; iter=iter->next) + ctl2_write_chunk(hFile, iter->u.data, iter->u.data[0] & 0xffff); + + for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) + ctl2_write_chunk(hFile, &iter->indice, sizeof(int)); + + for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) + ctl2_write_chunk(hFile, &iter->name, sizeof(int)); + + for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) { + ctl2_write_chunk(hFile, &offset, sizeof(int)); + offset += iter->u.data[0] & 0xffff; + } } } @@ -3310,6 +4004,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface) int retval; int filepos; HANDLE hFile; + HRESULT hres; TRACE("(%p)\n", iface); @@ -3324,9 +4019,9 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface) filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEINFO); filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUIDHASH); filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUID); + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_REFERENCES); filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTINFO); filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTFILES); - filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_REFERENCES); filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAMEHASH); filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAME); filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_STRING); @@ -3335,7 +4030,11 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface) filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATA); filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATAGUID); - ctl2_finalize_typeinfos(This, filepos); + hres = ctl2_finalize_typeinfos(This, filepos); + if(FAILED(hres)) { + CloseHandle(hFile); + return hres; + } if (!ctl2_write_chunk(hFile, &This->typelib_header, sizeof(This->typelib_header))) return retval; if (This->typelib_header.varflags & HELPDLLFLAG) @@ -3345,9 +4044,9 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface) if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEINFO )) return retval; if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUIDHASH )) return retval; if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUID )) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_REFERENCES )) return retval; if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTINFO )) return retval; if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTFILES )) return retval; - if (!ctl2_write_segment(This, hFile, MSFT_SEG_REFERENCES )) return retval; if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAMEHASH )) return retval; if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAME )) return retval; if (!ctl2_write_segment(This, hFile, MSFT_SEG_STRING )) return retval; @@ -3360,8 +4059,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface) if (!CloseHandle(hFile)) return retval; - retval = S_OK; - return retval; + return S_OK; } @@ -3596,9 +4294,28 @@ static HRESULT WINAPI ITypeLib2_fnGetLibAttr( { ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - FIXME("(%p,%p), stub!\n", This, ppTLibAttr); + TRACE("(%p,%p)\n", This, ppTLibAttr); - return E_OUTOFMEMORY; + if(!ppTLibAttr) + return E_INVALIDARG; + + *ppTLibAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TLIBATTR)); + if(!*ppTLibAttr) + return E_OUTOFMEMORY; + + if(This->typelib_header.posguid != -1) { + MSFT_GuidEntry *guid; + + guid = (MSFT_GuidEntry*)&This->typelib_segment_data[MSFT_SEG_GUID][This->typelib_header.posguid]; + (*ppTLibAttr)->guid = guid->guid; + } + + (*ppTLibAttr)->lcid = This->typelib_header.lcid; + (*ppTLibAttr)->syskind = This->typelib_header.varflags&0x3; + (*ppTLibAttr)->wMajorVerNum = This->typelib_header.version&0xffff; + (*ppTLibAttr)->wMinorVerNum = This->typelib_header.version>>16; + (*ppTLibAttr)->wLibFlags = This->typelib_header.flags; + return S_OK; } /****************************************************************************** @@ -3631,10 +4348,71 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation( BSTR* pBstrHelpFile) { ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); + WCHAR *string; - FIXME("(%p,%d,%p,%p,%p,%p), stub!\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); + TRACE("(%p,%d,%p,%p,%p,%p)\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); - return E_OUTOFMEMORY; + if(index != -1) { + ICreateTypeInfo2Impl *iter; + + for(iter=This->typeinfos; iter!=NULL && index!=0; iter=iter->next_typeinfo) + index--; + + if(!iter) + return TYPE_E_ELEMENTNOTFOUND; + + return ITypeInfo_GetDocumentation((ITypeInfo*)iter->lpVtblTypeInfo2, + -1, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); + } + + if(pBstrName) { + if(This->typelib_header.NameOffset == -1) + *pBstrName = NULL; + else { + MSFT_NameIntro *name = (MSFT_NameIntro*)&This-> + typelib_segment_data[MSFT_SEG_NAME][This->typelib_header.NameOffset]; + + ctl2_decode_name((char*)&name->namelen, &string); + + *pBstrName = SysAllocString(string); + if(!*pBstrName) + return E_OUTOFMEMORY; + } + } + + if(pBstrDocString) { + if(This->typelib_header.helpstring == -1) + *pBstrDocString = NULL; + else { + ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpstring], &string); + + *pBstrDocString = SysAllocString(string); + if(!*pBstrDocString) { + if(pBstrName) SysFreeString(*pBstrName); + return E_OUTOFMEMORY; + } + } + } + + if(pdwHelpContext) + *pdwHelpContext = This->typelib_header.helpcontext; + + if(pBstrHelpFile) { + if(This->typelib_header.helpfile == -1) + *pBstrHelpFile = NULL; + else { + ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpfile], &string); + + *pBstrHelpFile = SysAllocString(string); + if(!*pBstrHelpFile) { + if(pBstrName) SysFreeString(*pBstrName); + if(pBstrDocString) SysFreeString(*pBstrDocString); + return E_OUTOFMEMORY; + } + } + } + + return S_OK; } /****************************************************************************** @@ -3702,9 +4480,9 @@ static void WINAPI ITypeLib2_fnReleaseTLibAttr( ITypeLib2 * iface, TLIBATTR* pTLibAttr) { - ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); + TRACE("(%p,%p)\n", iface, pTLibAttr); - FIXME("(%p,%p), stub!\n", This, pTLibAttr); + HeapFree(GetProcessHeap(), 0, pTLibAttr); } /****************************************************************************** diff --git a/reactos/dll/win32/oleaut32/usrmarshal.c b/reactos/dll/win32/oleaut32/usrmarshal.c index 3172ebad5fc..402794ce333 100644 --- a/reactos/dll/win32/oleaut32/usrmarshal.c +++ b/reactos/dll/win32/oleaut32/usrmarshal.c @@ -256,20 +256,21 @@ static unsigned int get_type_alignment(ULONG *pFlags, VARTYPE vt) static unsigned interface_variant_size(const ULONG *pFlags, REFIID riid, IUnknown *punk) { - ULONG size; - HRESULT hr; - /* find the buffer size of the marshalled dispatch interface */ - hr = CoGetMarshalSizeMax(&size, riid, punk, LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL); - if (FAILED(hr)) { - if (!punk) - WARN("NULL dispatch pointer\n"); - else - ERR("Dispatch variant buffer size calculation failed, HRESULT=0x%x\n", hr); - return 0; - } - size += sizeof(ULONG); /* we have to store the buffersize in the stream */ - TRACE("wire-size extra of dispatch variant is %d\n", size); - return size; + ULONG size = 0; + HRESULT hr; + + if (punk) + { + hr = CoGetMarshalSizeMax(&size, riid, punk, LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL); + if (FAILED(hr)) + { + ERR("interface variant buffer size calculation failed, HRESULT=0x%x\n", hr); + return 0; + } + } + size += sizeof(ULONG); /* we have to store the buffersize in the stream */ + TRACE("wire-size extra of interface variant is %d\n", size); + return size; } static ULONG wire_extra_user_size(ULONG *pFlags, ULONG Start, VARIANT *pvar) @@ -322,6 +323,12 @@ static unsigned char* interface_variant_marshal(const ULONG *pFlags, unsigned ch TRACE("pFlags=%d, Buffer=%p, pUnk=%p\n", *pFlags, Buffer, punk); + if(!punk) + { + memset(Buffer, 0, sizeof(ULONG)); + return Buffer + sizeof(ULONG); + } + oldpos = Buffer; /* CoMarshalInterface needs a stream, whereas at this level we are operating in terms of buffers. @@ -378,6 +385,12 @@ static unsigned char *interface_variant_unmarshal(const ULONG *pFlags, unsigned memcpy(&size, Buffer, sizeof(ULONG)); TRACE("buffersize=%d\n", size); + if(!size) + { + *ppunk = NULL; + return Buffer + sizeof(ULONG); + } + working_mem = GlobalAlloc(0, size); if (!working_mem) return oldpos; @@ -552,14 +565,29 @@ unsigned char * WINAPI VARIANT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffe if(header->vt & VT_BYREF) { + ULONG mem_size; Pos += 4; + + switch (header->vt & ~VT_BYREF) + { + /* these types have a different memory size compared to wire size */ + case VT_UNKNOWN: + case VT_DISPATCH: + case VT_BSTR: + mem_size = sizeof(void *); + break; + default: + mem_size = type_size; + break; + } + if (V_VT(pvar) != header->vt) { VariantClear(pvar); - V_BYREF(pvar) = CoTaskMemAlloc(type_size); + V_BYREF(pvar) = CoTaskMemAlloc(mem_size); } else if (!V_BYREF(pvar)) - V_BYREF(pvar) = CoTaskMemAlloc(type_size); + V_BYREF(pvar) = CoTaskMemAlloc(mem_size); memcpy(V_BYREF(pvar), Pos, type_size); if((header->vt & VT_TYPEMASK) != VT_VARIANT) Pos += type_size; @@ -748,6 +776,26 @@ static inline SF_TYPE SAFEARRAY_GetUnionType(SAFEARRAY *psa) } } +static DWORD elem_wire_size(LPSAFEARRAY lpsa, SF_TYPE sftype) +{ + if (sftype == SF_BSTR) + return sizeof(DWORD); + else if (sftype == SF_VARIANT) + return sizeof(variant_wire_t) - sizeof(DWORD); + else + return lpsa->cbElements; +} + +static DWORD elem_mem_size(wireSAFEARRAY wiresa, SF_TYPE sftype) +{ + if (sftype == SF_BSTR) + return sizeof(BSTR); + else if (sftype == SF_VARIANT) + return sizeof(VARIANT); + else + return wiresa->cbElements; +} + ULONG WINAPI LPSAFEARRAY_UserSize(ULONG *pFlags, ULONG StartingSize, LPSAFEARRAY *ppsa) { ULONG size = StartingSize; @@ -853,13 +901,15 @@ unsigned char * WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buf SF_TYPE sftype; GUID guid; + sftype = SAFEARRAY_GetUnionType(psa); + *(ULONG *)Buffer = psa->cDims; Buffer += sizeof(ULONG); *(USHORT *)Buffer = psa->cDims; Buffer += sizeof(USHORT); *(USHORT *)Buffer = psa->fFeatures; Buffer += sizeof(USHORT); - *(ULONG *)Buffer = psa->cbElements; + *(ULONG *)Buffer = elem_wire_size(psa, sftype); Buffer += sizeof(ULONG); hr = SafeArrayGetVartype(psa, &vt); @@ -868,7 +918,6 @@ unsigned char * WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buf *(ULONG *)Buffer = (USHORT)psa->cLocks | (vt << 16); Buffer += sizeof(ULONG); - sftype = SAFEARRAY_GetUnionType(psa); *(ULONG *)Buffer = sftype; Buffer += sizeof(ULONG); @@ -1028,7 +1077,7 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B (*ppsa)->fFeatures &= FADF_AUTOSETFLAGS; (*ppsa)->fFeatures |= (wiresa->fFeatures & ~(FADF_AUTOSETFLAGS)); /* FIXME: there should be a limit on how large wiresa->cbElements can be */ - (*ppsa)->cbElements = wiresa->cbElements; + (*ppsa)->cbElements = elem_mem_size(wiresa, sftype); (*ppsa)->cLocks = LOWORD(wiresa->cLocks); /* SafeArrayCreateEx allocates the data for us, but @@ -1180,6 +1229,8 @@ HRESULT CALLBACK IDispatch_Invoke_Proxy( if (V_ISBYREF(arg)) { rgVarRefIdx[cVarRef] = u; VariantInit(&rgVarRef[cVarRef]); + VariantCopy(&rgVarRef[cVarRef], arg); + VariantClear(arg); cVarRef++; } } @@ -1265,6 +1316,12 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub( } if (SUCCEEDED(hr)) { + /* copy ref args to arg array */ + for (u=0; urgvarg = arg; hr = IDispatch_Invoke(This, @@ -1277,14 +1334,10 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub( pExcepInfo, pArgErr); - /* copy ref args to out list */ + /* copy ref args from arg array */ for (u=0; u= 0) - exponent -= pad; - else + exponent -= pad; + if (pad < 0) { have_int = need_int; have_frac -= pad; - exponent -= pad; pad = 0; } } @@ -1285,6 +1283,14 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat, have_frac = -pad; pad = 0; } + if(exponent < 0 && exponent > (-256 + have_int + have_frac)) + { + /* Remove exponent notation */ + memmove(rgbDig - exponent, rgbDig, have_int + have_frac); + ZeroMemory(rgbDig, -exponent); + have_frac -= exponent; + exponent = 0; + } } /* Rounding the number */ @@ -1313,10 +1319,10 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat, } else (*prgbDig)++; - /* We converted trailing digits to zeroes => have_frac has changed */ - while (have_frac > 0 && rgbDig[have_int + have_frac - 1] == 0) - have_frac--; } + /* We converted trailing digits to zeroes => have_frac has changed */ + while (have_frac > 0 && rgbDig[have_int + have_frac - 1] == 0) + have_frac--; } TRACE("have_int=%d,need_int=%d,have_frac=%d,need_frac=%d,pad=%d,exp=%d\n", have_int, need_int, have_frac, need_frac, pad, exponent); @@ -1957,7 +1963,7 @@ static HRESULT VARIANT_FormatString(LPVARIANT pVarIn, LPOLESTR lpszFormat, if (FAILED(hRes)) return hRes; - if (V_BSTR(pVarIn)[0] == '\0') + if (V_BSTR(&vStr)[0] == '\0') strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetNegative(header)); else strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetPositive(header)); diff --git a/reactos/dll/win32/oleaut32/variant.c b/reactos/dll/win32/oleaut32/variant.c index e92a63dcdd7..450856fed41 100644 --- a/reactos/dll/win32/oleaut32/variant.c +++ b/reactos/dll/win32/oleaut32/variant.c @@ -578,6 +578,66 @@ void WINAPI VariantInit(VARIANTARG* pVarg) V_VT(pVarg) = VT_EMPTY; /* Native doesn't set any other fields */ } +HRESULT VARIANT_ClearInd(VARIANTARG *pVarg) +{ + HRESULT hres; + + TRACE("(%p->(%s%s))\n", pVarg, debugstr_VT(pVarg), debugstr_VF(pVarg)); + + hres = VARIANT_ValidateType(V_VT(pVarg)); + if (FAILED(hres)) + return hres; + + switch (V_VT(pVarg)) + { + case VT_DISPATCH: + case VT_UNKNOWN: + if (V_UNKNOWN(pVarg)) + IUnknown_Release(V_UNKNOWN(pVarg)); + break; + case VT_UNKNOWN | VT_BYREF: + case VT_DISPATCH | VT_BYREF: + if(*V_UNKNOWNREF(pVarg)) + IUnknown_Release(*V_UNKNOWNREF(pVarg)); + break; + case VT_BSTR: + SysFreeString(V_BSTR(pVarg)); + break; + case VT_BSTR | VT_BYREF: + SysFreeString(*V_BSTRREF(pVarg)); + break; + case VT_VARIANT | VT_BYREF: + VariantClear(V_VARIANTREF(pVarg)); + break; + case VT_RECORD: + case VT_RECORD | VT_BYREF: + { + struct __tagBRECORD* pBr = &V_UNION(pVarg,brecVal); + if (pBr->pRecInfo) + { + IRecordInfo_RecordClear(pBr->pRecInfo, pBr->pvRecord); + IRecordInfo_Release(pBr->pRecInfo); + } + break; + } + default: + if (V_ISARRAY(pVarg) || (V_VT(pVarg) & ~VT_BYREF) == VT_SAFEARRAY) + { + if (V_ISBYREF(pVarg)) + { + if (*V_ARRAYREF(pVarg)) + hres = SafeArrayDestroy(*V_ARRAYREF(pVarg)); + } + else if (V_ARRAY(pVarg)) + hres = SafeArrayDestroy(V_ARRAY(pVarg)); + } + break; + } + + V_VT(pVarg) = VT_EMPTY; + return hres; +} + /****************************************************************************** * VariantClear [OLEAUT32.9] * @@ -1069,71 +1129,66 @@ static inline double VARIANT_JulianFromDMY(USHORT year, USHORT month, USHORT day static HRESULT VARIANT_RollUdate(UDATE *lpUd) { static const BYTE days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + short iYear, iMonth, iDay, iHour, iMinute, iSecond; - TRACE("Raw date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth, - lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond); + /* interpret values signed */ + iYear = lpUd->st.wYear; + iMonth = lpUd->st.wMonth; + iDay = lpUd->st.wDay; + iHour = lpUd->st.wHour; + iMinute = lpUd->st.wMinute; + iSecond = lpUd->st.wSecond; + TRACE("Raw date: %d/%d/%d %d:%d:%d\n", iDay, iMonth, + iYear, iHour, iMinute, iSecond); + + if (iYear > 9999 || iYear < -9999) + return E_INVALIDARG; /* Invalid value */ /* Years < 100 are treated as 1900 + year */ - if (lpUd->st.wYear < 100) - lpUd->st.wYear += 1900; + if (iYear > 0 && iYear < 100) + iYear += 1900; - if (!lpUd->st.wMonth) + iMinute += iSecond / 60; + iSecond = iSecond % 60; + iHour += iMinute / 60; + iMinute = iMinute % 60; + iDay += iHour / 24; + iHour = iHour % 24; + iYear += iMonth / 12; + iMonth = iMonth % 12; + if (iMonth<=0) {iMonth+=12; iYear--;} + while (iDay > days[iMonth]) { - /* Roll back to December of the previous year */ - lpUd->st.wMonth = 12; - lpUd->st.wYear--; - } - else while (lpUd->st.wMonth > 12) - { - /* Roll forward the correct number of months */ - lpUd->st.wYear++; - lpUd->st.wMonth -= 12; - } - - if (lpUd->st.wYear > 9999 || lpUd->st.wHour > 23 || - lpUd->st.wMinute > 59 || lpUd->st.wSecond > 59) - return E_INVALIDARG; /* Invalid values */ - - if (!lpUd->st.wDay) - { - /* Roll back the date one day */ - if (lpUd->st.wMonth == 1) - { - /* Roll back to December 31 of the previous year */ - lpUd->st.wDay = 31; - lpUd->st.wMonth = 12; - lpUd->st.wYear--; - } + if (iMonth == 2 && IsLeapYear(iYear)) + iDay -= 29; else - { - lpUd->st.wMonth--; /* Previous month */ - if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear)) - lpUd->st.wDay = 29; /* February has 29 days on leap years */ - else - lpUd->st.wDay = days[lpUd->st.wMonth]; /* Last day of the month */ - } + iDay -= days[iMonth]; + iMonth++; + iYear += iMonth / 12; + iMonth = iMonth % 12; } - else if (lpUd->st.wDay > 28) + while (iDay <= 0) { - int rollForward = 0; - - /* Possibly need to roll the date forward */ - if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear)) - rollForward = lpUd->st.wDay - 29; /* February has 29 days on leap years */ + iMonth--; + if (iMonth<=0) {iMonth+=12; iYear--;} + if (iMonth == 2 && IsLeapYear(iYear)) + iDay += 29; else - rollForward = lpUd->st.wDay - days[lpUd->st.wMonth]; - - if (rollForward > 0) - { - lpUd->st.wDay = rollForward; - lpUd->st.wMonth++; - if (lpUd->st.wMonth > 12) - { - lpUd->st.wMonth = 1; /* Roll forward into January of the next year */ - lpUd->st.wYear++; - } - } + iDay += days[iMonth]; } + + if (iSecond<0){iSecond+=60; iMinute--;} + if (iMinute<0){iMinute+=60; iHour--;} + if (iHour<0) {iHour+=24; iDay--;} + if (iYear<=0) iYear+=2000; + + lpUd->st.wYear = iYear; + lpUd->st.wMonth = iMonth; + lpUd->st.wDay = iDay; + lpUd->st.wHour = iHour; + lpUd->st.wMinute = iMinute; + lpUd->st.wSecond = iSecond; + TRACE("Rolled date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth, lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond); return S_OK; @@ -1190,6 +1245,8 @@ INT WINAPI DosDateTimeToVariantTime(USHORT wDosDate, USHORT wDosTime, ud.st.wMinute = DOS_MINUTE(wDosTime); ud.st.wSecond = DOS_SECOND(wDosTime); ud.st.wDayOfWeek = ud.st.wMilliseconds = 0; + if (ud.st.wHour > 23 || ud.st.wMinute > 59 || ud.st.wSecond > 59) + return FALSE; /* Invalid values in Dos*/ return VarDateFromUdate(&ud, 0, pDateOut) == S_OK; } @@ -1328,7 +1385,6 @@ HRESULT WINAPI VarDateFromUdateEx(UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DAT dateVal += ud.st.wHour / 24.0; dateVal += ud.st.wMinute / 1440.0; dateVal += ud.st.wSecond / 86400.0; - dateVal += ud.st.wMilliseconds / 86400000.0; TRACE("Returning %g\n", dateVal); *pDateOut = dateVal; @@ -2795,6 +2851,7 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags) if (FAILED(rc)) return rc; rc = VarBstrCmp(V_BSTR(bstrv), V_BSTR(&rv), lcid, flags); + VariantClear(&rv); } else if (V_BSTR(bstrv) && *V_BSTR(bstrv)) { /* Non NULL nor empty BSTR */ /* If the BSTR is not a number the BSTR is greater */ @@ -2810,8 +2867,8 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags) /* Numeric comparison, will be handled below. VARCMP_NULL used only to break out. */ rc = VARCMP_NULL; - VariantClear(&lv); - VariantClear(&rv); + VariantClear(&lv); + VariantClear(&rv); } else /* Empty or NULL BSTR */ rc = VARCMP_GT; diff --git a/reactos/dll/win32/oleaut32/variant.h b/reactos/dll/win32/oleaut32/variant.h index c881b24d60f..265fcc8041e 100644 --- a/reactos/dll/win32/oleaut32/variant.h +++ b/reactos/dll/win32/oleaut32/variant.h @@ -126,3 +126,4 @@ typedef struct tagVARIANT_NUMBER_CHARS BOOL VARIANT_GetLocalisedText(LANGID, DWORD, WCHAR *); +HRESULT VARIANT_ClearInd(VARIANTARG *); diff --git a/reactos/dll/win32/oleaut32/vartype.c b/reactos/dll/win32/oleaut32/vartype.c index 7f5325936b0..da1288d4a7c 100644 --- a/reactos/dll/win32/oleaut32/vartype.c +++ b/reactos/dll/win32/oleaut32/vartype.c @@ -3420,7 +3420,8 @@ static const int CY_Divisors[5] = { CY_MULTIPLIER/10000, CY_MULTIPLIER/1000, */ HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pCyOut) { - return VarCyFromR8(bIn, pCyOut); + pCyOut->int64 = (ULONG64)bIn * CY_MULTIPLIER; + return S_OK; } /************************************************************************ @@ -3440,7 +3441,8 @@ HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pCyOut) */ HRESULT WINAPI VarCyFromI2(SHORT sIn, CY* pCyOut) { - return VarCyFromR8(sIn, pCyOut); + pCyOut->int64 = (LONG64)sIn * CY_MULTIPLIER; + return S_OK; } /************************************************************************ @@ -3460,7 +3462,8 @@ HRESULT WINAPI VarCyFromI2(SHORT sIn, CY* pCyOut) */ HRESULT WINAPI VarCyFromI4(LONG lIn, CY* pCyOut) { - return VarCyFromR8(lIn, pCyOut); + pCyOut->int64 = (LONG64)lIn * CY_MULTIPLIER; + return S_OK; } /************************************************************************ @@ -3617,7 +3620,8 @@ HRESULT WINAPI VarCyFromDisp(IDispatch* pdispIn, LCID lcid, CY* pCyOut) */ HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pCyOut) { - return VarCyFromR8(boolIn, pCyOut); + pCyOut->int64 = (LONG64)boolIn * CY_MULTIPLIER; + return S_OK; } /************************************************************************ @@ -3637,7 +3641,8 @@ HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pCyOut) */ HRESULT WINAPI VarCyFromI1(signed char cIn, CY* pCyOut) { - return VarCyFromR8(cIn, pCyOut); + pCyOut->int64 = (LONG64)cIn * CY_MULTIPLIER; + return S_OK; } /************************************************************************ @@ -3657,7 +3662,8 @@ HRESULT WINAPI VarCyFromI1(signed char cIn, CY* pCyOut) */ HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY* pCyOut) { - return VarCyFromR8(usIn, pCyOut); + pCyOut->int64 = (ULONG64)usIn * CY_MULTIPLIER; + return S_OK; } /************************************************************************ @@ -3677,7 +3683,8 @@ HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY* pCyOut) */ HRESULT WINAPI VarCyFromUI4(ULONG ulIn, CY* pCyOut) { - return VarCyFromR8(ulIn, pCyOut); + pCyOut->int64 = (ULONG64)ulIn * CY_MULTIPLIER; + return S_OK; } /************************************************************************ @@ -3757,7 +3764,9 @@ HRESULT WINAPI VarCyFromI8(LONG64 llIn, CY* pCyOut) */ HRESULT WINAPI VarCyFromUI8(ULONG64 ullIn, CY* pCyOut) { - return VarCyFromR8(ullIn, pCyOut); + if (ullIn >= (I8_MAX/CY_MULTIPLIER)) return DISP_E_OVERFLOW; + pCyOut->int64 = ullIn * CY_MULTIPLIER; + return S_OK; } /************************************************************************ @@ -7598,6 +7607,14 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd break; case 0x3: /* TTT TTTDD TTTDDD */ + if (iDate && dp.dwCount == 3) + { + /* DDD */ + if ((dp.dwFlags[0] & (DP_AM|DP_PM)) || (dp.dwFlags[1] & (DP_AM|DP_PM)) || + (dp.dwFlags[2] & (DP_AM|DP_PM))) + hRet = DISP_E_TYPEMISMATCH; + break; + } if (dp.dwCount > 4 && ((dp.dwFlags[3] & (DP_AM|DP_PM)) || (dp.dwFlags[4] & (DP_AM|DP_PM)) || (dp.dwFlags[5] & (DP_AM|DP_PM)))) @@ -7690,6 +7707,13 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd dp.dwCount -= 3; break; + case 0x1B: /* localized DDDTTT */ + if (!iDate) + { + hRet = DISP_E_TYPEMISMATCH; + break; + } + /* .. fall through .. */ case 0x18: /* DDDTTT */ if ((dp.dwFlags[0] & (DP_AM|DP_PM)) || (dp.dwFlags[1] & (DP_AM|DP_PM)) || (dp.dwFlags[2] & (DP_AM|DP_PM))) diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index d8eb71f78f1..7cd927d7b7a 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -123,7 +123,7 @@ reactos/dll/win32/odbc32 # Out of sync. Depends on port of Linux ODBC. reactos/dll/win32/odbccp32 # Autosync reactos/dll/win32/ole32 # Autosync reactos/dll/win32/oleacc # Autosync -reactos/dll/win32/oleaut32 # Autosync ?? +reactos/dll/win32/oleaut32 # Autosync reactos/dll/win32/olecli32 # Autosync reactos/dll/win32/oledlg # Autosync reactos/dll/win32/olepro32 # Autosync From fdf2da655e24738853ffaada909ece61cff12cc4 Mon Sep 17 00:00:00 2001 From: Kamil Hornicek Date: Thu, 11 Mar 2010 11:34:29 +0000 Subject: [PATCH 38/64] [KERNEL32] GetConsoleProcessList is implemented, this prevents the console winetest from crashing svn path=/trunk/; revision=46095 --- reactos/dll/win32/kernel32/kernel32.pspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/kernel32/kernel32.pspec b/reactos/dll/win32/kernel32/kernel32.pspec index a642cd79023..d9622bb715e 100644 --- a/reactos/dll/win32/kernel32/kernel32.pspec +++ b/reactos/dll/win32/kernel32/kernel32.pspec @@ -324,7 +324,7 @@ @ stdcall GetConsoleMode(long ptr) @ stdcall GetConsoleNlsMode(long ptr) @ stdcall GetConsoleOutputCP() -@ stub GetConsoleProcessList ; missing in XP SP3 +@ stdcall GetConsoleProcessList(ptr long) ; missing in XP SP3 @ stdcall GetConsoleScreenBufferInfo(long ptr) @ stdcall GetConsoleSelectionInfo(ptr) @ stdcall GetConsoleTitleA(ptr long) From e277aa50f4d59a16cd7ff3dfe2f7360db29b8620 Mon Sep 17 00:00:00 2001 From: Kamil Hornicek Date: Thu, 11 Mar 2010 11:47:13 +0000 Subject: [PATCH 39/64] fix build? svn path=/trunk/; revision=46096 --- reactos/dll/win32/oleaut32/oleaut32.rbuild | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/dll/win32/oleaut32/oleaut32.rbuild b/reactos/dll/win32/oleaut32/oleaut32.rbuild index 1873cade868..8f8580ebbd6 100644 --- a/reactos/dll/win32/oleaut32/oleaut32.rbuild +++ b/reactos/dll/win32/oleaut32/oleaut32.rbuild @@ -9,7 +9,7 @@ include/reactos/wine 0x600 - {0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}} + "{0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}}" @@ -54,7 +54,7 @@ - {0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}} + "{0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}}" From 8e7d72058b8fad7fb0ccf94583ef48b049e3c3fb Mon Sep 17 00:00:00 2001 From: Kamil Hornicek Date: Thu, 11 Mar 2010 14:57:05 +0000 Subject: [PATCH 40/64] [SHELL32] - partial Wine sync, fixes crashing shlfileop winetest: Use the current directory when copying to an empty destination. Fix a memory leak in SHFileOperationW. Vincent Povirk svn path=/trunk/; revision=46098 --- reactos/dll/win32/shell32/shlfileop.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/reactos/dll/win32/shell32/shlfileop.c b/reactos/dll/win32/shell32/shlfileop.c index b8e0568a65b..e3bdf6eac31 100644 --- a/reactos/dll/win32/shell32/shlfileop.c +++ b/reactos/dll/win32/shell32/shlfileop.c @@ -1087,6 +1087,20 @@ static HRESULT copy_files(FILE_OPERATION *op, const FILE_LIST *flFrom, FILE_LIST if (flFrom->bAnyDontExist) return ERROR_SHELL_INTERNAL_FILE_NOT_FOUND; + if (flTo->dwNumFiles == 0) + { + /* If the destination is empty, SHFileOperation should use the current directory */ + WCHAR curdir[MAX_PATH+1]; + + GetCurrentDirectoryW(MAX_PATH, curdir); + curdir[lstrlenW(curdir)+1] = 0; + + destroy_file_list(flTo); + ZeroMemory(flTo, sizeof(FILE_LIST)); + parse_file_list(flTo, curdir); + fileDest = &flTo->feFiles[0]; + } + if (op->req->fFlags & FOF_MULTIDESTFILES) { if (flFrom->bAnyFromWildcard) @@ -1097,6 +1111,14 @@ static HRESULT copy_files(FILE_OPERATION *op, const FILE_LIST *flFrom, FILE_LIST if (flFrom->dwNumFiles != 1 && !IsAttribDir(fileDest->attributes)) return ERROR_CANCELLED; + /* Free all but the first entry. */ + for (i = 1; i < flTo->dwNumFiles; i++) + { + HeapFree(GetProcessHeap(), 0, flTo->feFiles[i].szDirectory); + HeapFree(GetProcessHeap(), 0, flTo->feFiles[i].szFilename); + HeapFree(GetProcessHeap(), 0, flTo->feFiles[i].szFullPath); + } + flTo->dwNumFiles = 1; } else if (IsAttribDir(fileDest->attributes)) From f4e17f00cb11e72ab91740cbf50736aff0f2b27d Mon Sep 17 00:00:00 2001 From: Sylvain Petreolle Date: Thu, 11 Mar 2010 16:36:11 +0000 Subject: [PATCH 41/64] [WLANSVC] Correctly start and report status to the service manager. svn path=/trunk/; revision=46099 --- reactos/base/services/wlansvc/wlansvc.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/reactos/base/services/wlansvc/wlansvc.c b/reactos/base/services/wlansvc/wlansvc.c index 86302f68a9e..5f0e1e6d95e 100644 --- a/reactos/base/services/wlansvc/wlansvc.c +++ b/reactos/base/services/wlansvc/wlansvc.c @@ -21,6 +21,7 @@ SERVICE_STATUS_HANDLE ServiceStatusHandle; SERVICE_STATUS SvcStatus; +static WCHAR ServiceName[] = L"WlanSvc"; /* FUNCTIONS *****************************************************************/ static DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter) @@ -94,13 +95,14 @@ ServiceMain(DWORD argc, LPWSTR *argv) DPRINT("ServiceMain() called\n"); SvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + SvcStatus.dwCurrentState = SERVICE_START_PENDING; SvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; SvcStatus.dwCheckPoint = 0; - SvcStatus.dwWin32ExitCode = 0; + SvcStatus.dwWin32ExitCode = NO_ERROR; SvcStatus.dwServiceSpecificExitCode = 0; SvcStatus.dwWaitHint = 4000; - ServiceStatusHandle = RegisterServiceCtrlHandlerExW(SERVICE_NAME, + ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName, ServiceControlHandler, NULL); @@ -115,15 +117,15 @@ ServiceMain(DWORD argc, LPWSTR *argv) NULL); if (!hThread) + { DPRINT("Can't create RpcThread\n"); + UpdateServiceStatus(ServiceStatusHandle, SERVICE_STOPPED, 0); + } else { - WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); } - UpdateServiceStatus(ServiceStatusHandle, SERVICE_STOPPED, 0); - DPRINT("ServiceMain() done\n"); } @@ -132,7 +134,7 @@ wmain(int argc, WCHAR *argv[]) { SERVICE_TABLE_ENTRYW ServiceTable[2] = { - {SERVICE_NAME, ServiceMain}, + {ServiceName, ServiceMain}, {NULL, NULL} }; From ec3193bd42bee7d9d36a6dfa2b19babd646617f7 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 11 Mar 2010 17:32:43 +0000 Subject: [PATCH 42/64] [PSDK] - Add GdiConvertToDevmodeW declaration (needed for comdlg32). Arwinss PSDK changes should really be merged in. svn path=/trunk/; revision=46101 --- reactos/include/psdk/wingdi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/include/psdk/wingdi.h b/reactos/include/psdk/wingdi.h index ef233abde14..b7bd62b1aae 100644 --- a/reactos/include/psdk/wingdi.h +++ b/reactos/include/psdk/wingdi.h @@ -2917,6 +2917,7 @@ BOOL WINAPI FlattenPath(HDC); BOOL WINAPI FloodFill(HDC,int,int,COLORREF); BOOL WINAPI GdiAlphaBlend(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION); BOOL WINAPI GdiComment(HDC,UINT,const BYTE*); +DEVMODEW* WINAPI GdiConvertToDevmodeW(const DEVMODEA *); BOOL WINAPI GdiFlush(void); DWORD WINAPI GdiGetBatchLimit(void); DWORD WINAPI GdiSetBatchLimit(DWORD); From 260b4a396b0382272eb5aa544ff93347346f2983 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 11 Mar 2010 17:37:30 +0000 Subject: [PATCH 43/64] [COMDLG32] - Sync to Wine-1.1.40. svn path=/trunk/; revision=46102 --- reactos/dll/win32/comdlg32/cdlg.h | 47 -- reactos/dll/win32/comdlg32/cdlg32.c | 1 - reactos/dll/win32/comdlg32/cdlg_Bg.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Ca.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Cs.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Da.rc | 3 + reactos/dll/win32/comdlg32/cdlg_De.rc | 113 ++-- reactos/dll/win32/comdlg32/cdlg_El.rc | 3 + reactos/dll/win32/comdlg32/cdlg_En.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Eo.rc | 5 +- reactos/dll/win32/comdlg32/cdlg_Es.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Fi.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Fr.rc | 427 +++++++------ reactos/dll/win32/comdlg32/cdlg_Hu.rc | 3 + reactos/dll/win32/comdlg32/cdlg_It.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Ja.rc | 5 +- reactos/dll/win32/comdlg32/cdlg_Ko.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Lt.rc | 54 +- reactos/dll/win32/comdlg32/cdlg_Nl.rc | 5 +- reactos/dll/win32/comdlg32/cdlg_No.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Pl.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Pt.rc | 287 +++++---- reactos/dll/win32/comdlg32/cdlg_Ro.rc | 5 +- reactos/dll/win32/comdlg32/cdlg_Ru.rc | 522 +++++++-------- reactos/dll/win32/comdlg32/cdlg_Si.rc | 5 +- reactos/dll/win32/comdlg32/cdlg_Sk.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Sv.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Th.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Tr.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Uk.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Wa.rc | 3 + reactos/dll/win32/comdlg32/cdlg_Zh.rc | 5 +- reactos/dll/win32/comdlg32/cdlg_xx.rc | 7 +- reactos/dll/win32/comdlg32/colordlg.c | 42 +- reactos/dll/win32/comdlg32/comdlg32.rbuild | 2 +- reactos/dll/win32/comdlg32/filedlg.c | 231 ++----- reactos/dll/win32/comdlg32/filedlg31.c | 90 ++- reactos/dll/win32/comdlg32/filedlg31.h | 26 +- .../win32/comdlg32/{finddlg32.c => finddlg.c} | 122 ++-- reactos/dll/win32/comdlg32/finddlg16.c | 496 --------------- reactos/dll/win32/comdlg32/fontdlg.c | 86 +-- reactos/dll/win32/comdlg32/fontdlg16.c | 380 ----------- reactos/dll/win32/comdlg32/printdlg.c | 171 ++--- reactos/dll/win32/comdlg32/printdlg16.c | 602 ------------------ reactos/dll/win32/comdlg32/rsrc.rc | 17 +- reactos/media/doc/README.WINE | 2 +- 46 files changed, 1165 insertions(+), 2647 deletions(-) rename reactos/dll/win32/comdlg32/{finddlg32.c => finddlg.c} (86%) delete mode 100644 reactos/dll/win32/comdlg32/finddlg16.c delete mode 100644 reactos/dll/win32/comdlg32/fontdlg16.c delete mode 100644 reactos/dll/win32/comdlg32/printdlg16.c diff --git a/reactos/dll/win32/comdlg32/cdlg.h b/reactos/dll/win32/comdlg32/cdlg.h index 84486a72fcc..b56c1674977 100644 --- a/reactos/dll/win32/comdlg32/cdlg.h +++ b/reactos/dll/win32/comdlg32/cdlg.h @@ -184,51 +184,4 @@ extern LPVOID (WINAPI *COMDLG32_SHAlloc)(DWORD); extern DWORD (WINAPI *COMDLG32_SHFree)(LPVOID); extern BOOL (WINAPI *COMDLG32_SHGetFolderPathW)(HWND,int,HANDLE,DWORD,LPWSTR); -/* - * Internal Functions - * Do NOT Export to other programs and dlls - */ - -BOOL CC_HookCallChk( const CHOOSECOLORW *lpcc ); -int CC_MouseCheckResultWindow( HWND hDlg, LPARAM lParam ); -LRESULT CC_WMLButtonDown( HWND hDlg, WPARAM wParam, LPARAM lParam ); -LRESULT CC_WMLButtonUp( HWND hDlg, WPARAM wParam, LPARAM lParam ); -LRESULT CC_WMMouseMove( HWND hDlg, LPARAM lParam ); -LRESULT CC_WMPaint( HWND hDlg, WPARAM wParam, LPARAM lParam ); -void CC_SwitchToFullSize( HWND hDlg, COLORREF result, LPCRECT lprect ); -void CC_PaintSelectedColor( HWND hDlg, COLORREF cr ); -int CC_RGBtoHSL(char c, int r, int g, int b); -void CC_PaintCross( HWND hDlg, int x, int y); -void CC_PaintTriangle( HWND hDlg, int y); -int CC_CheckDigitsInEdit( HWND hwnd, int maxval ); -void CC_EditSetHSL( HWND hDlg, int h, int s, int l ); -int CC_HSLtoRGB(char c, int hue, int sat, int lum); -void CC_EditSetRGB( HWND hDlg, COLORREF cr ); -void CC_PaintUserColorArray( HWND hDlg, int rows, int cols, const COLORREF* lpcr ); - -typedef struct -{ - HWND hWnd1; - HWND hWnd2; - LPCHOOSEFONTW lpcf32w; - int added; -} CFn_ENUMSTRUCT, *LPCFn_ENUMSTRUCT; - -INT AddFontFamily(const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM, - UINT nFontType, const CHOOSEFONTW *lpcf, HWND hwnd, - LPCFn_ENUMSTRUCT e); -INT AddFontStyle(const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *metrics, - UINT nFontType, const CHOOSEFONTW *lpcf, HWND hcmb2, HWND hcmb3, - HWND hDlg, BOOL iswin16); -void _dump_cf_flags(DWORD cflags); - -LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam, - LPCHOOSEFONTW lpcf); -LRESULT CFn_WMMeasureItem(HWND hDlg, WPARAM wParam, LPARAM lParam); -LRESULT CFn_WMDrawItem(HWND hDlg, WPARAM wParam, LPARAM lParam); -LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, - LPCHOOSEFONTW lpcf); -LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, - const CHOOSEFONTW *lpcf); - #endif /* _WINE_DLL_CDLG_H */ diff --git a/reactos/dll/win32/comdlg32/cdlg32.c b/reactos/dll/win32/comdlg32/cdlg32.c index 321554fc922..950244346ce 100644 --- a/reactos/dll/win32/comdlg32/cdlg32.c +++ b/reactos/dll/win32/comdlg32/cdlg32.c @@ -154,7 +154,6 @@ void COMDLG32_SetCommDlgExtendedError(DWORD err) /*********************************************************************** * CommDlgExtendedError (COMDLG32.@) - * CommDlgExtendedError (COMMDLG.26) * * Get the thread's local error value if a comdlg32 function fails. * RETURNS diff --git a/reactos/dll/win32/comdlg32/cdlg_Bg.rc b/reactos/dll/win32/comdlg32/cdlg_Bg.rc index 746b942fa70..5b0865a7c24 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Bg.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Bg.rc @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * Òóê èçðè÷íî ïèøåøå äà íå ïèïàì íåùî, àìà àç ãî ïèïíàõ. * Àêî èìà ïðîáëåìè íÿêîé äà ãè îïðàâè. diff --git a/reactos/dll/win32/comdlg32/cdlg_Ca.rc b/reactos/dll/win32/comdlg32/cdlg_Ca.rc index b76f412841d..59cffb12fa3 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Ca.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Ca.rc @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Cs.rc b/reactos/dll/win32/comdlg32/cdlg_Cs.rc index 64e9f892757..e3acb801f68 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Cs.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Cs.rc @@ -18,6 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Da.rc b/reactos/dll/win32/comdlg32/cdlg_Da.rc index 839a1a46c7b..951cb6c5271 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Da.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Da.rc @@ -17,6 +17,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_De.rc b/reactos/dll/win32/comdlg32/cdlg_De.rc index 8e6432e83c4..787a85e0f0c 100644 --- a/reactos/dll/win32/comdlg32/cdlg_De.rc +++ b/reactos/dll/win32/comdlg32/cdlg_De.rc @@ -17,6 +17,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + +#pragma code_page(65001) + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ @@ -25,7 +30,7 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL OPEN_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Öffnen" +CAPTION "Öffnen" FONT 8, "MS Shell Dlg" { LTEXT "Datei&name:", 1090, 6, 6, 76, 9 @@ -38,10 +43,10 @@ FONT 8, "MS Shell Dlg" COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP LTEXT "&Laufwerke:", 1091, 110, 104, 92, 9 COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Öffnen", IDOK, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "Öffnen", IDOK, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP PUSHBUTTON "Abbrechen", IDCANCEL, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Hilfe", pshHelp, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP - CHECKBOX "&Schreibgeschützt", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "&Schreibgeschützt", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP } @@ -63,7 +68,7 @@ FONT 8, "MS Shell Dlg" DEFPUSHBUTTON "Speichern als", IDOK, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP PUSHBUTTON "Abbrechen", IDCANCEL, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Hilfe", pshHelp, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP - CHECKBOX "&Schreibgeschützt", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "&Schreibgeschützt", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP } @@ -83,7 +88,7 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "&Einrichten", psh1, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP LTEXT "&Von:", 1090, 60, 80, 30, 9 LTEXT "&Bis:", 1091, 120, 80, 30, 9 - LTEXT "Druck&qualität:", 1092, 6, 100, 76, 9 + LTEXT "Druck&qualität:", 1092, 6, 100, 76, 9 COMBOBOX 1136, 80, 100, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP CHECKBOX "In &Datei drucken", 1040, 20, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP CHECKBOX "Verdichtet", 1041, 160, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP @@ -108,8 +113,8 @@ FONT 8, "MS Shell Dlg" RADIOBUTTON "&Querformat", rad4, 50, 115, 40, 12 ICON "LANDSCAP", 1097, 10, 95, 32, 32 ICON "PORTRAIT", 1098, 10, 95, 32, 32 - GROUPBOX "Paper", 1074, 120, 85, 180, 50, BS_GROUPBOX - LTEXT "&Größe", 1089, 130, 95, 30, 9 + GROUPBOX "Papier", 1074, 120, 85, 180, 50, BS_GROUPBOX + LTEXT "&Größe", 1089, 130, 95, 30, 9 LTEXT "P&apierquelle", 1090, 130, 110, 30, 9 COMBOBOX 1137, 155, 95, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP COMBOBOX 1138, 155, 110, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP @@ -124,14 +129,14 @@ BEGIN CONTROL "", rct2, "Static", SS_GRAYRECT, 160, 12, 4, 80 CONTROL "", rct3, "Static", SS_GRAYRECT, 84, 88, 80, 4 GROUPBOX "Papier", grp2, 8, 96, 224, 56, BS_GROUPBOX - LTEXT "&Größe:", stc2, 16, 112, 36, 8 + LTEXT "&Größe:", stc2, 16, 112, 36, 8 COMBOBOX cmb2, 64, 110, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL LTEXT "&Zufuhr:", stc3, 16, 132, 36, 8 COMBOBOX cmb3, 64, 130, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL GROUPBOX "Format", grp1, 8, 156, 64, 56, BS_GROUPBOX AUTORADIOBUTTON "&Hochformat", rad1, 16, 170, 52, 12, BS_AUTORADIOBUTTON AUTORADIOBUTTON "&Querformat", rad2, 16, 190, 52, 12, BS_AUTORADIOBUTTON - GROUPBOX "Ränder", grp4, 80, 156, 152, 56, BS_GROUPBOX + GROUPBOX "Ränder", grp4, 80, 156, 152, 56, BS_GROUPBOX LTEXT "&Links:", stc15, 88, 172, 21, 8 EDITTEXT edt4, 111, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER LTEXT "&Rechts:", stc16, 159, 172, 27, 8 @@ -157,7 +162,7 @@ FONT 8, "MS Shell Dlg" LTEXT "Schrift&stil:",1089 ,108,3,44,9 COMBOBOX 1137,108,13,64,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE - LTEXT "Schrift&größe:",1090,179,3,30,9 + LTEXT "Schrift&größe:",1090,179,3,30,9 COMBOBOX 1138,179,13,32,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE | CBS_SORT DEFPUSHBUTTON "OK",IDOK,218,6,40,14,WS_GROUP @@ -188,13 +193,13 @@ FONT 8, "MS Shell Dlg" LTEXT "Farbe | B&asis", 1090, 150, 151, 48, 10 LTEXT "&Rot:", 726 ,249,126,24,10 EDITTEXT 706, 275,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "&Grün:",727/*1095*/,249,140,24,10 + LTEXT "&Grün:",727/*1095*/,249,140,24,10 EDITTEXT 707, 275,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP LTEXT "&Blau:",728 /*1096*/,249,154,24,10 EDITTEXT 708, 275,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP LTEXT "&Farbe:" ,723 /*1091*/,202,126,22,10 EDITTEXT 703, 226,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "&Sätt:" ,724 /*1092*/,202,140,22,10 + LTEXT "&Sätt:" ,724 /*1092*/,202,140,22,10 EDITTEXT 704, 226,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP LTEXT "H&ell:" ,725 /*1093*/,202,154,22,10 EDITTEXT 705, 226,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP @@ -206,7 +211,7 @@ FONT 8, "MS Shell Dlg" DEFPUSHBUTTON "Ok", IDOK, 4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP PUSHBUTTON "Abbrechen", IDCANCEL, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Hilfe", pshHelp,100,166, 44, 14 - PUSHBUTTON "Farbe hin&zufügen", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Farbe hin&zufügen", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "Farben &definieren >>", 719/*1025*/, 4, 150, 142, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&a",713,300,200,4,14 /* just a dummy: 'a' is like &a in "B&asis" */ } @@ -220,7 +225,7 @@ FONT 8, "MS Shell Dlg" LTEXT "S&uchen nach:", -1, 4, 8, 45, 8 EDITTEXT 1152, 53, 7, 128, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP CHECKBOX "Nu&r ganzes Wort suchen", 1040, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Groß-/Klein&schreibung", 1041, 4, 42, 84, 12, BS_AUTOCHECKBOX | WS_TABSTOP + CHECKBOX "Groß-/Klein&schreibung", 1041, 4, 42, 84, 12, BS_AUTOCHECKBOX | WS_TABSTOP GROUPBOX "Suchrichtung", 1072, 113, 23, 68, 37 CONTROL "Nach &oben", rad1, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 117, 34, 50, 10 CONTROL "Nach &unten", rad2, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 117, 47, 50, 10 @@ -240,7 +245,7 @@ FONT 8, "MS Shell Dlg" LTEXT "Ersetzen &durch:", -1, 4, 26, 52, 8 EDITTEXT 1153, 56, 24, 112, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP CHECKBOX "Nu&r ganzes Wort", 1040, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Groß-/Kleins&chreibung", 1041, 5, 62, 86, 12, BS_AUTOCHECKBOX | WS_TABSTOP + CHECKBOX "Groß-/Kleins&chreibung", 1041, 5, 62, 86, 12, BS_AUTOCHECKBOX | WS_TABSTOP DEFPUSHBUTTON "&Weitersuchen", IDOK, 175, 6, 60, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP PUSHBUTTON "&Ersetzen", psh1, 175, 23, 60, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "A&lles ersetzen", psh2, 175, 40, 60, 14, WS_GROUP | WS_TABSTOP @@ -250,7 +255,7 @@ FONT 8, "MS Shell Dlg" NEWFILEOPENORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 280, 164 STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN -CAPTION "Öffnen" +CAPTION "Öffnen" FONT 8, "MS Shell Dlg" { LTEXT "&Suche in",IDC_LOOKINSTATIC,4,6,43,8, SS_NOTIFY @@ -265,14 +270,14 @@ FONT 8, "MS Shell Dlg" LTEXT "Datei&typen",IDC_FILETYPESTATIC,5,128,42,8, SS_NOTIFY COMBOBOX IDC_FILETYPE,54,126,155,53,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "&Schreibgeschützt",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,145,100,10 + CONTROL "&Schreibgeschützt",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,145,100,10 - DEFPUSHBUTTON "Ö&ffnen", IDOK,222,110,50,14 + DEFPUSHBUTTON "Ö&ffnen", IDOK,222,110,50,14 PUSHBUTTON "Abbrechen", IDCANCEL,222,128,50,14 PUSHBUTTON "&Hilfe", pshHelp,222,145,50,14 } -PRINT32 DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 288, 186 +PRINT32 DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 295, 186 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP | DS_3DLOOK CAPTION "Drucken" @@ -282,24 +287,24 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "Abbrechen", IDCANCEL, 232,164, 48,14, WS_GROUP PUSHBUTTON "&Hilfe", pshHelp, 50, 161, 48,14, WS_GROUP - GROUPBOX "Drucker", grp4, 8, 4, 272,84, WS_GROUP - CONTROL "In Da&tei drucken", chx1, "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,212,70,64,12 + GROUPBOX "Drucker", grp4, 8, 4, 279,84, WS_GROUP + CONTROL "In Da&tei drucken", chx1, "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,212,70,66,12 PUSHBUTTON "&Eigenschaften", psh2, 212, 17, 60,14, WS_GROUP LTEXT "&Name:", stc6, 16, 20, 36,8 COMBOBOX cmb4, 52, 18, 152,152,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP LTEXT "Status:", stc8, 16, 36, 36,10, SS_NOPREFIX - LTEXT "Dummy State", stc12, 52, 36, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "[keiner]", stc12, 52, 36, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP LTEXT "Typ:", stc7, 16, 48, 36,10, SS_NOPREFIX - LTEXT "Dummy Type", stc11, 52, 48, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "[keiner]", stc11, 52, 48, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP LTEXT "Ort:", stc10, 16, 60, 36,10, SS_NOPREFIX - LTEXT "Dummy Location", stc14, 52, 60, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "[keiner]", stc14, 52, 60, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP LTEXT "Kommentar:", stc9, 16, 72, 36,10, SS_NOPREFIX - LTEXT "Dummy Remark", stc13, 52, 72, 152,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "[keiner]", stc13, 52, 72, 152,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - GROUPBOX "Kopien", grp2, 160, 92, 120,64, WS_GROUP + GROUPBOX "Kopien", grp2, 160, 92, 127,64, WS_GROUP LTEXT "Anzahl &Kopien:",stc5,168,108,68,8 ICON "", ico3, 162,124, 76,24, WS_GROUP | SS_CENTERIMAGE - CONTROL "C&ollate", chx2,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,240,130,36,12 + CONTROL "S&ortieren", chx2,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,240,130,42,12 EDITTEXT edt3, 240,106, 32,12, WS_GROUP | ES_NUMBER GROUPBOX "Druck Bereich", grp1, 8,92, 144,64, WS_GROUP @@ -336,7 +341,7 @@ BEGIN LTEXT "[keiner]", stc13, 52, 72, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP GROUPBOX "Papier", grp2, 8, 92, 164,56, WS_GROUP - LTEXT "&Größe:", stc2, 16,108, 36, 8 + LTEXT "&Größe:", stc2, 16,108, 36, 8 COMBOBOX cmb2, 52,106, 112,112,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP LTEXT "&Zufuhr:", stc3, 16,128, 36, 8 COMBOBOX cmb3, 52,126, 112,112,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP @@ -349,7 +354,7 @@ END STRINGTABLE DISCARDABLE { - IDS_ABOUTBOX "Ü&ber den Folderpicker" + IDS_ABOUTBOX "Ü&ber den Folderpicker" IDS_DOCUMENTFOLDERS "Dokumenten Ordner" IDS_PERSONAL "Meine Dokumente" IDS_FAVORITES "Meine Favoriten" @@ -364,10 +369,10 @@ STRINGTABLE DISCARDABLE IDS_SYSTEMFOLDERS "System Ordner" IDS_LOCALHARDRIVES "Lokale Festplatten" IDS_FILENOTFOUND "Datei nicht gefunden" - IDS_VERIFYFILE "Bitte überprüfen sie, ob der korrekte Dateiname angegeben wurde" + IDS_VERIFYFILE "Bitte überprüfen sie, ob der korrekte Dateiname angegeben wurde" IDS_CREATEFILE "Die Datei existiert nicht.\nWollen Sie sie neu anlegen?" - IDS_OVERWRITEFILE "Die Datei existiert bereits.\nWollen Sie sie überschreiben?" - IDS_INVALID_FILENAME_TITLE "Unzulässige Zeichen im Pfad" + IDS_OVERWRITEFILE "Die Datei existiert bereits.\nWollen Sie sie überschreiben?" + IDS_INVALID_FILENAME_TITLE "Unzulässige Zeichen im Pfad" IDS_INVALID_FILENAME "Ein Dateiname darf folgende Zeichen nicht enthalten:\n / : < > |" IDS_PATHNOTEXISTING "Der Pfad existiert nicht" IDS_FILENOTEXISTING "Die Datei existiert nicht" @@ -375,7 +380,7 @@ STRINGTABLE DISCARDABLE STRINGTABLE DISCARDABLE { - IDS_UPFOLDER "Eine Verzeichnisebene höher" + IDS_UPFOLDER "Eine Verzeichnisebene höher" IDS_NEWFOLDER "Neuen Ordner anlegen" IDS_LISTVIEW "Liste" IDS_REPORTVIEW "Details" @@ -389,50 +394,50 @@ STRINGTABLE DISCARDABLE PD32_VALUE_UREADABLE "Unlesbarer Eintrag" PD32_INVALID_PAGE_RANGE "Dieser Wert liegt nicht auf der Seite.\n\ Bitte geben sie einen Wert zwischen %d und %d an." - PD32_FROM_NOT_ABOVE_TO "Der 'von' Eintrag kann nicht größer sein als der 'bis' Eintrag." - PD32_MARGINS_OVERLAP "Die Ränder überlappen oder sind außerhalb des Papiers.\nBitte die Ränder neu eingeben." + PD32_FROM_NOT_ABOVE_TO "Der 'von' Eintrag kann nicht größer sein als der 'bis' Eintrag." + PD32_MARGINS_OVERLAP "Die Ränder überlappen oder sind außerhalb des Papiers.\nBitte die Ränder neu eingeben." PD32_NR_OF_COPIES_EMPTY "Es muss ein Wert bei der Anzahl der Kopien angegeben werden." - PD32_TOO_LARGE_COPIES "Ihr Drucker unterstützt so viele Kopien nicht.\nBitte verwenden Sie eine Kopienzahl zwischen 1 und %d." + PD32_TOO_LARGE_COPIES "Ihr Drucker unterstützt so viele Kopien nicht.\nBitte verwenden Sie eine Kopienzahl zwischen 1 und %d." PD32_PRINT_ERROR "Ein Druckerfehler ist aufgetreten." PD32_NO_DEFAULT_PRINTER "Es ist kein Standarddrucker eingestellt." PD32_CANT_FIND_PRINTER "Kann den Drucker nicht finden." PD32_OUT_OF_MEMORY "Kein freier Speicher mehr." PD32_GENERIC_ERROR "Ein unbekannter Fehler ist aufgetreten." PD32_DRIVER_UNKNOWN "Unbekannter Druckertreiber." - PD32_NO_DEVICES "Bevor Sie drucker-relevante Aufgaben ausführen können, \ + PD32_NO_DEVICES "Bevor Sie drucker-relevante Aufgaben ausführen können, \ wie die Seiteneinrichtung oder ein Dokument zu drucken, \ - müssen Sie einen Drucker installieren. Bitte führen Sie dies zuerst aus und versuchen Sie es erneut." + müssen Sie einen Drucker installieren. Bitte führen Sie dies zuerst aus und versuchen Sie es erneut." PD32_DEFAULT_PRINTER "Standard Drucker; " PD32_NR_OF_DOCUMENTS_IN_QUEUE "Es sind %d Dokumente in der Queue" - PD32_MARGINS_IN_INCHES "Ränder [inches/zoll]" - PD32_MARGINS_IN_MILLIMETERS "Ränder [mm]" + PD32_MARGINS_IN_INCHES "Ränder [inches/zoll]" + PD32_MARGINS_IN_MILLIMETERS "Ränder [mm]" PD32_MILLIMETERS "mm" PD32_PRINTER_STATUS_READY "Bereit" PD32_PRINTER_STATUS_PAUSED "Gestoppt; " PD32_PRINTER_STATUS_ERROR "Fehler; " - PD32_PRINTER_STATUS_PENDING_DELETION "Wartet auf Löschung; " + PD32_PRINTER_STATUS_PENDING_DELETION "Wartet auf Löschung; " PD32_PRINTER_STATUS_PAPER_JAM "Papierstau; " PD32_PRINTER_STATUS_PAPER_OUT "Papierfach leer; " - PD32_PRINTER_STATUS_MANUAL_FEED "Papier manuell zuführen; " + PD32_PRINTER_STATUS_MANUAL_FEED "Papier manuell zuführen; " PD32_PRINTER_STATUS_PAPER_PROBLEM "Papierproblem; " PD32_PRINTER_STATUS_OFFLINE "Printer ist offline; " - PD32_PRINTER_STATUS_IO_ACTIVE "Datenübertragung; " - PD32_PRINTER_STATUS_BUSY "Beschäftigt; " + PD32_PRINTER_STATUS_IO_ACTIVE "Datenübertragung; " + PD32_PRINTER_STATUS_BUSY "Beschäftigt; " PD32_PRINTER_STATUS_PRINTING "Druckend; " PD32_PRINTER_STATUS_OUTPUT_BIN_FULL "Ausgabe Fach ist voll; " PD32_PRINTER_STATUS_NOT_AVAILABLE "Nicht vorhanden; " PD32_PRINTER_STATUS_WAITING "Wartend; " PD32_PRINTER_STATUS_PROCESSING "In Bearbeitung; " PD32_PRINTER_STATUS_INITIALIZING "Initialisierend; " - PD32_PRINTER_STATUS_WARMING_UP "Aufwärmend; " + PD32_PRINTER_STATUS_WARMING_UP "Aufwärmend; " PD32_PRINTER_STATUS_TONER_LOW "Tonerstand niedrig; " PD32_PRINTER_STATUS_NO_TONER "Kein Toner mehr; " - PD32_PRINTER_STATUS_PAGE_PUNT "Page punt; " + PD32_PRINTER_STATUS_PAGE_PUNT "Seitenausgabe; " PD32_PRINTER_STATUS_USER_INTERVENTION "Durch Benutzer unterbrochen; " PD32_PRINTER_STATUS_OUT_OF_MEMORY "Kein Speicher mehr; " - PD32_PRINTER_STATUS_DOOR_OPEN "Druckergehäuse ist offen; " + PD32_PRINTER_STATUS_DOOR_OPEN "Druckergehäuse ist offen; " PD32_PRINTER_STATUS_SERVER_UNKNOWN "Druckserver unbekannt; " PD32_PRINTER_STATUS_POWER_SAVE "Stromsparmodus; " } @@ -449,28 +454,28 @@ STRINGTABLE DISCARDABLE /* Color names */ { IDS_COLOR_BLACK "Schwarz" IDS_COLOR_MAROON "Kastanienbraun" - IDS_COLOR_GREEN "Grün" - IDS_COLOR_OLIVE "Olivgrün" + IDS_COLOR_GREEN "Grün" + IDS_COLOR_OLIVE "Olivgrün" IDS_COLOR_NAVY "Dunkelblau" IDS_COLOR_PURPLE "Lila" - IDS_COLOR_TEAL "Blaugrün" + IDS_COLOR_TEAL "Blaugrün" IDS_COLOR_GRAY "Grau" IDS_COLOR_SILVER "Silber" IDS_COLOR_RED "Rot" - IDS_COLOR_LIME "Hellgrün" + IDS_COLOR_LIME "Hellgrün" IDS_COLOR_YELLOW "Gelb" IDS_COLOR_BLUE "Blau" IDS_COLOR_FUCHSIA "Pink" IDS_COLOR_AQUA "Aquamarin" - IDS_COLOR_WHITE "Weiß" + IDS_COLOR_WHITE "Weiß" } STRINGTABLE DISCARDABLE { - IDS_FONT_SIZE "Wählen Sie eine Schriftgröße zwischen %d und %d Punkten aus." + IDS_FONT_SIZE "Wählen Sie eine Schriftgröße zwischen %d und %d Punkten aus." IDS_SAVE_BUTTON "&Speichern" IDS_SAVE_IN "Speichern &unter:" IDS_SAVE "Speichern" IDS_SAVE_AS "Speichern als" - IDS_OPEN_FILE "Öffne Datei" + IDS_OPEN_FILE "Öffne Datei" } diff --git a/reactos/dll/win32/comdlg32/cdlg_El.rc b/reactos/dll/win32/comdlg32/cdlg_El.rc index 9fa64dde42a..309cda955c2 100644 --- a/reactos/dll/win32/comdlg32/cdlg_El.rc +++ b/reactos/dll/win32/comdlg32/cdlg_El.rc @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_En.rc b/reactos/dll/win32/comdlg32/cdlg_En.rc index 962c1891152..c6889b41947 100644 --- a/reactos/dll/win32/comdlg32/cdlg_En.rc +++ b/reactos/dll/win32/comdlg32/cdlg_En.rc @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Eo.rc b/reactos/dll/win32/comdlg32/cdlg_Eo.rc index b9573f455a5..cf4ad4c110b 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Eo.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Eo.rc @@ -1,6 +1,6 @@ /* * Copyright 1996 Duncan C Thomson - * Copyright 1006 Antonio Codazzi + * Copyright 2006 Antonio Codazzi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,6 +17,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Es.rc b/reactos/dll/win32/comdlg32/cdlg_Es.rc index 1f6226a0fb0..8327e6ab015 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Es.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Es.rc @@ -17,6 +17,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Fi.rc b/reactos/dll/win32/comdlg32/cdlg_Fi.rc index 8e732df21a7..dbe273f9fb6 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Fi.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Fi.rc @@ -17,6 +17,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Fr.rc b/reactos/dll/win32/comdlg32/cdlg_Fr.rc index bd93a10b9bf..de87186d9cf 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Fr.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Fr.rc @@ -4,6 +4,7 @@ * * Copyright 1995 Alexandre Julliard * Copyright 2005-2008 Jonathan Ernst + * Copyright 2009 Frédéric Delanoy * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,6 +21,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + +/* UTF-8 */ +#pragma code_page(65001) + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ @@ -31,20 +38,20 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Ouvrir" FONT 8, "MS Shell Dlg" { - LTEXT "&Nom de fichier :", 1090, 6, 6, 76, 9 + LTEXT "&Nom de fichier :", 1090, 6, 6, 76, 9 EDITTEXT edt1, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "&Répertoires", -1, 110, 6, 92, 9 + LTEXT "&Répertoires", -1, 110, 6, 92, 9 LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "Liste des fichiers de &type :", 1089, 6, 104, 90, 9 - COMBOBOX cmb1, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP - LTEXT "&Lecteurs :", 1091, 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 "OK", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + LTEXT "Liste des fichiers de &type :", 1089, 6, 104, 90, 9 + COMBOBOX cmb1, 6, 114, 90, 15, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP + LTEXT "&Lecteurs :", 1091, 110, 104, 92, 9 + COMBOBOX cmb2, 110, 114, 92, 15, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Ouvrir", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP PUSHBUTTON "Annuler", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "Aid&e", pshHelp, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP - CHECKBOX "Lecture seule", chx1, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "&Lecture seule", chx1, 208, 68, 55, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP } @@ -53,84 +60,84 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Enregistrer sous..." FONT 8, "MS Shell Dlg" { - LTEXT "&Nom de fichier :", 1090, 6, 6, 76, 9 + LTEXT "&Nom de fichier :", 1090, 6, 6, 76, 9 EDITTEXT edt1, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "&Répertoires :", -1, 110, 6, 92, 9 + LTEXT "&Répertoires :", -1, 110, 6, 92, 9 LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "Liste des fichiers de &type :", 1089, 6, 104, 90, 9 + LTEXT "Lister les fichiers de &type :", 1089, 6, 104, 90, 9 COMBOBOX cmb1, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP LTEXT "&Lecteurs:", 1091, 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 "OK", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Annuler", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Aid&e", pshHelp, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP - CHECKBOX "Lecture seule", chx1, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "Enregistrer", 1, 208, 6, 60, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Annuler", 2, 208, 24, 60, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Aid&e", pshHelp, 208, 46, 60, 14, WS_GROUP | WS_TABSTOP + CHECKBOX "Lecture seule", chx1, 208, 68, 55, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP } -PRINT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134 +PRINT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 237, 134 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Imprimer" FONT 8, "MS Shell Dlg" { - LTEXT "Imprimante :", 1088, 6, 6, 40, 9 + LTEXT "Imprimante :", 1088, 6, 6, 40, 9 LTEXT "", 1089, 60, 6, 150, 9 - GROUPBOX "Étendue", grp1, 6, 30, 160, 65, BS_GROUPBOX + GROUPBOX "Zone d'impression", grp1, 6, 30, 160, 65, BS_GROUPBOX RADIOBUTTON "&Tout", rad1, 16, 45, 60, 12 - RADIOBUTTON "&Sélection", rad2, 16, 60, 60, 12 - RADIOBUTTON "&Pages", rad3, 16, 75, 60, 12 - DEFPUSHBUTTON "OK", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Annuler", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Configurer...", psh1, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP - LTEXT "&De:", 1090, 60, 80, 30, 9 - LTEXT "&A:", 1091, 120, 80, 30, 9 - LTEXT "&Qualité d'impression:", 1092, 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 "&Fichier d'impression", chx1, 20, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Copies t&riées", chx2, 160, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + RADIOBUTTON "&Sélection", rad2, 16, 60, 60, 12 + RADIOBUTTON "&Pages", rad3, 16, 75, 41, 12 + DEFPUSHBUTTON "Imprimer", 1, 173, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Annuler", 2, 173, 24, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Configurer...", psh1, 173, 46, 56, 14, WS_GROUP | WS_TABSTOP + LTEXT "&De:", 1090, 64, 77, 30, 9 + LTEXT "&à:", 1091, 120, 77, 30, 9 + LTEXT "&Qualité d'impression:", 1092, 7, 102, 69, 9 + COMBOBOX cmb1, 78, 100, 88, 13, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP + CHECKBOX "Imprimer dans un &fichier", chx1, 7, 117, 93, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Copies t&riées", chx2, 106, 118, 63, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP } -PRINT_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134 +PRINT_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 151 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Configuration de l'impression" FONT 8, "MS Shell Dlg" { - GROUPBOX "Imprimante", grp1, 6, 10, 180, 65, BS_GROUPBOX - RADIOBUTTON "&Imprimante par défaut", rad1, 16, 20, 80, 12 + GROUPBOX "Imprimante", grp1, 6, 6, 180, 74, BS_GROUPBOX + RADIOBUTTON "&Imprimante par défaut", rad1, 16, 22, 90, 12 LTEXT "[aucune]", 1088, 35, 35, 120, 9 - RADIOBUTTON "Imprimante &spécifique", rad2, 16, 50, 80, 12 - COMBOBOX cmb1, 35, 65, 149, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP + RADIOBUTTON "Imprimante &spécifique", rad2, 16, 46, 90, 12 + COMBOBOX cmb1, 35, 60, 146, 17, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP PUSHBUTTON "Annuler", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Options...", psh1, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP - GROUPBOX "Orientation", grp2, 6, 85, 100, 50, BS_GROUPBOX - RADIOBUTTON "&Portrait", rad3, 50, 100, 40, 12 - RADIOBUTTON "Paysag&e", rad4, 50, 115, 40, 12 - ICON "LANDSCAP", stc10, 10, 95, 32, 32 - ICON "PORTRAIT", stc11, 10, 95, 32, 32 - GROUPBOX "Papier", grp3, 120, 85, 180, 50, BS_GROUPBOX - LTEXT "&Taille :", 1089, 130, 95, 30, 9 - LTEXT "&Source :", 1090, 130, 110, 30, 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 + GROUPBOX "Orientation", grp2, 6, 90, 100, 50, BS_GROUPBOX + RADIOBUTTON "&Portrait", rad3, 50, 105, 40, 12 + RADIOBUTTON "Pa&ysage", rad4, 50, 120, 40, 12 + ICON "LANDSCAP", stc10, 10, 100, 21, 20 + ICON "PORTRAIT", stc11, 10, 100, 21, 20 + GROUPBOX "Papier", grp3, 120, 90, 135, 50, BS_GROUPBOX + LTEXT "&Taille :", 1089, 125, 103, 30, 9 + LTEXT "&Source :", 1090, 125, 121, 30, 9 + COMBOBOX cmb2, 155, 100, 92, 17, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP + COMBOBOX cmb3, 155, 118, 92, 17, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP } CHOOSE_FONT DIALOG DISCARDABLE 13, 54, 264, 147 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Polices" +CAPTION "Police" FONT 8, "MS Shell Dlg" { - LTEXT "&Police:",stc1 ,6,3,40,9 + LTEXT "&Police :",stc1 ,6,3,40,9 COMBOBOX cmb1 ,6,13,94,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE - LTEXT "St&yle de police:",stc2 ,108,3,44,9 + LTEXT "St&yle :",stc2 ,108,3,44,9 COMBOBOX cmb2,108,13,64,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE - LTEXT "&Taille:",stc3,179,3,30,9 + LTEXT "&Taille :",stc3,179,3,30,9 COMBOBOX cmb3,179,13,32,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE | CBS_SORT DEFPUSHBUTTON "OK",IDOK,218,6,40,14,WS_GROUP @@ -138,15 +145,15 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "A&ppliquer", psh3,218,40,40,14,WS_GROUP PUSHBUTTON "Aid&e" , pshHelp,218,57,40,14,WS_GROUP GROUPBOX "Effets",grp1,6,72,84,34,WS_GROUP - CHECKBOX "&Barré", chx1, 10,82,50,10, BS_AUTOCHECKBOX | WS_TABSTOP - CHECKBOX "&Souligné", chx2, 10,94,50,10, BS_AUTOCHECKBOX - LTEXT "&Couleur:", stc4 ,6,110,30,9 + CHECKBOX "&Barré", chx1, 10,82,50,10, BS_AUTOCHECKBOX | WS_TABSTOP + CHECKBOX "&Souligné", chx2, 10,94,50,10, BS_AUTOCHECKBOX + LTEXT "&Couleur :", stc4 ,6,110,30,9 COMBOBOX cmb4,6,120,84,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Exemple",grp2,98,72,120,36,WS_GROUP - CTEXT "AaBbYyZz",stc5,103,80,109,24,SS_NOPREFIX | NOT WS_VISIBLE - LTEXT "Scr&ipt (translate):",stc7 ,98,114,80,9 - COMBOBOX cmb5,98,124,120,90,CBS_DROPDOWNLIST | CBS_HASSTRINGS | + GROUPBOX "Aperçu",grp2,98,72,120,36,WS_GROUP + CTEXT "\nÀàCcÇçEeÉéÈèÊêIiÃïÎîLlUuÙù12",stc5,103,80,109,24,SS_NOPREFIX | NOT WS_VISIBLE + LTEXT "Sc&ript :",stc7 ,98,110,80,9 + COMBOBOX cmb5,98,120,120,90,CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP } @@ -156,31 +163,31 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Couleurs" FONT 8, "MS Shell Dlg" { - LTEXT "Couleurs de &base :", 1088, 4, 4, 140, 10 - LTEXT "&Couleurs personnalisées :", 1089, 4, 106, 140, 10 - LTEXT "Couleur | &Uni", 1090, 150, 151, 48, 10 - LTEXT "&Rouge :", 726 /*1094*/,249,126,24,10 + LTEXT "Couleurs de base :", 1088, 4, 4, 140, 10 + LTEXT "Couleurs personnalisées :", 1089, 4, 106, 140, 10 + LTEXT "Couleur | &Uni", 1090, 150, 151, 48, 10 + LTEXT "&Rouge :", 726 /*1094*/,249,126,24,10 EDITTEXT 706, 275,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "&Vert :",727/*1095*/,249,140,24,10 + LTEXT "&Vert :",727/*1095*/,249,140,24,10 EDITTEXT 707, 275,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "Bl&eu :",728 /*1096*/,249,154,24,10 + LTEXT "Bl&eu :",728 /*1096*/,249,154,24,10 EDITTEXT 708, 275,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "&Teinte :" ,723 /*1091*/,202,126,22,10 + LTEXT "&Teinte :" ,723 /*1091*/,202,126,22,10 EDITTEXT 703, 226,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "&Sat. :" ,724 /*1092*/,202,140,22,10 + LTEXT "&Satur. :" ,724 /*1092*/,202,140,22,10 EDITTEXT 704, 226,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "&Lum. :" ,725 /*1093*/,202,154,22,10 + LTEXT "&Lum. :" ,725 /*1093*/,202,154,22,10 EDITTEXT 705, 226,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP CONTROL "" ,720,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,14,140,86 CONTROL "" ,721,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,116,140,28 CONTROL "" ,710,"STATIC",WS_BORDER|SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,4,118,116 CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116 CONTROL "" ,709,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,124,40,26 - DEFPUSHBUTTON "Ok", 1, 4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "OK", 1, 4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP PUSHBUTTON "Annuler", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "Aid&e", pshHelp,100,166, 44, 14 - PUSHBUTTON "A&jouter couleur personnalisées", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Définir couleurs personnalisées >>", 719/*1025*/, 4, 150, 142, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Ajouter aux couleurs personnalisées", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Définir les couleurs personnalisées >>", 719/*1025*/, 4, 149, 142, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&i",713,300,200,4,14 /* just a dummy: 'i' is like &i in "sol&id" */ } @@ -190,15 +197,15 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Rechercher" FONT 8, "MS Shell Dlg" { - LTEXT "&Rechercher :", -1, 4, 8, 42, 8 + LTEXT "&Rechercher :", -1, 4, 8, 42, 8 EDITTEXT edt1, 47, 7, 128, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP - CHECKBOX "M&ot seulement", chx1, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Respect des &majuscules/minuscules", chx2, 4, 42, 64, 12, BS_AUTOCHECKBOX | WS_TABSTOP - GROUPBOX "Direction", grp1, 107, 26, 68, 28 - CONTROL "&Haut", rad1, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 111, 38, 20, 12 - CONTROL "&Bas", rad2, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 138, 38, 30, 12 + CHECKBOX "Mots &entiers seulement", chx1, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Respecter la &casse", chx2, 4, 42, 74, 12, BS_AUTOCHECKBOX | WS_TABSTOP + GROUPBOX "Direction", grp1, 103, 26, 72, 28 + CONTROL "&Haut", rad1, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 108, 38, 30, 12 + CONTROL "&Bas", rad2, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 140, 38, 30, 12 - DEFPUSHBUTTON "&Poursuivre", 1, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Suivant", 1, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "Annuler", 2, 182, 23, 50, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "Aid&e", pshHelp, 182, 45, 50, 14, WS_GROUP | WS_TABSTOP } @@ -209,59 +216,59 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Remplacer" FONT 8, "MS Shell Dlg" { - LTEXT "&Rechercher :", -1, 4, 9, 48, 8 - EDITTEXT edt1, 54, 7, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "R&emplacer par :", -1, 4, 26, 48, 8 - EDITTEXT edt2, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP - CHECKBOX "M&ot seulement", chx1, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Respect des &majuscules/minuscules", chx2, 5, 62, 59, 12, BS_AUTOCHECKBOX | WS_TABSTOP + LTEXT "&Rechercher :", -1, 4, 9, 48, 8 + EDITTEXT edt1, 54, 7, 108, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP + LTEXT "R&emplacer par :", -1, 4, 26, 48, 8 + EDITTEXT edt2, 54, 24, 108, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP + CHECKBOX "Mots &entiers uniquement", chx1, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Respecter la &casse", chx2, 5, 62, 74, 12, BS_AUTOCHECKBOX | WS_TABSTOP - DEFPUSHBUTTON "&Poursuivre", 1, 174, 4, 50, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Rempla&cer", psh1, 174, 21, 50, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Remplacer &tout", psh2, 174, 38, 50, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Annuler", IDCANCEL, 174, 55, 50, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Aid&e", pshHelp, 174, 75, 50, 14, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Suivant", 1, 168, 4, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Remplacer", psh1, 168, 21, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Remplacer &tout", psh2, 168, 38, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Annuler", IDCANCEL, 168, 55, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Aid&e", pshHelp, 168, 75, 56, 14, WS_GROUP | WS_TABSTOP } -PRINT32 DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 288, 186 +PRINT32 DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 288, 196 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP | DS_3DLOOK CAPTION "Impression" FONT 8, "MS Shell Dlg" { - DEFPUSHBUTTON "OK", IDOK, 180,164, 48,14, WS_GROUP | BS_DEFPUSHBUTTON - PUSHBUTTON "Annuler", IDCANCEL, 232,164, 48,14, WS_GROUP - PUSHBUTTON "Aid&e", pshHelp, 50, 161, 48,14, WS_GROUP + DEFPUSHBUTTON "OK", IDOK, 178,176, 48,14, WS_GROUP | BS_DEFPUSHBUTTON + PUSHBUTTON "Annuler", IDCANCEL, 231,176, 48,14, WS_GROUP + PUSHBUTTON "Aid&e", pshHelp, 55, 176, 48,14, WS_GROUP GROUPBOX "Imprimante", grp4, 8, 4, 272,84, WS_GROUP - CONTROL "Imprimer dans un fichier", chx1, "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,212,70,64,12 - PUSHBUTTON "Propriétés", psh2, 212, 17, 60,14, WS_GROUP - LTEXT "&Nom :", stc6, 16, 20, 36,8 - COMBOBOX cmb4, 52, 18, 152,152,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP - LTEXT "État :", stc8, 16, 36, 36,10, SS_NOPREFIX - LTEXT "Dummy State", stc12, 52, 36, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Type :", stc7, 16, 48, 36,10, SS_NOPREFIX - LTEXT "Dummy Type", stc11, 52, 48, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Emplacement :", stc10, 16, 60, 36,10, SS_NOPREFIX - LTEXT "Dummy Location", stc14, 52, 60, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Commentaire:", stc9, 16, 72, 36,10, SS_NOPREFIX - LTEXT "Dummy Remark", stc13, 52, 72, 152,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + CONTROL "Imprimer dans un fichier", chx1, "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,185,44,93,14 + PUSHBUTTON "&Propriétés", psh2, 214, 17, 60,14, WS_GROUP + LTEXT "&Nom :", stc6, 16, 20, 36,8 + COMBOBOX cmb4, 65, 18, 145, 15, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP + LTEXT "État :", stc8, 16, 36, 36,10, SS_NOPREFIX + LTEXT "État fictif", stc12, 65, 36, 112,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Type :", stc7, 16, 48, 36,10, SS_NOPREFIX + LTEXT "Type fictif", stc11, 65, 48, 111,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Emplacement :", stc10, 16, 60, 47,10, SS_NOPREFIX + LTEXT "Emplacement fictif", stc14, 65, 60, 211,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Commentaire:", stc9, 16, 72, 47, 10, SS_NOPREFIX + LTEXT "Remarque fictive", stc13, 65, 72, 144, 10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - GROUPBOX "Copies", grp2, 160, 92, 120,64, WS_GROUP + GROUPBOX "Copies", grp2, 160, 92, 120,73, WS_GROUP LTEXT "Nombre de copies:",stc5,168,108,68,8 - ICON "", ico3, 162,124, 76,24, WS_GROUP | SS_CENTERIMAGE - CONTROL "Copies assemblées",chx2,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,240,130,36,12 + ICON "", ico3, 183,121,76,24, WS_GROUP | SS_CENTERIMAGE + CONTROL "Copies assemblées",chx2,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,167,148,77,12 EDITTEXT edt3, 240,106, 32,12, WS_GROUP | ES_NUMBER - GROUPBOX "Etendue de pages", grp1, 8,92, 144,64, WS_GROUP - CONTROL "Toutes", rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,106,64,12 - CONTROL "Pages", rad3,"Button",BS_AUTORADIOBUTTON,16,122,36,12 - CONTROL "Selection", rad2,"Button",BS_AUTORADIOBUTTON,16,138,64,12 - EDITTEXT edt1, 74,122, 26,12, WS_GROUP | ES_NUMBER - EDITTEXT edt2, 118,122, 26,12, WS_GROUP | ES_NUMBER - RTEXT "&de :", stc2, 52,124, 20,8 - RTEXT "&à :", stc3, 100,124, 16,8 + GROUPBOX "Zone d'impression", grp1, 8,92, 144,73, WS_GROUP + CONTROL "&Tout", rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,108,64,12 + CONTROL "&Pages", rad3,"Button",BS_AUTORADIOBUTTON,16,124,36,12 + CONTROL "&Sélection", rad2,"Button",BS_AUTORADIOBUTTON,16,140,64,12 + EDITTEXT edt1, 74,124, 26,12, WS_GROUP | ES_NUMBER + EDITTEXT edt2, 118,124, 26,12, WS_GROUP | ES_NUMBER + RTEXT "&de :", stc2, 52,127, 20,8 + RTEXT "&à :", stc3, 100,127, 16,8 } PRINT32_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 288, 178 @@ -272,20 +279,20 @@ FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "OK",IDOK,180,156,48,14,WS_GROUP PUSHBUTTON "Annuler",IDCANCEL,232,156,48,14 -/* PUSHBUTTON "Réseau...", psh5, 284,156,48,14 */ +/* PUSHBUTTON "Réseau...", psh5, 284,156,48,14 */ GROUPBOX "Imprimante", grp4, 8, 4, 272,84, WS_GROUP - PUSHBUTTON "&Propriétés", psh2, 212, 17, 60,14, WS_GROUP - LTEXT "&Nom :", stc6, 16, 20, 36,8 - COMBOBOX cmb1, 52, 18, 152,152,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP - LTEXT "État:", stc8, 16, 36, 36,10, SS_NOPREFIX - LTEXT "[aucun]", stc12, 60, 36, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + PUSHBUTTON "&Propriétés", psh2, 214, 17, 60,14, WS_GROUP + LTEXT "&Nom :", stc6, 16, 20, 36,8 + COMBOBOX cmb1, 65, 18, 145,15,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP + LTEXT "État:", stc8, 16, 36, 36,10, SS_NOPREFIX + LTEXT "État fictif", stc12, 65, 36, 210,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP LTEXT "Type:", stc7, 16, 48, 36,10, SS_NOPREFIX - LTEXT "[aucun]", stc11, 60, 48, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Emplacement :", stc10, 16, 60, 36,10, SS_NOPREFIX - LTEXT "[aucun]", stc14, 60, 60, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Commentaire :", stc9, 16, 72, 36,10, SS_NOPREFIX - LTEXT "[aucun]", stc13, 60, 72, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Type fictif", stc11, 65, 48, 210,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Emplacement :", stc10, 16, 60, 47,10, SS_NOPREFIX + LTEXT "Emplacement fictif", stc14, 65, 60, 210,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Commentaire :", stc9, 16, 72, 47,10, SS_NOPREFIX + LTEXT "Commentaire fictif", stc13, 65, 72, 210,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP GROUPBOX "Papier", grp2, 8, 92, 164,56, WS_GROUP LTEXT "&Taille:", stc2, 16,108, 36, 8 @@ -296,10 +303,10 @@ BEGIN GROUPBOX "Orientation", grp1, 180, 92, 100,56, WS_GROUP ICON "", ico1, 195,112, 18,20, WS_GROUP CONTROL "&Portrait", rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP |WS_TABSTOP,224,106,52,12 - CONTROL "&Paysage", rad2,"Button",BS_AUTORADIOBUTTON,224,126,52,12 + CONTROL "Pa&ysage", rad2,"Button",BS_AUTORADIOBUTTON,224,126,52,12 END -PAGESETUPDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 240, 240 +PAGESETUPDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 242, 240 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Mise en page" FONT 8, "MS Shell Dlg" @@ -307,26 +314,26 @@ 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 "Papier", grp2, 8, 96, 224, 56, BS_GROUPBOX - LTEXT "&Taille :", stc2, 16, 112, 36, 8 - COMBOBOX cmb2, 64, 110, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL - LTEXT "&Source :", stc3, 16, 132, 36, 8 - COMBOBOX cmb3, 64, 130, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL + GROUPBOX "Papier", grp2, 8, 96, 228, 56, BS_GROUPBOX + LTEXT "&Taille :", stc2, 16, 112, 36, 8 + COMBOBOX cmb2, 64, 110, 167, 15, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL + LTEXT "&Bac :", stc3, 16, 132, 36, 8 + COMBOBOX cmb3, 64, 130, 167, 15, 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 "P&aysage", rad2, 16, 190, 52, 12, BS_AUTORADIOBUTTON - GROUPBOX "Marges", grp4, 80, 156, 152, 56, BS_GROUPBOX - LTEXT "&Droite :", stc15, 88, 172, 21, 8 - EDITTEXT edt4, 111, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER - LTEXT "&Gauche :", stc16, 159, 172, 27, 8 - EDITTEXT edt6, 187, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER - LTEXT "&Haut :", stc17, 88, 192, 21, 8 - EDITTEXT edt5, 111, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER - LTEXT "&Bas :", stc18, 159, 192, 23, 8 - EDITTEXT edt7, 187, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER - DEFPUSHBUTTON "OK", IDOK, 71, 220, 50, 14, BS_PUSHBUTTON - PUSHBUTTON "Annuler", IDCANCEL, 126, 220, 50, 14 - PUSHBUTTON "&Imprimante...", psh3, 184, 220, 48, 14 + AUTORADIOBUTTON "Pa&ysage", rad2, 16, 190, 52, 12, BS_AUTORADIOBUTTON + GROUPBOX "Marges", grp4, 80, 156, 156, 56, BS_GROUPBOX + LTEXT "&Gauche :", stc15, 88, 172, 29, 8 + EDITTEXT edt4, 119, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER + LTEXT "&Droite :", stc16, 163, 172, 27, 8 + EDITTEXT edt6, 190, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER + LTEXT "&Haut :", stc17, 88, 192, 21, 8 + EDITTEXT edt5, 119, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER + LTEXT "&Bas :", stc18, 163, 192, 23, 8 + EDITTEXT edt7, 190, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER + DEFPUSHBUTTON "OK", IDOK, 70, 220, 51, 14, BS_PUSHBUTTON + PUSHBUTTON "Annuler", IDCANCEL, 125, 220, 51, 14 + PUSHBUTTON "&Imprimante...", psh3, 184, 220, 51, 14 END NEWFILEOPENORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 280, 164 @@ -340,13 +347,13 @@ FONT 8, "MS Shell Dlg" 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 "&Nom du fichier :",IDC_FILENAMESTATIC,5,112,46,8, SS_NOTIFY - EDITTEXT IDC_FILENAME,54,110,155,12,ES_AUTOHSCROLL + LTEXT "&Nom du fichier",IDC_FILENAMESTATIC,5,112,50,8, SS_NOTIFY + EDITTEXT IDC_FILENAME,59,110,155,12,ES_AUTOHSCROLL - LTEXT "&Type du fichier",IDC_FILETYPESTATIC,5,128,42,8, SS_NOTIFY - COMBOBOX IDC_FILETYPE,54,126,155,53,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Fichiers de &type",IDC_FILETYPESTATIC,5,128,52,8, SS_NOTIFY + COMBOBOX IDC_FILETYPE,59,126,155,53,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "&Protection écriture",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,145,100,10 + CONTROL "&Lecture seule",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,59,145,100,10 DEFPUSHBUTTON "Ouvrir", IDOK,222,110,50,14 PUSHBUTTON "Annuler", IDCANCEL,222,128,50,14 @@ -355,11 +362,11 @@ FONT 8, "MS Shell Dlg" STRINGTABLE DISCARDABLE { - IDS_ABOUTBOX "À propos du choix de répertoires" - IDS_DOCUMENTFOLDERS "Répertoire documents" + IDS_ABOUTBOX "À propos du XXX choix de répertoires" + IDS_DOCUMENTFOLDERS "Répertoires des documents" IDS_PERSONAL "Mes documents" IDS_FAVORITES "Mes favoris" - IDS_PATH "Répertoire système" + IDS_PATH "Chemin système (path)" IDS_DESKTOP "Bureau" IDS_FONTS "Polices" IDS_MYCOMPUTER "Poste de travail" @@ -367,24 +374,24 @@ STRINGTABLE DISCARDABLE STRINGTABLE DISCARDABLE { - IDS_SYSTEMFOLDERS "Répertoires système" + IDS_SYSTEMFOLDERS "Répertoires système" IDS_LOCALHARDRIVES "Disques locaux" - IDS_FILENOTFOUND "Fichier non trouvé" - IDS_VERIFYFILE "Prière de vérifier que le nom de fichier indiqué est correct" - IDS_CREATEFILE "Ce fichier n'existe pas.\nSouhaitez-vous le créer ?" - IDS_OVERWRITEFILE "Ce fichier existe déjà.\nVoulez-vous le remplacer ?" - IDS_INVALID_FILENAME_TITLE "Le chemin d'accès contient des caractères invalides" - IDS_INVALID_FILENAME "Un nom de fichier ne peut contenir un des caractères suivants :\n / : < > |" - IDS_PATHNOTEXISTING "Le chemin d'accès n'existe pas" + IDS_FILENOTFOUND "Fichier non trouvé" + IDS_VERIFYFILE "Veuillez vérifier que le nom de fichier indiqué est correct" + IDS_CREATEFILE "Ce fichier n'existe pas.\nSouhaitez-vous le créer ?" + IDS_OVERWRITEFILE "Ce fichier existe déjà.\nVoulez-vous le remplacer ?" + IDS_INVALID_FILENAME_TITLE "Le chemin d'accès contient des caractères invalides" + IDS_INVALID_FILENAME "Un nom de fichier ne peut contenir aucun des caractères suivants :\n / : < > |" + IDS_PATHNOTEXISTING "Le chemin d'accès n'existe pas" IDS_FILENOTEXISTING "Le fichier n'existe pas" } STRINGTABLE DISCARDABLE { IDS_UPFOLDER "Remonter d'un niveau" - IDS_NEWFOLDER "Créer un nouveau dossier" + IDS_NEWFOLDER "Créer un nouveau dossier" IDS_LISTVIEW "Liste" - IDS_REPORTVIEW "Détails" + IDS_REPORTVIEW "Détails" IDS_TODESKTOP "Voir le bureau" } @@ -392,59 +399,59 @@ STRINGTABLE DISCARDABLE { PD32_PRINT_TITLE "Imprimer" - PD32_VALUE_UREADABLE "Entrée illisible" - PD32_INVALID_PAGE_RANGE "Cette valeur n'est pas dans l'intervalle de pages\n\ + PD32_VALUE_UREADABLE "Entrée illisible" + PD32_INVALID_PAGE_RANGE "Cette valeur n'est pas dans l'étendue de pages\n\ Veuillez indiquer une valeur entre %d et %d." - PD32_FROM_NOT_ABOVE_TO "Le champ « de » ne peut être plus grand \ -que le champ « à »." - PD32_MARGINS_OVERLAP "Les marges se recouvrent ou dépassent du papier\n\ + PD32_FROM_NOT_ABOVE_TO "Le champ « de » ne peut être plus grand \ +que le champ « à »." + PD32_MARGINS_OVERLAP "Les marges se chevauchent ou dépassent du papier\n\ Veuillez indiquer de nouvelles valeurs." - PD32_NR_OF_COPIES_EMPTY "Le champ « Copies » est vide.\n\ + PD32_NR_OF_COPIES_EMPTY "Le champ « Nombre de copies » est vide.\n\ Veuillez entrer un nombre et r&essayer." - PD32_TOO_LARGE_COPIES "Votre imprimante ne peut gérer autant de copies.\n\ + PD32_TOO_LARGE_COPIES "Votre imprimante ne peut gérer autant de copies.\n\ Veuillez indiquer un nombre de copies entre 1 et %d." - PD32_PRINT_ERROR "Une erreur d'impression est intervenue." - PD32_NO_DEFAULT_PRINTER "Pas d'imprimante par défaut." + PD32_PRINT_ERROR "Une erreur d'impression s'est produite." + PD32_NO_DEFAULT_PRINTER "Imprimante par défaut non définie." PD32_CANT_FIND_PRINTER "Impossible de trouver l'imprimante." - PD32_OUT_OF_MEMORY "Pas assez de mémoire." - PD32_GENERIC_ERROR "Une erreur est intervenue." + PD32_OUT_OF_MEMORY "Pas assez de mémoire." + PD32_GENERIC_ERROR "Une erreur s'est produite." PD32_DRIVER_UNKNOWN "Pilote d'imprimante inconnu." - PD32_NO_DEVICES "Avant de pouvoir effectuer des opérations en relation avec l'impression \ + PD32_NO_DEVICES "Avant de pouvoir effectuer des opérations en relation avec l'impression \ comme la configuration de l'imprimante ou l'impression d'un document, vous devez installer une imprimante. \ -Veuillez en installer une et réessayez." +Veuillez en installer une et réessayez." - PD32_DEFAULT_PRINTER "Imprimante par défaut ; " + PD32_DEFAULT_PRINTER "Imprimante par défaut ; " PD32_NR_OF_DOCUMENTS_IN_QUEUE "Il y a %d documents dans la file d'attente" - PD32_MARGINS_IN_INCHES "Marges [pouces]" - PD32_MARGINS_IN_MILLIMETERS "Marges [mm]" + PD32_MARGINS_IN_INCHES "Marges (pouces]" + PD32_MARGINS_IN_MILLIMETERS "Marges (mm)" PD32_MILLIMETERS "mm" - PD32_PRINTER_STATUS_READY "Prêt" - PD32_PRINTER_STATUS_PAUSED "Suspendu ; " - PD32_PRINTER_STATUS_ERROR "Erreur ; " - PD32_PRINTER_STATUS_PENDING_DELETION "En attente de suppression ; " - PD32_PRINTER_STATUS_PAPER_JAM "Bourrage papier ; " - PD32_PRINTER_STATUS_PAPER_OUT "Plus de papier ; " - PD32_PRINTER_STATUS_MANUAL_FEED "Insertion manuelle du papier ; " - PD32_PRINTER_STATUS_PAPER_PROBLEM "Problème de papier; " - PD32_PRINTER_STATUS_OFFLINE "L'imprimante n'est pas en ligne; " - PD32_PRINTER_STATUS_IO_ACTIVE "IO Active; " - PD32_PRINTER_STATUS_BUSY "Occupée; " - PD32_PRINTER_STATUS_PRINTING "En cours d'impression; " - PD32_PRINTER_STATUS_OUTPUT_BIN_FULL "Le bac de sortie est plein; " - PD32_PRINTER_STATUS_NOT_AVAILABLE "Non disponible ; " - PD32_PRINTER_STATUS_WAITING "En attente ; " - PD32_PRINTER_STATUS_PROCESSING "Traitement en cours ; " - PD32_PRINTER_STATUS_INITIALIZING "Démarrage en cours ; " - PD32_PRINTER_STATUS_WARMING_UP "Préchauffage ; " - PD32_PRINTER_STATUS_TONER_LOW "Toner presque vide ; " - PD32_PRINTER_STATUS_NO_TONER "Pas de toner ; " - PD32_PRINTER_STATUS_PAGE_PUNT "Abandon de page ; " - PD32_PRINTER_STATUS_USER_INTERVENTION "Annulé par utilisateur ; " - PD32_PRINTER_STATUS_OUT_OF_MEMORY "Plus assez de mémoire ; " - PD32_PRINTER_STATUS_DOOR_OPEN "La porte de l'imprimante est ouverte ; " - PD32_PRINTER_STATUS_SERVER_UNKNOWN "Serveur d'impression inconnu ; " - PD32_PRINTER_STATUS_POWER_SAVE "Mode économie d'énergie ; " + PD32_PRINTER_STATUS_READY "Prêt" + PD32_PRINTER_STATUS_PAUSED "Suspendu ; " + PD32_PRINTER_STATUS_ERROR "Erreur ; " + PD32_PRINTER_STATUS_PENDING_DELETION "En attente de suppression ; " + PD32_PRINTER_STATUS_PAPER_JAM "Bourrage papier ; " + PD32_PRINTER_STATUS_PAPER_OUT "Plus de papier ; " + PD32_PRINTER_STATUS_MANUAL_FEED "Insertion manuelle du papier ; " + PD32_PRINTER_STATUS_PAPER_PROBLEM "Problème de papier ; " + PD32_PRINTER_STATUS_OFFLINE "L'imprimante n'est pas en ligne ; " + PD32_PRINTER_STATUS_IO_ACTIVE "E/S Active ; " + PD32_PRINTER_STATUS_BUSY "Occupée ; " + PD32_PRINTER_STATUS_PRINTING "En cours d'impression ; " + PD32_PRINTER_STATUS_OUTPUT_BIN_FULL "Le bac de sortie est plein ; " + PD32_PRINTER_STATUS_NOT_AVAILABLE "Non disponible ; " + PD32_PRINTER_STATUS_WAITING "En attente ; " + PD32_PRINTER_STATUS_PROCESSING "Traitement en cours ; " + PD32_PRINTER_STATUS_INITIALIZING "Démarrage en cours ; " + PD32_PRINTER_STATUS_WARMING_UP "Préchauffage ; " + PD32_PRINTER_STATUS_TONER_LOW "Toner presque vide ; " + PD32_PRINTER_STATUS_NO_TONER "Pas de toner ; " + PD32_PRINTER_STATUS_PAGE_PUNT "Abandon de page ; " + PD32_PRINTER_STATUS_USER_INTERVENTION "Interrompu par utilisateur ; " + PD32_PRINTER_STATUS_OUT_OF_MEMORY "Plus assez de mémoire ; " + PD32_PRINTER_STATUS_DOOR_OPEN "La porte de l'imprimante est ouverte ; " + PD32_PRINTER_STATUS_SERVER_UNKNOWN "Serveur d'impression inconnu ; " + PD32_PRINTER_STATUS_POWER_SAVE "Mode économie d'énergie ; " } STRINGTABLE DISCARDABLE /* Font styles */ @@ -464,24 +471,24 @@ STRINGTABLE DISCARDABLE /* Color names */ IDS_COLOR_OLIVE "Olive" IDS_COLOR_NAVY "Bleu marine" IDS_COLOR_PURPLE "Pourpre" - IDS_COLOR_TEAL "Turquoise" + IDS_COLOR_TEAL "Sarcelle" IDS_COLOR_GRAY "Gris" IDS_COLOR_SILVER "Argent" IDS_COLOR_RED "Rouge" - IDS_COLOR_LIME "Lime" + IDS_COLOR_LIME "Citron vert" IDS_COLOR_YELLOW "Jaune" IDS_COLOR_BLUE "Bleu" IDS_COLOR_FUCHSIA "Fuchsia" - IDS_COLOR_AQUA "Aqua" + IDS_COLOR_AQUA "Eau" IDS_COLOR_WHITE "Blanc" } STRINGTABLE DISCARDABLE { - IDS_FONT_SIZE "Sélectionnez une taille de police entre %d et %d points." - IDS_SAVE_BUTTON "&Sauver" - IDS_SAVE_IN "Sauver &dans :" + IDS_FONT_SIZE "Sélectionnez une taille de police entre %d et %d points." + IDS_SAVE_BUTTON "&Enregistrer" + IDS_SAVE_IN "Enregistrer &dans :" IDS_SAVE "Enregistrer" IDS_SAVE_AS "Enregistrer sous" - IDS_OPEN_FILE "Ouvrir Fichier" + IDS_OPEN_FILE "Ouvrir fichier" } diff --git a/reactos/dll/win32/comdlg32/cdlg_Hu.rc b/reactos/dll/win32/comdlg32/cdlg_Hu.rc index 3df3b2a4e70..3bf7104c91b 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Hu.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Hu.rc @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_It.rc b/reactos/dll/win32/comdlg32/cdlg_It.rc index f48b403f83d..beb9bd77849 100644 --- a/reactos/dll/win32/comdlg32/cdlg_It.rc +++ b/reactos/dll/win32/comdlg32/cdlg_It.rc @@ -18,6 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Ja.rc b/reactos/dll/win32/comdlg32/cdlg_Ja.rc index e29f2624d81..0e0358f1f01 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Ja.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Ja.rc @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ @@ -483,5 +486,3 @@ STRINGTABLE DISCARDABLE IDS_SAVE_AS "åå‰ã‚’付ã‘ã¦ä¿å­˜" IDS_OPEN_FILE "ファイルを開ã" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/comdlg32/cdlg_Ko.rc b/reactos/dll/win32/comdlg32/cdlg_Ko.rc index 74467935fdd..1fc97981b71 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Ko.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Ko.rc @@ -18,6 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Lt.rc b/reactos/dll/win32/comdlg32/cdlg_Lt.rc index 1610413ce7a..c4bbf982d6d 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Lt.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Lt.rc @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ @@ -76,14 +79,14 @@ FONT 8, "MS Shell Dlg" { LTEXT "Spausdintuvas:", 1088, 6, 6, 50, 9 LTEXT "", 1089, 60, 6, 150, 9 - GROUPBOX "Spausdinimo intervalas", grp1, 6, 30, 160, 65, BS_GROUPBOX + GROUPBOX "Spausdinimo rėžis", grp1, 6, 30, 160, 65, BS_GROUPBOX RADIOBUTTON "&Viskas", rad1, 16, 45, 60, 12 RADIOBUTTON "PažymÄ—tas &tekstas", rad2, 16, 60, 76, 12 RADIOBUTTON "&Puslapiai", rad3, 16, 75, 60, 12 DEFPUSHBUTTON "Spausdinti", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP PUSHBUTTON "Atsisakyti", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Nuostatos", psh1, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP - LTEXT "&nuo:", 1090, 60, 80, 30, 9 + LTEXT "n&uo:", 1090, 60, 80, 30, 9 LTEXT "&iki:", 1091, 120, 80, 30, 9 LTEXT "Spausdinimo &kokybÄ—:", 1092, 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 @@ -144,7 +147,7 @@ FONT 8, "MS Shell Dlg" CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP GROUPBOX "Pavyzdys",grp2,98,72,120,36,WS_GROUP CTEXT "AaĄąZzŽž",stc5,103,80,109,24,SS_NOPREFIX | NOT WS_VISIBLE - LTEXT "Sim&bolių rinkinys:",stc7 ,98,114,60,9 + LTEXT "Si&mbolių rinkinys:",stc7 ,98,114,60,9 COMBOBOX cmb5,98,124,120,90,CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP } @@ -156,11 +159,11 @@ CAPTION "Spalva" FONT 8, "MS Shell Dlg" { LTEXT "&PagrindinÄ—s spalvos:", 1088, 4, 4, 140, 10 - LTEXT "&Individualios spalvos:", 1089, 4, 106, 140, 10 + LTEXT "Pr&itaikytos spalvos:", 1089, 4, 106, 140, 10 LTEXT "Spal. | Vient.", 1090, 150, 151, 48, 10 LTEXT "&Raudona:", 726 /*1094*/,243,126,32,10 EDITTEXT 706, 275,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "&Žalia:",727/*1095*/,243,140,24,10 + LTEXT "Ža&lia:",727/*1095*/,243,140,24,10 EDITTEXT 707, 275,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP LTEXT "&MÄ—lyna:",728 /*1096*/,243,154,24,10 EDITTEXT 708, 275,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP @@ -178,8 +181,8 @@ FONT 8, "MS Shell Dlg" DEFPUSHBUTTON "Gerai", 1, 4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP PUSHBUTTON "Atsisakyti", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Žinynas", pshHelp,100,166, 44, 14 - PUSHBUTTON "&Ä®dÄ—ti prie individualių spalvų", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "A&pibrėžti individualias spalvas >>", 719/*1025*/, 4, 150, 142, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Ä®dÄ—ti prie pritaikytų spalvų", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Api&brėžti pritaikytas spalvas >>", 719/*1025*/, 4, 150, 142, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&i",713,300,200,4,14 /* just a dummy: 'i' is like &i in "sol&id" */ } @@ -195,7 +198,7 @@ FONT 8, "MS Shell Dlg" CHECKBOX "Skirti raidžių &dydį", chx2, 4, 42, 70, 12, BS_AUTOCHECKBOX | WS_TABSTOP GROUPBOX "Kryptis", grp1, 89, 26, 86, 28 CONTROL "&AukÅ¡tyn", rad1, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 93, 38, 40, 12 - CONTROL "&Žemyn", rad2, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 134, 38, 36, 12 + CONTROL "Ž&emyn", rad2, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 134, 38, 36, 12 DEFPUSHBUTTON "IeÅ¡koti &kito", IDOK, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON PUSHBUTTON "Atsisakyti", IDCANCEL , 182, 23, 50, 14, WS_GROUP | WS_TABSTOP @@ -210,7 +213,7 @@ FONT 8, "MS Shell Dlg" { LTEXT "Ko &ieÅ¡koti:", -1, 4, 9, 48, 8 EDITTEXT edt1, 54, 7, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "Kuo pa&keisti:", -1, 4, 26, 48, 8 + LTEXT "Kuo pak&eisti:", -1, 4, 26, 48, 8 EDITTEXT edt2, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP CHECKBOX "Tenkina tik &visas žodis", chx1, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP CHECKBOX "Skirti raidžių &dydį", chx2, 5, 62, 70, 12, BS_AUTOCHECKBOX | WS_TABSTOP @@ -253,7 +256,7 @@ FONT 8, "MS Shell Dlg" CONTROL "Su&dÄ—st.", chx2,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,240,130,36,12 EDITTEXT edt3, 240,106, 32,12, WS_GROUP | ES_NUMBER - GROUPBOX "Intervalas", grp1, 8,92, 144,64, WS_GROUP + GROUPBOX "Rėžis", grp1, 8,92, 144,64, WS_GROUP CONTROL "V&isi puslapiai", rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,106,64,12 CONTROL "Pu&slapiai", rad3,"Button",BS_AUTORADIOBUTTON,16,122,40,12 CONTROL "PažymÄ—tas &tekstas", rad2,"Button",BS_AUTORADIOBUTTON,16,138,72,12 @@ -309,7 +312,7 @@ BEGIN GROUPBOX "Popierius", grp2, 8, 96, 224, 56, BS_GROUPBOX LTEXT "&Dydis:", stc2, 16, 112, 36, 8 COMBOBOX cmb2, 64, 110, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL - LTEXT "DÄ—&klas:", stc3, 16, 132, 36, 8 + LTEXT "DÄ—k&las:", stc3, 16, 132, 36, 8 COMBOBOX cmb3, 64, 130, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL GROUPBOX "PadÄ—tis", grp1, 8, 156, 64, 56, BS_GROUPBOX AUTORADIOBUTTON "&StaÄias", rad1, 16, 170, 52, 12, BS_AUTORADIOBUTTON @@ -339,7 +342,7 @@ FONT 8, "MS Shell Dlg" 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 "Failo &vardas:",IDC_FILENAMESTATIC,5,112,46,8, SS_NOTIFY + LTEXT "&Failo vardas:",IDC_FILENAMESTATIC,5,112,46,8, SS_NOTIFY EDITTEXT IDC_FILENAME,54,110,155,12,ES_AUTOHSCROLL LTEXT "Failų &tipai:",IDC_FILETYPESTATIC,5,128,42,8, SS_NOTIFY @@ -392,25 +395,23 @@ STRINGTABLE DISCARDABLE PD32_PRINT_TITLE "Spausdinti" PD32_VALUE_UREADABLE "Neperskaitomas įraÅ¡as" - PD32_INVALID_PAGE_RANGE "Å i reikÅ¡mÄ— nepatenka į puslapių intervalÄ….\n\ -PraÅ¡ome įvesti reikÅ¡mÄ™ tarp %d ir %d." - PD32_FROM_NOT_ABOVE_TO "'Nuo' reikÅ¡mÄ— negali virÅ¡yti \ -'iki' reikÅ¡mÄ—s." - PD32_MARGINS_OVERLAP "ParaÅ¡tÄ—s persidengia arba iÅ¡eina už \ -popieriaus ribų.\nPraÅ¡ome įvesti paraÅ¡tes iÅ¡ naujo." - PD32_NR_OF_COPIES_EMPTY "SkaitinÄ— 'Kopijų skaiÄius' \ -reikÅ¡mÄ— negali bÅ«ti tuÅ¡Äia." - PD32_TOO_LARGE_COPIES "Toks didelis kopijų skaiÄius yra \ -nepalaikomas jÅ«sų spausdintuvo.\nPraÅ¡ome įvesti reikÅ¡mÄ™ tarp 1 ir %d." + PD32_INVALID_PAGE_RANGE "Å i reikÅ¡mÄ— nepatenka į puslapių rėžį.\n\ + PraÅ¡ome įvesti reikÅ¡mÄ™ tarp %d ir %d." + PD32_FROM_NOT_ABOVE_TO "„Nuo“ reikÅ¡mÄ— negali virÅ¡yti „iki“ reikÅ¡mÄ—s." + PD32_MARGINS_OVERLAP "ParaÅ¡tÄ—s persidengia arba iÅ¡eina už popieriaus ribų.\n\ + PraÅ¡ome įvesti paraÅ¡tes iÅ¡ naujo." + PD32_NR_OF_COPIES_EMPTY "SkaitinÄ— „kopijų skaiÄius“ reikÅ¡mÄ— negali bÅ«ti tuÅ¡Äia." + PD32_TOO_LARGE_COPIES "Toks didelis kopijų skaiÄius yra nepalaikomas jÅ«sų spausdintuvo.\n\ + PraÅ¡ome įvesti reikÅ¡mÄ™ tarp 1 ir %d." PD32_PRINT_ERROR "Ä®vyko spausdintuvo klaida." PD32_NO_DEFAULT_PRINTER "Nenurodytas pagrindinis spausdintuvas." PD32_CANT_FIND_PRINTER "Nepavyko rasti spausdintuvo." - PD32_OUT_OF_MEMORY "BaigÄ—si atmintis." + PD32_OUT_OF_MEMORY "TrÅ«ksta atminties." PD32_GENERIC_ERROR "Ä®vyko klaida." PD32_DRIVER_UNKNOWN "Nežinoma spausdintuvo tvarkyklÄ—." PD32_NO_DEVICES "PrieÅ¡ atlikdami su spausdintuvu susijusius veiksmus, \ tokius kaip puslapio nuostatų keitimas ar dokumento spausdinimas, turite įdiegti spausdintuvÄ…. \ -PraÅ¡ome įdeigti spausdintuvÄ… ir pakartoti." +PraÅ¡ome įdiegti spausdintuvÄ… ir pakartoti." PD32_DEFAULT_PRINTER "Pagrindinis spausdintuvas; " PD32_NR_OF_DOCUMENTS_IN_QUEUE "EilÄ—je yra %d dokumentų" @@ -440,7 +441,7 @@ PraÅ¡ome įdeigti spausdintuvÄ… ir pakartoti." PD32_PRINTER_STATUS_NO_TONER "NÄ—ra dažų; " PD32_PRINTER_STATUS_PAGE_PUNT "Puslapis perkrautas; " PD32_PRINTER_STATUS_USER_INTERVENTION "Pertraukta naudotojo; " - PD32_PRINTER_STATUS_OUT_OF_MEMORY "BaigÄ—si atmintis; " + PD32_PRINTER_STATUS_OUT_OF_MEMORY "TrÅ«ksta atminties; " PD32_PRINTER_STATUS_DOOR_OPEN "Spausdintuvo durelÄ—s atidarytos; " PD32_PRINTER_STATUS_SERVER_UNKNOWN "Spausdinimo serveris nežinomas; " PD32_PRINTER_STATUS_POWER_SAVE "Energijos taupymo režimas; " @@ -470,7 +471,7 @@ STRINGTABLE DISCARDABLE /* Color names */ IDS_COLOR_YELLOW "Geltona" IDS_COLOR_BLUE "MÄ—lyna" IDS_COLOR_FUCHSIA "Fuksija" - IDS_COLOR_AQUA "Akvarelinis cianas" + IDS_COLOR_AQUA "Žydra" IDS_COLOR_WHITE "Balta" } @@ -483,4 +484,3 @@ STRINGTABLE DISCARDABLE IDS_SAVE_AS "IÅ¡saugoti kaip" IDS_OPEN_FILE "Atverti failÄ…" } -#pragma code_page(default) diff --git a/reactos/dll/win32/comdlg32/cdlg_Nl.rc b/reactos/dll/win32/comdlg32/cdlg_Nl.rc index 6910405154e..340c2db8691 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Nl.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Nl.rc @@ -17,6 +17,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ @@ -237,7 +240,7 @@ FONT 8, "MS Shell Dlg" LTEXT "Bestands&typen:",IDC_FILETYPESTATIC,5,128,48,8, SS_NOTIFY COMBOBOX IDC_FILETYPE,54,126,155,53,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Openen met als kenmerk &Alleen-lezen",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,145,100,10 + CONTROL "Openen met als kenmerk &Alleen-lezen",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,145,140,10 DEFPUSHBUTTON "&Openen", IDOK,222,110,50,14 PUSHBUTTON "Annuleren", IDCANCEL,222,128,50,14 diff --git a/reactos/dll/win32/comdlg32/cdlg_No.rc b/reactos/dll/win32/comdlg32/cdlg_No.rc index e1d35f5416a..75e8f792405 100644 --- a/reactos/dll/win32/comdlg32/cdlg_No.rc +++ b/reactos/dll/win32/comdlg32/cdlg_No.rc @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Pl.rc b/reactos/dll/win32/comdlg32/cdlg_Pl.rc index 796054b6db3..71c1afebe5f 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Pl.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Pl.rc @@ -18,6 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Pt.rc b/reactos/dll/win32/comdlg32/cdlg_Pt.rc index 2da9de53fdf..b061f613146 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Pt.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Pt.rc @@ -1,7 +1,8 @@ /* * Copyright 1997 Ricardo R. Massaro * Copyright 2003 Marcelo Duarte - * Copyright 2006-2007 Américo José Melo + * Copyright 2006-2007 Américo José Melo + * Copyright 2009 Ricardo Filipe * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,10 +19,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ +#pragma code_page(65001) + LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN OPEN_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134 @@ -32,7 +38,7 @@ FONT 8, "MS Shell Dlg" LTEXT "Nome do &Arquivo:", 1090, 6, 6, 76, 9 EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "&Diretórios:", -1, 110, 6, 92, 9 + LTEXT "&Diretórios:", -1, 110, 6, 92, 9 LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP LTEXT "Listar Arquivos do &Tipo:", 1089, 6, 104, 90, 9 @@ -55,7 +61,7 @@ FONT 8, "MS Shell Dlg" LTEXT "Nome do &Ficheiro:", 1090, 6, 6, 76, 9 EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "&Directórios:", -1, 110, 6, 92, 9 + LTEXT "&Directórios:", -1, 110, 6, 92, 9 LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP LTEXT "Listar Ficheiros do &Tipo:", 1089, 6, 104, 90, 9 @@ -79,7 +85,7 @@ FONT 8, "MS Shell Dlg" LTEXT "Nome do &Arquivo:", 1090, 6, 6, 76, 9 EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "&Diretórios:", -1, 110, 6, 92, 9 + LTEXT "&Diretórios:", -1, 110, 6, 92, 9 LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP LTEXT "Listar Arquivos do &Tipo:", 1089, 6, 104, 90, 9 @@ -102,7 +108,7 @@ FONT 8, "MS Shell Dlg" LTEXT "Nome do &Ficheiro:", 1090, 6, 6, 76, 9 EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "&Directórios:", -1, 110, 6, 92, 9 + LTEXT "&Directórios:", -1, 110, 6, 92, 9 LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP LTEXT "Listar Ficheiros do &Tipo:", 1089, 6, 104, 90, 9 @@ -125,16 +131,16 @@ FONT 8, "MS Shell Dlg" { LTEXT "Impressora:", 1088, 6, 6, 40, 9 LTEXT "", 1089, 60, 6, 150, 9 - GROUPBOX "Faixa de Impressão", 1072, 6, 30, 160, 65, BS_GROUPBOX + GROUPBOX "Faixa de Impressão", 1072, 6, 30, 160, 65, BS_GROUPBOX RADIOBUTTON "&Tudo", 1056, 16, 45, 60, 12 - RADIOBUTTON "S&eleção", 1057, 16, 60, 60, 12 - RADIOBUTTON "&Páginas", 1058, 16, 75, 60, 12 + RADIOBUTTON "S&eleção", 1057, 16, 60, 60, 12 + RADIOBUTTON "&Páginas", 1058, 16, 75, 60, 12 DEFPUSHBUTTON "Imprimir", IDOK, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP PUSHBUTTON "Cancelar", IDCANCEL, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Configurar", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP LTEXT "&De:", 1090, 60, 80, 30, 9 LTEXT "&Ate:", 1091, 120, 80, 30, 9 - LTEXT "&Qualidade de Impressão:", 1092, 6, 100, 76, 9 + LTEXT "&Qualidade de Impressão:", 1092, 6, 100, 76, 9 COMBOBOX 1136, 80, 100, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP CHECKBOX "Imprimir para Arquivo", 1040, 20, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP CHECKBOX "C&ondensado", 1041, 160, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP @@ -149,16 +155,16 @@ FONT 8, "MS Shell Dlg" { LTEXT "Impressora:", 1088, 6, 6, 40, 9 LTEXT "", 1089, 60, 6, 150, 9 - GROUPBOX "Faixa de Impressão", 1072, 6, 30, 160, 65, BS_GROUPBOX + GROUPBOX "Faixa de Impressão", 1072, 6, 30, 160, 65, BS_GROUPBOX RADIOBUTTON "&Tudo", 1056, 16, 45, 60, 12 - RADIOBUTTON "S&elecção", 1057, 16, 60, 60, 12 - RADIOBUTTON "&Páginas", 1058, 16, 75, 60, 12 + RADIOBUTTON "S&elecção", 1057, 16, 60, 60, 12 + RADIOBUTTON "&Páginas", 1058, 16, 75, 60, 12 DEFPUSHBUTTON "Imprimir", IDOK, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP PUSHBUTTON "Cancelar", IDCANCEL, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Configurar", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP LTEXT "&De:", 1090, 60, 80, 30, 9 - LTEXT "&Até:", 1091, 120, 80, 30, 9 - LTEXT "&Qualidade de Impressão:", 1092, 6, 100, 76, 9 + LTEXT "&Até:", 1091, 120, 80, 30, 9 + LTEXT "&Qualidade de Impressão:", 1092, 6, 100, 76, 9 COMBOBOX 1136, 80, 100, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP CHECKBOX "Imprimir para Ficheiro", 1040, 20, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP CHECKBOX "C&ondensado", 1041, 160, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP @@ -169,25 +175,25 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN PRINT_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Configurações de Impressão" +CAPTION "Configurações de Impressão" FONT 8, "MS Shell Dlg" { GROUPBOX "Impressora", 1072, 6, 10, 180, 65, BS_GROUPBOX - RADIOBUTTON "&Impressora Padrão", 1056, 16, 20, 80, 12 + RADIOBUTTON "&Impressora Padrão", 1056, 16, 20, 80, 12 LTEXT "[none]", 1088, 35, 35, 120, 9 - RADIOBUTTON "Impressora &Específica", 1057, 16, 50, 80, 12 + RADIOBUTTON "Impressora &Específica", 1057, 16, 50, 80, 12 COMBOBOX 1136, 35, 65, 149, 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 "Cancelar", IDCANCEL, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Configurar", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP - GROUPBOX "Orientação", 1073, 6, 85, 100, 50, BS_GROUPBOX + GROUPBOX "Orientação", 1073, 6, 85, 100, 50, BS_GROUPBOX RADIOBUTTON "&Retrato", 1058, 50, 100, 40, 12 RADIOBUTTON "&Paisagem", 1059, 50, 115, 40, 12 ICON "LANDSCAP", 1097, 10, 95, 32, 32 ICON "PORTRAIT", 1098, 10, 95, 32, 32 GROUPBOX "Papel", 1074, 120, 85, 180, 50, BS_GROUPBOX LTEXT "&Tamanho", 1089, 130, 95, 30, 9 - LTEXT "&Fonte de Alimentação", 1090, 130, 110, 30, 9 + LTEXT "&Fonte de Alimentação", 1090, 130, 110, 30, 9 COMBOBOX 1137, 155, 95, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP COMBOBOX 1138, 155, 110, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP } @@ -196,25 +202,25 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE PRINT_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Configurações de Impressão" +CAPTION "Configurações de Impressão" FONT 8, "MS Shell Dlg" { GROUPBOX "Impressora", 1072, 6, 10, 180, 65, BS_GROUPBOX RADIOBUTTON "&Impressora Predefinida", 1056, 16, 20, 80, 12 LTEXT "[none]", 1088, 35, 35, 120, 9 - RADIOBUTTON "Impressora &Específica", 1057, 16, 50, 80, 12 + RADIOBUTTON "Impressora &Específica", 1057, 16, 50, 80, 12 COMBOBOX 1136, 35, 65, 149, 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 "Cancelar", IDCANCEL, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Configurar", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP - GROUPBOX "Orientação", 1073, 6, 85, 100, 50, BS_GROUPBOX + GROUPBOX "Orientação", 1073, 6, 85, 100, 50, BS_GROUPBOX RADIOBUTTON "&Retrato", 1058, 50, 100, 40, 12 RADIOBUTTON "&Paisagem", 1059, 50, 115, 40, 12 ICON "LANDSCAP", 1097, 10, 95, 32, 32 ICON "PORTRAIT", 1098, 10, 95, 32, 32 GROUPBOX "Papel", 1074, 120, 85, 180, 50, BS_GROUPBOX LTEXT "&Tamanho", 1089, 130, 95, 30, 9 - LTEXT "&Fonte de Alimentação", 1090, 130, 110, 30, 9 + LTEXT "&Fonte de Alimentação", 1090, 130, 110, 30, 9 COMBOBOX 1137, 155, 95, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP COMBOBOX 1138, 155, 110, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP } @@ -295,9 +301,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Cor" FONT 8, "MS Shell Dlg" { - LTEXT "Cores &Básicas:", 1088, 4, 4, 140, 10 - LTEXT "&Cores do Usuário:", 1089, 4, 106, 140, 10 - LTEXT "Colorido|Sólid&o", 1090, 150, 151, 48, 10 + LTEXT "Cores &Básicas:", 1088, 4, 4, 140, 10 + LTEXT "&Cores do Usuário:", 1089, 4, 106, 140, 10 + LTEXT "Colorido|Sólid&o", 1090, 150, 151, 48, 10 LTEXT "Ver&melho:", 726 /*1094*/,249,126,24,10 EDITTEXT 706, 275,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP LTEXT "&Verde:",727/*1095*/,249,140,24,10 @@ -330,9 +336,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Cor" FONT 8, "MS Shell Dlg" { -LTEXT "Cores &Básicas:", 1088, 4, 4, 140, 10 +LTEXT "Cores &Básicas:", 1088, 4, 4, 140, 10 LTEXT "&Cores do Utilizador:", 1089, 4, 106, 140, 10 -LTEXT "Colorido|Sólid&o", 1090, 150, 151, 48, 10 +LTEXT "Colorido|Sólid&o", 1090, 150, 151, 48, 10 LTEXT "Ver&melho:", 726 /*1094*/,249,126,24,10 EDITTEXT 706, 275,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP LTEXT "&Verde:",727/*1095*/,249,140,24,10 @@ -368,12 +374,12 @@ FONT 8, "MS Shell Dlg" LTEXT "&Procurar:", -1, 4, 8, 42, 8 EDITTEXT 1152, 47, 7, 128, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP CHECKBOX "Palavra &Inteira", 1040, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "&Maiúsculas/minusculas", 1041, 4, 42, 64, 12, BS_AUTOCHECKBOX | WS_TABSTOP - GROUPBOX "Direção", 1072, 107, 26, 68, 28 + CHECKBOX "&Maiúsculas/minusculas", 1041, 4, 42, 64, 12, BS_AUTOCHECKBOX | WS_TABSTOP + GROUPBOX "Direção", 1072, 107, 26, 68, 28 CONTROL "A&cima", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 111, 38, 20, 12 CONTROL "A&baixo", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 138, 38, 30, 12 - DEFPUSHBUTTON "Procurar a Pró&xima", IDOK, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "Procurar a Pró&xima", IDOK, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "Cancelar", IDCANCEL, 182, 23, 50, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "A&juda", 1038, 182, 45, 50, 14, WS_GROUP | WS_TABSTOP } @@ -388,12 +394,12 @@ FONT 8, "MS Shell Dlg" LTEXT "&Procurar:", -1, 4, 8, 42, 8 EDITTEXT 1152, 47, 7, 128, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP CHECKBOX "Palavra &Inteira", 1040, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "&Maiúsculas/minúsculas", 1041, 4, 42, 64, 12, BS_AUTOCHECKBOX | WS_TABSTOP - GROUPBOX "Direcção", 1072, 107, 26, 68, 28 + CHECKBOX "&Maiúsculas/minúsculas", 1041, 4, 42, 64, 12, BS_AUTOCHECKBOX | WS_TABSTOP + GROUPBOX "Direcção", 1072, 107, 26, 68, 28 CONTROL "A&cima", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 111, 38, 20, 12 CONTROL "A&baixo", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 138, 38, 30, 12 - DEFPUSHBUTTON "&Procurar Próximo", IDOK, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Procurar Próximo", IDOK, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "Cancelar", IDCANCEL, 182, 23, 50, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "A&juda", 1038, 182, 45, 50, 14, WS_GROUP | WS_TABSTOP } @@ -411,9 +417,9 @@ FONT 8, "MS Shell Dlg" LTEXT "Substituir Pa&ra:", -1, 4, 26, 48, 8 EDITTEXT 1153, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP CHECKBOX "Palavra &inteira", 1040, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "&Maiúsculas/minúsculas", 1041, 5, 62, 59, 12, BS_AUTOCHECKBOX | WS_TABSTOP + CHECKBOX "&Maiúsculas/minúsculas", 1041, 5, 62, 59, 12, BS_AUTOCHECKBOX | WS_TABSTOP - DEFPUSHBUTTON "Procurar a Pró&xima", IDOK, 174, 4, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + DEFPUSHBUTTON "Procurar a Pró&xima", IDOK, 174, 4, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON PUSHBUTTON "&Substituir", psh1, 174, 21, 50, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "Substituir &Todas", psh2, 174, 38, 50, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "Cancelar", IDCANCEL, 174, 55, 50, 14, WS_GROUP | WS_TABSTOP @@ -432,9 +438,9 @@ FONT 8, "MS Shell Dlg" LTEXT "Substituir Pa&ra:", -1, 4, 26, 48, 8 EDITTEXT 1153, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP CHECKBOX "Palavra &inteira", 1040, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "&Maiúsculas/minúsculas", 1041, 5, 62, 59, 12, BS_AUTOCHECKBOX | WS_TABSTOP + CHECKBOX "&Maiúsculas/minúsculas", 1041, 5, 62, 59, 12, BS_AUTOCHECKBOX | WS_TABSTOP - DEFPUSHBUTTON "Procurar Próxima", IDOK, 174, 4, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + DEFPUSHBUTTON "Procurar Próxima", IDOK, 174, 4, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON PUSHBUTTON "&Substituir", psh1, 174, 21, 50, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "Substituir &Todas", psh2, 174, 38, 50, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "Cancelar", IDCANCEL, 174, 55, 50, 14, WS_GROUP | WS_TABSTOP @@ -465,23 +471,23 @@ FONT 8, "MS Shell Dlg" LTEXT "Dummy Type", stc11, 52, 48, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP LTEXT "Onde:", stc10, 16, 60, 36,10, SS_NOPREFIX LTEXT "Dummy Location", stc14, 52, 60, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Comentário:", stc9, 16, 72, 36,10, SS_NOPREFIX + LTEXT "Comentário:", stc9, 16, 72, 36,10, SS_NOPREFIX LTEXT "Dummy Remark", stc13, 52, 72, 152,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - GROUPBOX "Cópias", grp2, 160, 92, 120,64, WS_GROUP - LTEXT "Número de &cópias:", stc5, 168,108, 68, 8 + GROUPBOX "Cópias", grp2, 160, 92, 120,64, WS_GROUP + LTEXT "Número de &cópias:", stc5, 168,108, 68, 8 ICON "", ico3, 162,124, 76,24, WS_GROUP | SS_CENTERIMAGE CONTROL "&Agrupar", chx2,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,240,130,36,12 EDITTEXT edt3, 240,106, 32,12, WS_GROUP | ES_NUMBER - GROUPBOX "Faixa de impressão", grp1, 8,92, 144,64, WS_GROUP + GROUPBOX "Faixa de impressão", grp1, 8,92, 144,64, WS_GROUP CONTROL "&Todos", rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,106,64,12 - CONTROL "Pá&ginas", rad3,"Button",BS_AUTORADIOBUTTON,16,122,36,12 - CONTROL "Seleção", rad2,"Button",BS_AUTORADIOBUTTON,16,138,64,12 + CONTROL "Pá&ginas", rad3,"Button",BS_AUTORADIOBUTTON,16,122,36,12 + CONTROL "Seleção", rad2,"Button",BS_AUTORADIOBUTTON,16,138,64,12 EDITTEXT edt1, 74,122, 26,12, WS_GROUP | ES_NUMBER EDITTEXT edt2, 118,122, 26,12, WS_GROUP | ES_NUMBER RTEXT "&de:", stc2, 52,124, 20,8 - RTEXT "&até:", stc3, 100,124, 16,8 + RTEXT "&até:", stc3, 100,124, 16,8 } LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE @@ -505,25 +511,25 @@ FONT 8, "MS Shell Dlg" LTEXT "Estado 'Dummy'", stc12, 52, 36, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP LTEXT "Tipo:", stc7, 16, 48, 36,10, SS_NOPREFIX LTEXT "Tipo 'Dummy'", stc11, 52, 48, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Localizaça:", stc10, 16, 60, 36,10, SS_NOPREFIX - LTEXT "Localizaçao 'Dummy'", stc14, 52, 60, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Comentário:", stc9, 16, 72, 36,10, SS_NOPREFIX - LTEXT "Comentário 'Dummy'", stc13, 52, 72, 152,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Localizaça:", stc10, 16, 60, 36,10, SS_NOPREFIX + LTEXT "Localizaçao 'Dummy'", stc14, 52, 60, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Comentário:", stc9, 16, 72, 36,10, SS_NOPREFIX + LTEXT "Comentário 'Dummy'", stc13, 52, 72, 152,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - GROUPBOX "Cópias", grp2, 160, 92, 120,64, WS_GROUP - LTEXT "Número de &cópias:", stc5, 168,108, 68, 8 + GROUPBOX "Cópias", grp2, 160, 92, 120,64, WS_GROUP + LTEXT "Número de &cópias:", stc5, 168,108, 68, 8 ICON "", ico3, 162,124, 76,24, WS_GROUP | SS_CENTERIMAGE CONTROL "&Agrupar", chx2,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,240,130,36,12 EDITTEXT edt3, 240,106, 32,12, WS_GROUP | ES_NUMBER - GROUPBOX "Faixa de impressão", grp1, 8,92, 144,64, WS_GROUP + GROUPBOX "Faixa de impressão", grp1, 8,92, 144,64, WS_GROUP CONTROL "&Todos", rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,106,64,12 - CONTROL "Páginas", rad3,"Button",BS_AUTORADIOBUTTON,16,122,36,12 - CONTROL "Selecção", rad2,"Button",BS_AUTORADIOBUTTON,16,138,64,12 + CONTROL "Páginas", rad3,"Button",BS_AUTORADIOBUTTON,16,122,36,12 + CONTROL "Selecção", rad2,"Button",BS_AUTORADIOBUTTON,16,138,64,12 EDITTEXT edt1, 74,122, 26,12, WS_GROUP | ES_NUMBER EDITTEXT edt2, 118,122, 26,12, WS_GROUP | ES_NUMBER RTEXT "&de:", stc2, 52,124, 20,8 - RTEXT "&até", stc3, 100,124, 16,8 + RTEXT "&até", stc3, 100,124, 16,8 } @@ -532,7 +538,7 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN PRINT32_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 288, 178 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP | DS_3DLOOK -CAPTION "Configurações de Impressão" +CAPTION "Configurações de Impressão" FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "OK", IDOK,180,156,50,14,WS_GROUP @@ -549,7 +555,7 @@ BEGIN LTEXT "Dummy Type", stc11, 52, 48, 224, 10, SS_NOPREFIX | SS_LEFTNOWORDWRAP LTEXT "Onde:", stc10, 16, 60, 36, 10, SS_NOPREFIX LTEXT "Dummy Location", stc14, 52, 60, 224, 10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Comentário", stc9, 16, 72, 36, 10, SS_NOPREFIX + LTEXT "Comentário", stc9, 16, 72, 36, 10, SS_NOPREFIX LTEXT "Dummy Remark", stc13, 52, 72, 224, 10, SS_NOPREFIX | SS_LEFTNOWORDWRAP GROUPBOX "Papel", grp2, 8, 92, 164, 56, WS_GROUP @@ -558,7 +564,7 @@ BEGIN LTEXT "&Origem:", stc3, 16, 128, 36, 8 COMBOBOX cmb3, 52, 126, 112, 112, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP - GROUPBOX "Orientação", grp1, 180, 92, 100, 56, WS_GROUP + GROUPBOX "Orientação", grp1, 180, 92, 100, 56, WS_GROUP ICON "", ico1, 195, 112, 18, 20, WS_GROUP CONTROL "&Retrato", rad1, "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 224, 106, 52, 12 CONTROL "&Paisagem", rad2, "Button", BS_AUTORADIOBUTTON, 224, 126, 52, 12 @@ -569,7 +575,7 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE PRINT32_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 288, 178 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP | DS_3DLOOK -CAPTION "Configuração de Impressão" +CAPTION "Configuração de Impressão" FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "OK", IDOK,180,156,50,14,WS_GROUP @@ -584,10 +590,10 @@ BEGIN LTEXT "EStado 'Dummy'", stc12, 52, 36, 224, 10, SS_NOPREFIX | SS_LEFTNOWORDWRAP LTEXT "Tipo:", stc7, 16, 48, 36, 10, SS_NOPREFIX LTEXT "Tipo 'Dummy'", stc11, 52, 48, 224, 10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Localização:", stc10, 16, 60, 36, 10, SS_NOPREFIX - LTEXT "Localização 'Dummy'", stc14, 52, 60, 224, 10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Comentário", stc9, 16, 72, 36, 10, SS_NOPREFIX - LTEXT "Comentário 'Dummy'", stc13, 52, 72, 224, 10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Localização:", stc10, 16, 60, 36, 10, SS_NOPREFIX + LTEXT "Localização 'Dummy'", stc14, 52, 60, 224, 10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Comentário", stc9, 16, 72, 36, 10, SS_NOPREFIX + LTEXT "Comentário 'Dummy'", stc13, 52, 72, 224, 10, SS_NOPREFIX | SS_LEFTNOWORDWRAP GROUPBOX "Papel", grp2, 8, 92, 164, 56, WS_GROUP LTEXT "&Tamanho:", stc2, 16, 108, 36, 8 @@ -595,7 +601,7 @@ BEGIN LTEXT "&Origem:", stc3, 16, 128, 36, 8 COMBOBOX cmb3, 52, 126, 112, 112, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP - GROUPBOX "Orientação", grp1, 180, 92, 100, 56, WS_GROUP + GROUPBOX "Orientação", grp1, 180, 92, 100, 56, WS_GROUP ICON "", ico1, 195, 112, 18, 20, WS_GROUP CONTROL "&Retrato", rad1, "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 224, 106, 52, 12 CONTROL "&Paisagem", rad2, "Button", BS_AUTORADIOBUTTON, 224, 126, 52, 12 @@ -606,7 +612,7 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN PAGESETUPDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 240, 240 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Configurações de Página" +CAPTION "Configurações de Página" FONT 8, "MS Shell Dlg" BEGIN CONTROL "", rct1, "Static", SS_WHITERECT, 80, 8, 80, 80 @@ -617,7 +623,7 @@ BEGIN COMBOBOX cmb2, 64, 110, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL LTEXT "&Bandeja:", stc3, 16, 132, 36, 8 COMBOBOX cmb3, 64, 130, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL - GROUPBOX "Orientação", grp1, 8, 156, 64, 56, BS_GROUPBOX + GROUPBOX "Orientação", grp1, 8, 156, 64, 56, BS_GROUPBOX AUTORADIOBUTTON "&Retrato", rad1, 16, 170, 52, 12, BS_AUTORADIOBUTTON AUTORADIOBUTTON "&Paisagem", rad2, 16, 190, 52, 12, BS_AUTORADIOBUTTON GROUPBOX "Bordas", grp4, 80, 156, 152, 56, BS_GROUPBOX @@ -638,7 +644,7 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE PAGESETUPDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 240, 240 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Configurações de Página" +CAPTION "Configurações de Página" FONT 8, "MS Shell Dlg" BEGIN CONTROL "", rct1, "Static", SS_WHITERECT, 80, 8, 80, 80 @@ -649,7 +655,7 @@ BEGIN COMBOBOX cmb2, 64, 110, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL LTEXT "&Bandeja:", stc3, 16, 132, 36, 8 COMBOBOX cmb3, 64, 130, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL - GROUPBOX "Orientação", grp1, 8, 156, 64, 56, BS_GROUPBOX + GROUPBOX "Orientação", grp1, 8, 156, 64, 56, BS_GROUPBOX AUTORADIOBUTTON "&Retrato", rad1, 16, 170, 52, 12, BS_AUTORADIOBUTTON AUTORADIOBUTTON "&Paisagem", rad2, 16, 190, 52, 12, BS_AUTORADIOBUTTON GROUPBOX "Bordas", grp4, 80, 156, 152, 56, BS_GROUPBOX @@ -729,7 +735,7 @@ STRINGTABLE DISCARDABLE IDS_PERSONAL "Meus Documentos" IDS_FAVORITES "Favoritos" IDS_PATH "Caminho do Sistema" - IDS_DESKTOP "Área de Trabalho" + IDS_DESKTOP "Ãrea de Trabalho" IDS_FONTS "Fontes" IDS_MYCOMPUTER "Meu Computador" } @@ -742,8 +748,8 @@ STRINGTABLE DISCARDABLE IDS_DOCUMENTFOLDERS "Pastas de Documentos" IDS_PERSONAL "Os Meus Documentos" IDS_FAVORITES "Favoritos" - IDS_PATH "Localização do Sistema" - IDS_DESKTOP "Ecrã" + IDS_PATH "Localização do Sistema" + IDS_DESKTOP "Ecrã" IDS_FONTS "Tipos de Letra" IDS_MYCOMPUTER "O Meu Computador" } @@ -754,15 +760,15 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE DISCARDABLE { IDS_SYSTEMFOLDERS "Pastas do Sistema" - IDS_LOCALHARDRIVES "Discos Rígidos Locais" - IDS_FILENOTFOUND "Arquivo não encontrado" + IDS_LOCALHARDRIVES "Discos Rígidos Locais" + IDS_FILENOTFOUND "Arquivo não encontrado" IDS_VERIFYFILE "Por favor verifique se foi fornecido o nome correto do arquivo" - IDS_CREATEFILE "Arquivo não existe\nVocê gostaria de cria-lo" - IDS_OVERWRITEFILE "Arquivo já existe.\nGostaria de substituí-lo?" - IDS_INVALID_FILENAME_TITLE "Caracter(es) inválidos no caminho" - IDS_INVALID_FILENAME "Um nome de arquivo não pode conter quaisquer dos seguintes caracteres:\n / : < > |" - IDS_PATHNOTEXISTING "Caminho não existe" - IDS_FILENOTEXISTING "Arquivo não existe" + IDS_CREATEFILE "Arquivo não existe\nVocê gostaria de cria-lo" + IDS_OVERWRITEFILE "Arquivo já existe.\nGostaria de substituí-lo?" + IDS_INVALID_FILENAME_TITLE "Caracter(es) inválidos no caminho" + IDS_INVALID_FILENAME "Um nome de arquivo não pode conter quaisquer dos seguintes caracteres:\n / : < > |" + IDS_PATHNOTEXISTING "Caminho não existe" + IDS_FILENOTEXISTING "Arquivo não existe" } LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE @@ -770,15 +776,15 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE STRINGTABLE DISCARDABLE { IDS_SYSTEMFOLDERS "Pastas do Sistema" - IDS_LOCALHARDRIVES "Discos Rígidos Locais" - IDS_FILENOTFOUND "Ficheiro não encontrado" + IDS_LOCALHARDRIVES "Discos Rígidos Locais" + IDS_FILENOTFOUND "Ficheiro não encontrado" IDS_VERIFYFILE "Por favor verifique se foi fornecido o nome correcto do ficheiro" - IDS_CREATEFILE "O ficheiro não existe\nGostaria de o criar" - IDS_OVERWRITEFILE "O ficheiro já existe.\nGostaria de o substituir?" - IDS_INVALID_FILENAME_TITLE "Caracter(es) inválidos na localização" - IDS_INVALID_FILENAME "Um nome de ficheiro não pode conter quaisquer dos seguintes caracteres:\n / : < > |" - IDS_PATHNOTEXISTING "A localização não existe" - IDS_FILENOTEXISTING "O ficheiro não existe" + IDS_CREATEFILE "O ficheiro não existe\nGostaria de o criar" + IDS_OVERWRITEFILE "O ficheiro já existe.\nGostaria de o substituir?" + IDS_INVALID_FILENAME_TITLE "Caracter(es) inválidos na localização" + IDS_INVALID_FILENAME "Um nome de ficheiro não pode conter quaisquer dos seguintes caracteres:\n / : < > |" + IDS_PATHNOTEXISTING "A localização não existe" + IDS_FILENOTEXISTING "O ficheiro não existe" } @@ -786,22 +792,22 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE DISCARDABLE { - IDS_UPFOLDER "Um Nível Acima" + IDS_UPFOLDER "Um Nível Acima" IDS_NEWFOLDER "Criar Nova Pasta" IDS_LISTVIEW "Lista" IDS_REPORTVIEW "Detalhes" - IDS_TODESKTOP "Área de Trabalho" + IDS_TODESKTOP "Ãrea de Trabalho" } LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE STRINGTABLE DISCARDABLE { - IDS_UPFOLDER "Um Nível Acima" + IDS_UPFOLDER "Um Nível Acima" IDS_NEWFOLDER "Criar Nova Pasta" IDS_LISTVIEW "Lista" IDS_REPORTVIEW "Detalhes" - IDS_TODESKTOP "Ecrã" + IDS_TODESKTOP "Ecrã" } @@ -811,26 +817,26 @@ STRINGTABLE DISCARDABLE { PD32_PRINT_TITLE "Imprimir" - PD32_VALUE_UREADABLE "Entrada Ilegível" - PD32_INVALID_PAGE_RANGE "Este valor não se encaixa na faixa de páginas\n\ + PD32_VALUE_UREADABLE "Entrada Ilegível" + PD32_INVALID_PAGE_RANGE "Este valor não se encaixa na faixa de páginas\n\ Por favor entre um valor entre %d e %d." - PD32_FROM_NOT_ABOVE_TO "A entrada DE não pode exceder ATÉ." - PD32_MARGINS_OVERLAP "As margens estão fora das medidas \ + PD32_FROM_NOT_ABOVE_TO "A entrada DE não pode exceder ATÉ." + PD32_MARGINS_OVERLAP "As margens estão fora das medidas \ do papel.\nPor favor reentre as margens." - PD32_NR_OF_COPIES_EMPTY "O número de cópias não pode ter valor vazio." - PD32_TOO_LARGE_COPIES "Esta grande quantidade de cópias não é suportada \ + PD32_NR_OF_COPIES_EMPTY "O número de cópias não pode ter valor vazio." + PD32_TOO_LARGE_COPIES "Esta grande quantidade de cópias não é suportada \ pela sua impressora.\nPor favor entre um valor entre 1 e %d." - PD32_PRINT_ERROR "Ocorreu um erro de impressão." - PD32_NO_DEFAULT_PRINTER "Não existe uma impressora padrão." - PD32_CANT_FIND_PRINTER "Não é possível encontrar uma impressora." - PD32_OUT_OF_MEMORY "Memória insuficiente." + PD32_PRINT_ERROR "Ocorreu um erro de impressão." + PD32_NO_DEFAULT_PRINTER "Não existe uma impressora padrão." + PD32_CANT_FIND_PRINTER "Não é possível encontrar uma impressora." + PD32_OUT_OF_MEMORY "Memória insuficiente." PD32_GENERIC_ERROR "Ocorreu algum erro." PD32_DRIVER_UNKNOWN "Driver de impressora desconhecido." 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 "Impressora Padrão; " + PD32_DEFAULT_PRINTER "Impressora Padrão; " PD32_NR_OF_DOCUMENTS_IN_QUEUE "Existem %d documentos na fila" PD32_MARGINS_IN_INCHES "Margens [polegadas]" PD32_MARGINS_IN_MILLIMETERS "Margens [mm]" @@ -839,29 +845,29 @@ Please install one and retry." PD32_PRINTER_STATUS_READY "Pronto" PD32_PRINTER_STATUS_PAUSED "Pausada; " PD32_PRINTER_STATUS_ERROR "Erro; " - PD32_PRINTER_STATUS_PENDING_DELETION "Exclusão pendente; " + PD32_PRINTER_STATUS_PENDING_DELETION "Exclusão pendente; " PD32_PRINTER_STATUS_PAPER_JAM "Papel atolado; " PD32_PRINTER_STATUS_PAPER_OUT "Sem papel; " - PD32_PRINTER_STATUS_MANUAL_FEED "Alimentação manual; " + PD32_PRINTER_STATUS_MANUAL_FEED "Alimentação manual; " PD32_PRINTER_STATUS_PAPER_PROBLEM "Problemas com o papel; " PD32_PRINTER_STATUS_OFFLINE "Impressora desligada; " PD32_PRINTER_STATUS_IO_ACTIVE "E/S Ativa; " PD32_PRINTER_STATUS_BUSY "Ocupada; " PD32_PRINTER_STATUS_PRINTING "Imprimindo; " - PD32_PRINTER_STATUS_OUTPUT_BIN_FULL "Bandeja de saída está cheia; " - PD32_PRINTER_STATUS_NOT_AVAILABLE "Não disponível; " + PD32_PRINTER_STATUS_OUTPUT_BIN_FULL "Bandeja de saída está cheia; " + PD32_PRINTER_STATUS_NOT_AVAILABLE "Não disponível; " PD32_PRINTER_STATUS_WAITING "Esperando; " PD32_PRINTER_STATUS_PROCESSING "Processando; " PD32_PRINTER_STATUS_INITIALIZING "Inicializando; " PD32_PRINTER_STATUS_WARMING_UP "Aquecendo; " PD32_PRINTER_STATUS_TONER_LOW "Pouco toner; " PD32_PRINTER_STATUS_NO_TONER "Sem toner; " - PD32_PRINTER_STATUS_PAGE_PUNT "Lançar página; " - PD32_PRINTER_STATUS_USER_INTERVENTION "Intervenção do usuário; " - PD32_PRINTER_STATUS_OUT_OF_MEMORY "Memória insuficiente; " - PD32_PRINTER_STATUS_DOOR_OPEN "A impressora está aberta; " - PD32_PRINTER_STATUS_SERVER_UNKNOWN "Servidor de impressão desconhecido; " - PD32_PRINTER_STATUS_POWER_SAVE "Modo econômico; " + PD32_PRINTER_STATUS_PAGE_PUNT "Lançar página; " + PD32_PRINTER_STATUS_USER_INTERVENTION "Intervenção do usuário; " + PD32_PRINTER_STATUS_OUT_OF_MEMORY "Memória insuficiente; " + PD32_PRINTER_STATUS_DOOR_OPEN "A impressora está aberta; " + PD32_PRINTER_STATUS_SERVER_UNKNOWN "Servidor de impressão desconhecido; " + PD32_PRINTER_STATUS_POWER_SAVE "Modo econômico; " } LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE @@ -870,23 +876,23 @@ STRINGTABLE DISCARDABLE { PD32_PRINT_TITLE "Imprimir" - PD32_VALUE_UREADABLE "Entrada Ilegível" - PD32_INVALID_PAGE_RANGE "Este valor não se encaixa na faixa de páginas\n\ + PD32_VALUE_UREADABLE "Entrada Ilegível" + PD32_INVALID_PAGE_RANGE "Este valor não se encaixa na faixa de páginas\n\ Por favor indique um valor entre %d e %d." - PD32_FROM_NOT_ABOVE_TO "A entrada DE não pode exceder ATÉ" - PD32_MARGINS_OVERLAP "As margens estão fora das medidas \ + PD32_FROM_NOT_ABOVE_TO "A entrada DE não pode exceder ATÉ" + PD32_MARGINS_OVERLAP "As margens estão fora das medidas \ do papel.\nPor favor indique as margens." - PD32_NR_OF_COPIES_EMPTY "O número de cópias não pode ter valor vazio." - PD32_TOO_LARGE_COPIES "Esta grande quantidade de cópias não é suportada \ + PD32_NR_OF_COPIES_EMPTY "O número de cópias não pode ter valor vazio." + PD32_TOO_LARGE_COPIES "Esta grande quantidade de cópias não é suportada \ pela sua impressora.\nPor favor indique um valor entre 1 e %d." - PD32_PRINT_ERROR "Ocorreu um erro de impressão." - PD32_NO_DEFAULT_PRINTER "Não existe uma impressora predefinida." - PD32_CANT_FIND_PRINTER "Não é possível encontrar uma impressora." - PD32_OUT_OF_MEMORY "Memória insuficiente." + PD32_PRINT_ERROR "Ocorreu um erro de impressão." + PD32_NO_DEFAULT_PRINTER "Não existe uma impressora predefinida." + PD32_CANT_FIND_PRINTER "Não é possível encontrar uma impressora." + PD32_OUT_OF_MEMORY "Memória insuficiente." PD32_GENERIC_ERROR "Ocorreu algum erro." PD32_DRIVER_UNKNOWN "Controlador de impressora desconhecido." PD32_NO_DEVICES "Antes de realizar tarefas relacionadas com a impressora \ -tais como configuração de páginas ou imprimir um documento, precisa instalar uma impressora. \ +tais como configuração de páginas ou imprimir um documento, precisa instalar uma impressora. \ Por favor instale uma e tente novamente." PD32_DEFAULT_PRINTER "Impressora Predefinida; " @@ -898,31 +904,40 @@ Por favor instale uma e tente novamente." PD32_PRINTER_STATUS_READY "Pronto" PD32_PRINTER_STATUS_PAUSED "Pausada; " PD32_PRINTER_STATUS_ERROR "Erro; " - PD32_PRINTER_STATUS_PENDING_DELETION "Exclusão pendente; " + PD32_PRINTER_STATUS_PENDING_DELETION "Exclusão pendente; " PD32_PRINTER_STATUS_PAPER_JAM "Papel atolado; " PD32_PRINTER_STATUS_PAPER_OUT "Sem papel; " - PD32_PRINTER_STATUS_MANUAL_FEED "Alimentação manual; " + PD32_PRINTER_STATUS_MANUAL_FEED "Alimentação manual; " PD32_PRINTER_STATUS_PAPER_PROBLEM "Problemas com o papel; " PD32_PRINTER_STATUS_OFFLINE "Impressora desligada; " PD32_PRINTER_STATUS_IO_ACTIVE "E/S Activa; " PD32_PRINTER_STATUS_BUSY "Ocupada; " PD32_PRINTER_STATUS_PRINTING "A imprimir; " PD32_PRINTER_STATUS_OUTPUT_BIN_FULL "A bandeja de saida encontra-se cheia; " - PD32_PRINTER_STATUS_NOT_AVAILABLE "Não disponível; " + PD32_PRINTER_STATUS_NOT_AVAILABLE "Não disponível; " PD32_PRINTER_STATUS_WAITING "A esperar; " PD32_PRINTER_STATUS_PROCESSING "A processar; " PD32_PRINTER_STATUS_INITIALIZING "A inicializar; " PD32_PRINTER_STATUS_WARMING_UP "A aquecer; " PD32_PRINTER_STATUS_TONER_LOW "Pouco toner; " PD32_PRINTER_STATUS_NO_TONER "Sem toner; " - PD32_PRINTER_STATUS_PAGE_PUNT "Lançar página; " - PD32_PRINTER_STATUS_USER_INTERVENTION "Intervenção do utilizador; " - PD32_PRINTER_STATUS_OUT_OF_MEMORY "Memória insuficiente; " - PD32_PRINTER_STATUS_DOOR_OPEN "A impressora está aberta; " - PD32_PRINTER_STATUS_SERVER_UNKNOWN "Servidor de impressão desconhecido; " - PD32_PRINTER_STATUS_POWER_SAVE "Modo económico; " + PD32_PRINTER_STATUS_PAGE_PUNT "Lançar página; " + PD32_PRINTER_STATUS_USER_INTERVENTION "Intervenção do utilizador; " + PD32_PRINTER_STATUS_OUT_OF_MEMORY "Memória insuficiente; " + PD32_PRINTER_STATUS_DOOR_OPEN "A impressora está aberta; " + PD32_PRINTER_STATUS_SERVER_UNKNOWN "Servidor de impressão desconhecido; " + PD32_PRINTER_STATUS_POWER_SAVE "Modo económico; " } +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE + +STRINGTABLE DISCARDABLE /* Estilos de tipos de letra */ +{ + IDS_FONT_REGULAR "Normal" + IDS_FONT_BOLD "Negrito" + IDS_FONT_ITALIC "Itálico" + IDS_FONT_BOLD_ITALIC "Negrito Itálico" +} LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN @@ -934,14 +949,14 @@ STRINGTABLE DISCARDABLE /* Nomes de cores */ IDS_COLOR_OLIVE "Verde-oliva" IDS_COLOR_NAVY "Azul-marinho" IDS_COLOR_PURPLE "Roxo" - IDS_COLOR_TEAL "Azul-petróleo" + IDS_COLOR_TEAL "Azul-petróleo" IDS_COLOR_GRAY "Cinza" IDS_COLOR_SILVER "Prateado" IDS_COLOR_RED "Vermelho" - IDS_COLOR_LIME "Verde-limão" + IDS_COLOR_LIME "Verde-limão" IDS_COLOR_YELLOW "Amarelo" IDS_COLOR_BLUE "Azul" - IDS_COLOR_FUCHSIA "Fúcsia" + IDS_COLOR_FUCHSIA "Fúcsia" IDS_COLOR_AQUA "Azul-piscina" IDS_COLOR_WHITE "Branco" } @@ -956,7 +971,7 @@ STRINGTABLE DISCARDABLE /* Nomes de cores */ IDS_COLOR_OLIVE "Verde-oliveira" IDS_COLOR_NAVY "Azul-marinho" IDS_COLOR_PURPLE "Roxo" - IDS_COLOR_TEAL "Azul-petróleo" + IDS_COLOR_TEAL "Azul-petróleo" IDS_COLOR_GRAY "Cinza" IDS_COLOR_SILVER "Prateado" IDS_COLOR_RED "Vermelho" diff --git a/reactos/dll/win32/comdlg32/cdlg_Ro.rc b/reactos/dll/win32/comdlg32/cdlg_Ro.rc index 45a6889d860..0c1b304c29e 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Ro.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Ro.rc @@ -17,6 +17,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ @@ -476,5 +479,3 @@ STRINGTABLE DISCARDABLE IDS_SAVE_AS "Salvează ca" IDS_OPEN_FILE "Deschide fiÈ™ier" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/comdlg32/cdlg_Ru.rc b/reactos/dll/win32/comdlg32/cdlg_Ru.rc index c5af92cb009..7c1eec530a4 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Ru.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Ru.rc @@ -16,100 +16,106 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ +/* UTF-8 */ +#pragma code_page(65001) + LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT OPEN_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Îòêðûòü" +CAPTION "Открыть" FONT 8, "MS Shell Dlg" { - LTEXT "&Èìÿ ôàéëà:", 1090, 6, 6, 76, 9 + LTEXT "&Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°:", 1090, 6, 6, 76, 9 EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "&Êàòàëîãè:", -1, 110, 6, 92, 9 + LTEXT "&Каталоги:", -1, 110, 6, 92, 9 LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "Ïîêàçûâàòü ôàéëû &òèïà:", 1089, 6, 104, 90, 9 + LTEXT "Показывать файлы &типа:", 1089, 6, 104, 90, 9 COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP - LTEXT "&Äèñêè:", 1091, 110, 104, 92, 9 + LTEXT "&ДиÑки:", 1091, 110, 104, 92, 9 COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Îòêðûòü", IDOK, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Îòìåíà", IDCANCEL, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Ñïðàâêà", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP - CHECKBOX "Ò&îëüêî äëÿ ÷òåíèÿ", 1040, 208, 68, 54, 24, BS_AUTOCHECKBOX | BS_MULTILINE | WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "Открыть", IDOK, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Отмена", IDCANCEL, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Справка", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP + CHECKBOX "Т&олько Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ", 1040, 208, 68, 54, 24, BS_AUTOCHECKBOX | BS_MULTILINE | WS_GROUP | WS_TABSTOP } SAVE_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Ñîõðàíèòü êàê..." +CAPTION "Сохранить как..." FONT 8, "MS Shell Dlg" { - LTEXT "&Èìÿ ôàéëà:", 1090, 6, 6, 76, 9 + LTEXT "&Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°:", 1090, 6, 6, 76, 9 EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "&Êàòàëîãè:", -1, 110, 6, 92, 9 + LTEXT "&Каталоги:", -1, 110, 6, 92, 9 LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP - LTEXT "Ïîêàçûâàòü ôàéëû &òèïà:", 1089, 6, 104, 90, 9 + LTEXT "Показывать файлы &типа:", 1089, 6, 104, 90, 9 COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP - LTEXT "&Äèñêè:", 1091, 110, 104, 92, 9 + LTEXT "&ДиÑки:", 1091, 110, 104, 92, 9 COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Ñîõðàíèòü êàê", IDOK, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Îòìåíà", IDCANCEL, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Ñïðàâêà", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP - CHECKBOX "&Òîëüêî äëÿ ÷òåíèÿ", 1040, 208, 68, 54, 24, BS_AUTOCHECKBOX | BS_MULTILINE | WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "Сохранить как", IDOK, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Отмена", IDCANCEL, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Справка", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP + CHECKBOX "&Только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ", 1040, 208, 68, 54, 24, BS_AUTOCHECKBOX | BS_MULTILINE | WS_GROUP | WS_TABSTOP } PRINT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Ïå÷àòü" +CAPTION "Печать" FONT 8, "MS Shell Dlg" { - LTEXT "Ïðèíòåð:", 1088, 6, 6, 40, 9 + LTEXT "Принтер:", 1088, 6, 6, 40, 9 LTEXT "", 1089, 60, 6, 150, 9 - GROUPBOX "Ïå÷àòàòü", 1072, 6, 30, 160, 65, BS_GROUPBOX - RADIOBUTTON "&Âñå", 1056, 16, 45, 60, 12 - RADIOBUTTON "Â&ûäåëåííûé ôðàãìåíò", 1057, 16, 60, 60, 12 - RADIOBUTTON "&Ñòðàíèöû", 1058, 16, 75, 60, 12 - DEFPUSHBUTTON "Ïå÷àòü", IDOK, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Îòìåíà", IDCANCEL, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Ñâî&éñòâà", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP - LTEXT "&ñ:", 1090, 60, 80, 30, 9 - LTEXT "&ïî:", 1091, 120, 80, 30, 9 - LTEXT "&Êà÷åñòâî ïå÷àòè:", 1092, 6, 100, 76, 9 + GROUPBOX "Печатать", 1072, 6, 30, 160, 65, BS_GROUPBOX + RADIOBUTTON "&Ð’Ñе", 1056, 16, 45, 60, 12 + RADIOBUTTON "Ð’&ыделенный фрагмент", 1057, 16, 60, 60, 12 + RADIOBUTTON "&Страницы", 1058, 16, 75, 60, 12 + DEFPUSHBUTTON "Печать", IDOK, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Отмена", IDCANCEL, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Сво&йÑтва", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP + LTEXT "&Ñ:", 1090, 60, 80, 30, 9 + LTEXT "&по:", 1091, 120, 80, 30, 9 + LTEXT "&КачеÑтво печати:", 1092, 6, 100, 76, 9 COMBOBOX 1136, 80, 100, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP - CHECKBOX "Ï&å÷àòü â ôàéë", 1040, 20, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Ñæàòî", 1041, 160, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "П&ечать в файл", 1040, 20, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Сжато", 1041, 160, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP } PRINT_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Íàñòðîéêà ïðèíòåðà" +CAPTION "ÐаÑтройка принтера" FONT 8, "MS Shell Dlg" { - GROUPBOX "Ïðèíòåð", 1072, 6, 10, 180, 65, BS_GROUPBOX - RADIOBUTTON "Ïðèíòåð ïî &óìîë÷àíèþ", 1056, 16, 20, 80, 12 - LTEXT "[íåò]", 1088, 35, 35, 120, 9 - RADIOBUTTON "&Äðóãîé ïðèíòåð", 1057, 16, 50, 80, 12 + GROUPBOX "Принтер", 1072, 6, 10, 180, 65, BS_GROUPBOX + RADIOBUTTON "Принтер по &умолчанию", 1056, 16, 20, 80, 12 + LTEXT "[нет]", 1088, 35, 35, 120, 9 + RADIOBUTTON "&Другой принтер", 1057, 16, 50, 80, 12 COMBOBOX 1136, 35, 65, 149, 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 "Îòìåíà", IDCANCEL, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Íàñòðîéêà", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP - GROUPBOX "Îðèåíòàöèÿ", 1073, 6, 85, 100, 50, BS_GROUPBOX - RADIOBUTTON "&Êíèæíàÿ", 1058, 50, 100, 40, 12 - RADIOBUTTON "&Àëüáîìíàÿ", 1059, 50, 115, 40, 12 + PUSHBUTTON "Отмена", IDCANCEL, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&ÐаÑтройка", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP + GROUPBOX "ОриентациÑ", 1073, 6, 85, 100, 50, BS_GROUPBOX + RADIOBUTTON "&КнижнаÑ", 1058, 50, 100, 40, 12 + RADIOBUTTON "&ÐльбомнаÑ", 1059, 50, 115, 40, 12 ICON "LANDSCAP", 1097, 10, 95, 32, 32 ICON "PORTRAIT", 1098, 10, 95, 32, 32 - GROUPBOX "Áóìàãà", 1074, 120, 85, 180, 50, BS_GROUPBOX - LTEXT "Ðà&çìåð", 1089, 130, 95, 30, 9 - LTEXT "&Èñòî÷íèê", 1090, 130, 110, 30, 9 + GROUPBOX "Бумага", 1074, 120, 85, 180, 50, BS_GROUPBOX + LTEXT "Ра&змер", 1089, 130, 95, 30, 9 + LTEXT "&ИÑточник", 1090, 130, 110, 30, 9 COMBOBOX 1137, 155, 95, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP COMBOBOX 1138, 155, 110, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP } @@ -117,31 +123,31 @@ FONT 8, "MS Shell Dlg" CHOOSE_FONT DIALOG DISCARDABLE 13, 54, 264, 147 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Øðèôò" +CAPTION "Шрифт" FONT 8, "MS Shell Dlg" { - LTEXT "&Øðèôò:",1088 ,6,3,40,9 + LTEXT "&Шрифт:",1088 ,6,3,40,9 COMBOBOX 1136 ,6,13,94,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE - LTEXT "&Íà÷åðòàíèå:",1089 ,108,3,44,9 + LTEXT "&Ðачертание:",1089 ,108,3,44,9 COMBOBOX 1137,108,13,64,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE - LTEXT "&Ðàçìåð:",1090,179,3,30,9 + LTEXT "&Размер:",1090,179,3,30,9 COMBOBOX 1138,179,13,32,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE | CBS_SORT DEFPUSHBUTTON "OK",IDOK,218,6,40,14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Îòìåíà",IDCANCEL,218,23,40,14,WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Ïðèìåíèòü", 1026,218,40,40,14,WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Ñïðàâêà" , 1038,218,57,40,14,WS_GROUP | WS_TABSTOP - GROUPBOX "Àòðèáóòû",1072,6,72,84,34,WS_GROUP - CHECKBOX "&Çà÷åðêíóòûé", 1040, 10,82,75,10, BS_AUTOCHECKBOX | WS_TABSTOP - CHECKBOX "Ïîä&÷åðêíóòûé", 1041, 10,94,75,10, BS_AUTOCHECKBOX - LTEXT "Ö&âåò:", 1091 ,6,110,30,9 + PUSHBUTTON "Отмена",IDCANCEL,218,23,40,14,WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Применить", 1026,218,40,40,14,WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Справка" , 1038,218,57,40,14,WS_GROUP | WS_TABSTOP + GROUPBOX "Ðтрибуты",1072,6,72,84,34,WS_GROUP + CHECKBOX "&Зачеркнутый", 1040, 10,82,75,10, BS_AUTOCHECKBOX | WS_TABSTOP + CHECKBOX "Под&черкнутый", 1041, 10,94,75,10, BS_AUTOCHECKBOX + LTEXT "Ц&вет:", 1091 ,6,110,30,9 COMBOBOX 1139,6,120,84,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Îáðàçåö",grp2,98,72,120,36,WS_GROUP - CTEXT "ÀàÁáAaBb",stc5,103,80,109,24,SS_NOPREFIX | NOT WS_VISIBLE - LTEXT "Íà&áîð ñèìâîëîâ:",stc7 ,98,114,80,9 + GROUPBOX "Образец",grp2,98,72,120,36,WS_GROUP + CTEXT "ÐаБбAaBb",stc5,103,80,109,24,SS_NOPREFIX | NOT WS_VISIBLE + LTEXT "Ðа&бор Ñимволов:",stc7 ,98,114,80,9 COMBOBOX cmb5,98,124,120,90,CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP } @@ -149,23 +155,23 @@ FONT 8, "MS Shell Dlg" CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 310, 185 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Èçìåíåíèå ïàëèòðû" +CAPTION "Изменение палитры" FONT 8, "MS Shell Dlg" { - LTEXT "&Áàçîâàÿ ïàëèòðà:", 1088, 4, 4, 140, 10 - LTEXT "Äî&ïîëíèòåëüíûå öâåòà:", 1089, 4, 106, 140, 10 - LTEXT "Öâåò|Çà&ëèâêà", 1090, 150, 151, 48, 10 - LTEXT "Êðàñ&íûé:", 726 /*1094*/,254,126,32,10 + LTEXT "&Ð‘Ð°Ð·Ð¾Ð²Ð°Ñ Ð¿Ð°Ð»Ð¸Ñ‚Ñ€Ð°:", 1088, 4, 4, 140, 10 + LTEXT "До&полнительные цвета:", 1089, 4, 106, 140, 10 + LTEXT "Цвет|За&ливка", 1090, 150, 151, 48, 10 + LTEXT "КраÑ&ный:", 726 /*1094*/,254,126,32,10 EDITTEXT 706, 288,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "&Çåë¸íûé:",727/*1095*/,254,140,32,10 + LTEXT "&Зелёный:",727/*1095*/,254,140,32,10 EDITTEXT 707, 288,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "Ñ&èíèé:",728 /*1096*/,264,154,24,10 + LTEXT "С&иний:",728 /*1096*/,264,154,24,10 EDITTEXT 708, 288,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "Î&òòåíîê:" ,723 /*1091*/,202,126,30,10 + LTEXT "О&ттенок:" ,723 /*1091*/,202,126,30,10 EDITTEXT 703, 234,124,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "&Êîíòðàñò:" ,724 /*1092*/,199,140,34,10 + LTEXT "&КонтраÑÑ‚:" ,724 /*1092*/,199,140,34,10 EDITTEXT 704, 234,138,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "&ßðêîñòü:" ,725 /*1093*/,202,154,30,10 + LTEXT "&ЯркоÑть:" ,725 /*1093*/,202,154,30,10 EDITTEXT 705, 234,152,21,12, WS_BORDER | WS_GROUP | WS_TABSTOP CONTROL "" ,720,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,14,140,86 CONTROL "" ,721,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,116,140,28 @@ -173,309 +179,309 @@ FONT 8, "MS Shell Dlg" CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116 CONTROL "" ,709,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,124,40,26 DEFPUSHBUTTON "OK", IDOK, 4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Îòìåíà", IDCANCEL, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Cïðàâêà", 1038,100,166, 44, 14 - PUSHBUTTON "&Äîáàâèòü â íàáîð", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Îïðåäåëèòü öâåò >>", 719/*1025*/, 4, 150, 142, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Отмена", IDCANCEL, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Cправка", 1038,100,166, 44, 14 + PUSHBUTTON "&Добавить в набор", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Определить цвет >>", 719/*1025*/, 4, 150, 142, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&i",713,300,200,4,14 /* just a dummy: 'i' is like &i in "sol&id" */ } FINDDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 245, 62 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Ïîèñê" +CAPTION "ПоиÑк" FONT 8, "MS Shell Dlg" { - LTEXT "&Îáðàçåö:", -1, 4, 8, 42, 8 + LTEXT "&Образец:", -1, 4, 8, 42, 8 EDITTEXT 1152, 47, 7, 138, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP - CHECKBOX "&Òîëüêî ñëîâî öåëèêîì", 1040, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "C &ó÷åòîì ðåãèñòðà", 1041, 4, 42, 100, 12, BS_AUTOCHECKBOX | WS_TABSTOP - GROUPBOX "Íàïðàâëåíèå", 1072, 107, 26, 78, 28 - CONTROL "&Ââåðõ", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 111, 38, 40, 12 - CONTROL "Â&íèç", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 152, 38, 30, 12 + CHECKBOX "&Только Ñлово целиком", 1040, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "C &учетом региÑтра", 1041, 4, 42, 100, 12, BS_AUTOCHECKBOX | WS_TABSTOP + GROUPBOX "Ðаправление", 1072, 107, 26, 78, 28 + CONTROL "&Вверх", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 111, 38, 40, 12 + CONTROL "Ð’&низ", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 152, 38, 30, 12 - DEFPUSHBUTTON "&Íàéòè äàëåå", IDOK, 190, 5, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Îòìåíà", IDCANCEL , 190, 23, 50, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Ñïðàâêà", pshHelp , 190, 45, 50, 14, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Ðайти далее", IDOK, 190, 5, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + PUSHBUTTON "Отмена", IDCANCEL , 190, 23, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Справка", pshHelp , 190, 45, 50, 14, WS_GROUP | WS_TABSTOP } REPLACEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 230, 94 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Çàìåíà" +CAPTION "Замена" FONT 8, "MS Shell Dlg" { - LTEXT "&Îáðàçåö:", -1, 4, 9, 48, 8 + LTEXT "&Образец:", -1, 4, 9, 48, 8 EDITTEXT 1152, 54, 7, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP - LTEXT "Ç&àìåíèòü íà:", -1, 4, 26, 48, 8 + LTEXT "З&аменить на:", -1, 4, 26, 48, 8 EDITTEXT 1153, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP - CHECKBOX "&Òîëüêî ñëîâî öåëèêîì", 1040, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Ñ &ó÷¸òîì ðåãèñòðà", 1041, 5, 62, 104, 12, BS_AUTOCHECKBOX | WS_TABSTOP + CHECKBOX "&Только Ñлово целиком", 1040, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "С &учётом региÑтра", 1041, 5, 62, 104, 12, BS_AUTOCHECKBOX | WS_TABSTOP - DEFPUSHBUTTON "&Íàéòè äàëåå", IDOK, 174, 4, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "&Çàìåíèòü", psh1 , 174, 21, 50, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Çàìåíèòü &âñå", psh2 , 174, 38, 50, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Îòìåíà", IDCANCEL , 174, 55, 50, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Ñïðàâêà", pshHelp , 174, 75, 50, 14, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Ðайти далее", IDOK, 174, 4, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + PUSHBUTTON "&Заменить", psh1 , 174, 21, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Заменить &вÑе", psh2 , 174, 38, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Отмена", IDCANCEL , 174, 55, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Справка", pshHelp , 174, 75, 50, 14, WS_GROUP | WS_TABSTOP } PRINT32 DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 288, 186 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP | DS_3DLOOK -CAPTION "Ïå÷àòü" +CAPTION "Печать" FONT 8, "MS Shell Dlg" { DEFPUSHBUTTON "OK", IDOK, 180,164, 48,14, WS_GROUP | BS_DEFPUSHBUTTON - PUSHBUTTON "Îòìåíà", IDCANCEL, 232,164, 48,14, WS_GROUP - PUSHBUTTON "&Ñïðàâêà", pshHelp, 50, 161, 48,14, WS_GROUP + PUSHBUTTON "Отмена", IDCANCEL, 232,164, 48,14, WS_GROUP + PUSHBUTTON "&Справка", pshHelp, 50, 161, 48,14, WS_GROUP - GROUPBOX "Ïðèíòåð", grp4, 8, 4, 272,84, WS_GROUP - CONTROL "Ïå÷àòü â ôàé&ë", chx1, "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,212,70,64,12 - PUSHBUTTON "&Ñâîéñòâà", psh2, 212, 17, 60,14, WS_GROUP - LTEXT "&Èìÿ:", stc6, 16, 20, 46,8 + GROUPBOX "Принтер", grp4, 8, 4, 272,84, WS_GROUP + CONTROL "Печать в фай&л", chx1, "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,212,70,64,12 + PUSHBUTTON "&СвойÑтва", psh2, 212, 17, 60,14, WS_GROUP + LTEXT "&ИмÑ:", stc6, 16, 20, 46,8 COMBOBOX cmb4, 64, 18, 140,152,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP - LTEXT "Ñòàòóñ:", stc8, 16, 36, 46,10, SS_NOPREFIX - LTEXT "Ýìóëèðîâàí", stc12, 64, 36, 100,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Òèï:", stc7, 16, 48, 46,10, SS_NOPREFIX - LTEXT "Ýìóëèðîâàí", stc11, 64, 48, 100,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Ìåñòî:", stc10, 16, 60, 46,10, SS_NOPREFIX - LTEXT "Ýìóëèðîâàíî", stc14, 64, 60, 100,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Ïðèìå÷àíèå:", stc9, 16, 72, 46,10, SS_NOPREFIX - LTEXT "Ýìóëèðîâàíî", stc13, 64, 72, 100,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "СтатуÑ:", stc8, 16, 36, 46,10, SS_NOPREFIX + LTEXT "Эмулирован", stc12, 64, 36, 100,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Тип:", stc7, 16, 48, 46,10, SS_NOPREFIX + LTEXT "Эмулирован", stc11, 64, 48, 100,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "МеÑто:", stc10, 16, 60, 46,10, SS_NOPREFIX + LTEXT "Эмулировано", stc14, 64, 60, 100,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Примечание:", stc9, 16, 72, 46,10, SS_NOPREFIX + LTEXT "Эмулировано", stc13, 64, 72, 100,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - GROUPBOX "Êîïèè", grp2, 160, 92, 120,64, WS_GROUP - LTEXT "×èñëî &êîïèé:",stc5,168,108,68,8 + GROUPBOX "Копии", grp2, 160, 92, 120,64, WS_GROUP + LTEXT "ЧиÑло &копий:",stc5,168,108,68,8 ICON "", ico3, 162,124, 60,24, WS_GROUP | SS_CENTERIMAGE - CONTROL "&Ðàçáèòü", chx2,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,230,130,42,12 + CONTROL "&Разбить", chx2,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,230,130,42,12 EDITTEXT edt3, 230,106, 42,12, WS_GROUP | ES_NUMBER - GROUPBOX "Ïå÷àòàòü", grp1, 8,92, 144,64, WS_GROUP - CONTROL "&Âñå", rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,106,64,12 - CONTROL "&Ñòðàíèöû", rad3,"Button",BS_AUTORADIOBUTTON,16,122,50,12 - CONTROL "&Âûäåëåíèå", rad2,"Button",BS_AUTORADIOBUTTON,16,138,64,12 + GROUPBOX "Печатать", grp1, 8,92, 144,64, WS_GROUP + CONTROL "&Ð’Ñе", rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,106,64,12 + CONTROL "&Страницы", rad3,"Button",BS_AUTORADIOBUTTON,16,122,50,12 + CONTROL "&Выделение", rad2,"Button",BS_AUTORADIOBUTTON,16,138,64,12 EDITTEXT edt1, 85,122, 20,12, WS_GROUP | ES_NUMBER EDITTEXT edt2, 120,122, 20,12, WS_GROUP | ES_NUMBER - RTEXT "&îò:", stc2, 70,124, 10,8 - RTEXT "&äî:", stc3, 106,124, 10,8 + RTEXT "&от:", stc2, 72,124, 12,8 + RTEXT "&до:", stc3, 108,124, 12,8 } PRINT32_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 288, 178 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP | DS_3DLOOK -CAPTION "Óñòàíîâêè ïðèíòåðà" +CAPTION "УÑтановки принтера" FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "OK",IDOK,180,156,48,14,WS_GROUP - PUSHBUTTON "Îòìåíà",IDCANCEL,232,156,48,14 -/* PUSHBUTTON "Ñåòü...", psh5, 284,156,48,14 */ + PUSHBUTTON "Отмена",IDCANCEL,232,156,48,14 +/* PUSHBUTTON "Сеть...", psh5, 284,156,48,14 */ - GROUPBOX "Ïðèíòåð", grp4, 8, 4, 272,84, WS_GROUP - PUSHBUTTON "&Ñâîéñòâà", psh2, 212, 17, 60,14, WS_GROUP - LTEXT "&Èìÿ:", stc6, 16, 20, 36,8 + GROUPBOX "Принтер", grp4, 8, 4, 272,84, WS_GROUP + PUSHBUTTON "&СвойÑтва", psh2, 212, 17, 60,14, WS_GROUP + LTEXT "&ИмÑ:", stc6, 16, 20, 36,8 COMBOBOX cmb1, 52, 18, 152,152,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP - LTEXT "Ñòàòóñ:", stc8, 16, 36, 36,10, SS_NOPREFIX - LTEXT "Ýìóëèðîâàí", stc12, 52, 36, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Òèï:", stc7, 16, 48, 36,10, SS_NOPREFIX - LTEXT "Ýìóëèðîâàí", stc11, 52, 48, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Ìåñòî:", stc10, 16, 60, 36,10, SS_NOPREFIX - LTEXT "Ýìóëèðîâàíî", stc14, 52, 60, 36,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - LTEXT "Çàìåòêè:", stc9, 16, 72, 36,10, SS_NOPREFIX - LTEXT "Ýìóëèðîâàíû", stc13, 52, 72, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "СтатуÑ:", stc8, 16, 36, 36,10, SS_NOPREFIX + LTEXT "Эмулирован", stc12, 52, 36, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Тип:", stc7, 16, 48, 36,10, SS_NOPREFIX + LTEXT "Эмулирован", stc11, 52, 48, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "МеÑто:", stc10, 16, 60, 36,10, SS_NOPREFIX + LTEXT "Эмулировано", stc14, 52, 60, 36,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "Заметки:", stc9, 16, 72, 36,10, SS_NOPREFIX + LTEXT "Эмулированы", stc13, 52, 72, 224,10, SS_NOPREFIX | SS_LEFTNOWORDWRAP - GROUPBOX "Áóìàãà", grp2, 8, 92, 164,56, WS_GROUP - LTEXT "Ðàç&ìåð:", stc2, 16,108, 36, 8 + GROUPBOX "Бумага", grp2, 8, 92, 164,56, WS_GROUP + LTEXT "Раз&мер:", stc2, 16,108, 36, 8 COMBOBOX cmb2, 52,106, 112,112,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP - LTEXT "&Èñòî÷íèê:", stc3, 16,128, 36, 8 + LTEXT "&ИÑточник:", stc3, 16,128, 36, 8 COMBOBOX cmb3, 52,126, 112,112,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP - GROUPBOX "Îðèåíòàöèÿ", grp1, 180, 92, 100,56, WS_GROUP + GROUPBOX "ОриентациÑ", grp1, 180, 92, 100,56, WS_GROUP ICON "", ico1, 195,112, 18,20, WS_GROUP - CONTROL "&Ïîðòðåò", rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP |WS_TABSTOP,224,106,52,12 - CONTROL "Ë&àíäøàôò", rad2,"Button",BS_AUTORADIOBUTTON,224,126,52,12 + CONTROL "&Портрет", rad1,"Button",BS_AUTORADIOBUTTON | WS_GROUP |WS_TABSTOP,224,106,52,12 + CONTROL "Л&андшафт", rad2,"Button",BS_AUTORADIOBUTTON,224,126,52,12 END PAGESETUPDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 240, 240 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Ïàðàìåòðû ñòðàíèöû" +CAPTION "Параметры Ñтраницы" 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 "Áóìàãà", grp2, 8, 96, 224, 56, BS_GROUPBOX - LTEXT "&Ðàçìåð:", stc2, 16, 112, 36, 8 + GROUPBOX "Бумага", grp2, 8, 96, 224, 56, BS_GROUPBOX + LTEXT "&Размер:", stc2, 16, 112, 36, 8 COMBOBOX cmb2, 64, 110, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL - LTEXT "Ïîäà&÷à:", stc3, 16, 132, 36, 8 + LTEXT "Пода&ча:", stc3, 16, 132, 36, 8 COMBOBOX cmb3, 64, 130, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL - GROUPBOX "Îðèåíòàöèÿ", grp1, 8, 156, 64, 56, BS_GROUPBOX - AUTORADIOBUTTON "Ê&íèæíàÿ", rad1, 16, 170, 52, 12, BS_AUTORADIOBUTTON - AUTORADIOBUTTON "Àëü&áîìíàÿ", rad2, 16, 190, 52, 12, BS_AUTORADIOBUTTON - GROUPBOX "Ïîëÿ", grp4, 80, 156, 152, 56, BS_GROUPBOX - LTEXT "&Ñëåâà:", stc15, 88, 172, 31, 8 + GROUPBOX "ОриентациÑ", grp1, 8, 156, 64, 56, BS_GROUPBOX + AUTORADIOBUTTON "К&нижнаÑ", rad1, 16, 170, 52, 12, BS_AUTORADIOBUTTON + AUTORADIOBUTTON "Ðль&бомнаÑ", rad2, 16, 190, 52, 12, BS_AUTORADIOBUTTON + GROUPBOX "ПолÑ", grp4, 80, 156, 152, 56, BS_GROUPBOX + LTEXT "&Слева:", stc15, 88, 172, 31, 8 EDITTEXT edt4, 121, 170, 29, 12, WS_TABSTOP|WS_GROUP|WS_BORDER - LTEXT "Ñ&âåðõó:", stc16, 159, 172, 27, 8 + LTEXT "С&верху:", stc16, 159, 172, 27, 8 EDITTEXT edt6, 187, 170, 29, 12, WS_TABSTOP|WS_GROUP|WS_BORDER - LTEXT "Ñïð&àâà:", stc17, 88, 192, 31, 8 + LTEXT "Спр&ава:", stc17, 88, 192, 31, 8 EDITTEXT edt5, 121, 190, 29, 12, WS_TABSTOP|WS_GROUP|WS_BORDER - LTEXT "Ñíè&çó:", stc18, 159, 192, 23, 8 + LTEXT "Сни&зу:", stc18, 159, 192, 23, 8 EDITTEXT edt7, 187, 190, 29, 12, WS_TABSTOP|WS_GROUP|WS_BORDER - DEFPUSHBUTTON "ÎÊ", IDOK, 71, 220, 50, 14, BS_PUSHBUTTON - PUSHBUTTON "Îòìåíà", IDCANCEL, 126, 220, 50, 14 - PUSHBUTTON "&Ïðèíòåð...", psh3, 184, 220, 48, 14 + DEFPUSHBUTTON "ОК", IDOK, 71, 220, 50, 14, BS_PUSHBUTTON + PUSHBUTTON "Отмена", IDCANCEL, 126, 220, 50, 14 + PUSHBUTTON "&Принтер...", psh3, 184, 220, 48, 14 END NEWFILEOPENORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 280, 164 STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN -CAPTION "Îòêðûòü" +CAPTION "Открыть" FONT 8, "MS Shell Dlg" { - LTEXT "Èñêàòü &â",IDC_LOOKINSTATIC,4,6,43,8, SS_NOTIFY + LTEXT "ИÑкать &в",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 "Èìÿ &ôàéëà:",IDC_FILENAMESTATIC,5,112,46,8, SS_NOTIFY + LTEXT "Ð˜Ð¼Ñ &файла:",IDC_FILENAMESTATIC,5,112,46,8, SS_NOTIFY EDITTEXT IDC_FILENAME,54,110,155,12,ES_AUTOHSCROLL - LTEXT "&Òèï ôàéëîâ:",IDC_FILETYPESTATIC,5,128,42,8, SS_NOTIFY + LTEXT "&Тип файлов:",IDC_FILETYPESTATIC,5,128,42,8, SS_NOTIFY COMBOBOX IDC_FILETYPE,54,126,155,53,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Òîëüêî äëÿ &÷òåíèÿ",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,145,100,10 + CONTROL "Только Ð´Ð»Ñ &чтениÑ",IDC_OPENREADONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,145,100,10 - DEFPUSHBUTTON "&Îòêðûòü", IDOK,222,110,50,14 - PUSHBUTTON "Îòìåíà", IDCANCEL,222,128,50,14 - PUSHBUTTON "&Ñïðàâêà", pshHelp,222,145,50,14 + DEFPUSHBUTTON "&Открыть", IDOK,222,110,50,14 + PUSHBUTTON "Отмена", IDCANCEL,222,128,50,14 + PUSHBUTTON "&Справка", pshHelp,222,145,50,14 } STRINGTABLE DISCARDABLE { - IDS_ABOUTBOX "&Î òåñòå ÂûáîðÏàïêè" - IDS_DOCUMENTFOLDERS "Ïàïêè äîêóìåíòîâ" - IDS_PERSONAL "Ìîè äîêóìåíòû" - IDS_FAVORITES "Èçáðàííîå" - IDS_PATH "Ñèñòåìíûé ïóòü" - IDS_DESKTOP "Ðàáî÷èé ñòîë" - IDS_FONTS "Øðèôòû" - IDS_MYCOMPUTER "Ìîé êîìïüþòåð" + IDS_ABOUTBOX "&О теÑте ВыборПапки" + IDS_DOCUMENTFOLDERS "Папки документов" + IDS_PERSONAL "Мои документы" + IDS_FAVORITES "Избранное" + IDS_PATH "СиÑтемный путь" + IDS_DESKTOP "Рабочий Ñтол" + IDS_FONTS "Шрифты" + IDS_MYCOMPUTER "Мой компьютер" } STRINGTABLE DISCARDABLE { - IDS_SYSTEMFOLDERS "Ñèñòåìíûå ïàïêè" - IDS_LOCALHARDRIVES "Ëîêàëüíûå æåñòêèå äèñêè" - IDS_FILENOTFOUND "Ôàéë íå íàéäåí" - IDS_VERIFYFILE "Ïðîâåðüòå, ïðàâèëüíî ëè óêàçàíî èìÿ ôàéëà" - IDS_CREATEFILE "Ôàéëà íå ñóùåñòâóåò\nÕîòèòå ëè Âû åãî ñîçäàòü?" - IDS_OVERWRITEFILE "Ôàéë óæå ñóùåñòâóåò.\nÇàìåíèòü åãî?" - IDS_INVALID_FILENAME_TITLE "Íåêîððåêòíûé ñèìâîë â çàïèñè ïóòè" - IDS_INVALID_FILENAME "Èìÿ ôàéëà íå ìîæåò ñîäåðæàòü ñëåäóþùèå ñèìâîëû:\n / : < > |" - IDS_PATHNOTEXISTING "Ïóòü íå ñóùåñòâóåò" - IDS_FILENOTEXISTING "Ôàéë íå ñóùåñòâóåò" + IDS_SYSTEMFOLDERS "СиÑтемные папки" + IDS_LOCALHARDRIVES "Локальные жеÑткие диÑки" + IDS_FILENOTFOUND "Файл не найден" + IDS_VERIFYFILE "Проверьте, правильно ли указано Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°" + IDS_CREATEFILE "Файла не ÑущеÑтвует\nХотите ли Ð’Ñ‹ его Ñоздать?" + IDS_OVERWRITEFILE "Файл уже ÑущеÑтвует.\nЗаменить его?" + IDS_INVALID_FILENAME_TITLE "Ðекорректный Ñимвол в запиÑи пути" + IDS_INVALID_FILENAME "Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° не может Ñодержать Ñледующие Ñимволы:\n / : < > |" + IDS_PATHNOTEXISTING "Путь не ÑущеÑтвует" + IDS_FILENOTEXISTING "Файл не ÑущеÑтвует" } STRINGTABLE DISCARDABLE { - IDS_UPFOLDER "Ââåðõ íà îäèí óðîâåíü" - IDS_NEWFOLDER "Ñîçäàòü íîâóþ ïàïêó" - IDS_LISTVIEW "Ñïèñîê" - IDS_REPORTVIEW "Ïîäðîáíîñòè" - IDS_TODESKTOP "Ïåðåõîä íà ðàáî÷èé ñòîë" + IDS_UPFOLDER "Вверх на один уровень" + IDS_NEWFOLDER "Создать новую папку" + IDS_LISTVIEW "СпиÑок" + IDS_REPORTVIEW "ПодробноÑти" + IDS_TODESKTOP "Переход на рабочий Ñтол" } STRINGTABLE DISCARDABLE { - PD32_PRINT_TITLE "Ïå÷àòü" + PD32_PRINT_TITLE "Печать" - PD32_VALUE_UREADABLE "Íå÷èòàåìûé ýëåìåíò" - PD32_INVALID_PAGE_RANGE "Ýòî çíà÷åíèå íå ëåæèò âíóòðè äèàïàçîíà ñòðàíèö\n\ -Ââåäèòå çíà÷åíèå ìåæäó %d è %d" - PD32_FROM_NOT_ABOVE_TO "Çíà÷åíèå ÎÒ íå äîëæíî ïðåâûøàòü ÄÎ:" - PD32_MARGINS_OVERLAP "Ãðàíèöû ïåðåêðûâàþò èëè ïðåâûøàþò \ -ðàçìåðû áóìàãè.\nÂâåäèòå èõ çàíîâî" - PD32_NR_OF_COPIES_EMPTY "Çíà÷åíèå ×èñëà Êîïèé íå ìîæåò áûòü \ -ïóñòûì" - PD32_TOO_LARGE_COPIES "Òàêîå áîëüøîå êîëè÷åñòâî êîïèé íå \ -ìîæåò áûòü íàïå÷àòàíî Âàøèì ïðèíòåðîì.\nÂâåäèòå çíà÷åíèå ìåæäó 1 è %d" - PD32_PRINT_ERROR "Ïðîèçîøëà îøèáêà ïðèíòåðà" - PD32_NO_DEFAULT_PRINTER "Íåò ïðèíòåðà, óñòàíîâëåííîãî ïî óìîë÷àíèþ" - PD32_CANT_FIND_PRINTER "Íå óäàëîñü íàéòè ïðèíòåð" - PD32_OUT_OF_MEMORY "Ìàëî ïàìÿòè" - PD32_GENERIC_ERROR "Ïðîèçîøëà(è) îøèáêà(è)" - PD32_DRIVER_UNKNOWN "Íåèçâåñòíûé äðàéâåð ïðèíòåðà" - PD32_NO_DEVICES "Îòñóòñòâóþò ïðèíòåðû â ñèñòåìå. \ -Ïðîâåðüòå, ÷òî õîòÿ áû îäèí ïðèíòåð óñòàíîâëåí è ñèñòåìà ïå÷àòè çàïóùåíà. \ + PD32_VALUE_UREADABLE "Ðечитаемый Ñлемент" + PD32_INVALID_PAGE_RANGE "Это значение не лежит внутри диапазона Ñтраниц\n\ +Введите значение между %d и %d" + PD32_FROM_NOT_ABOVE_TO "Значение ОТ не должно превышать ДО:" + PD32_MARGINS_OVERLAP "Границы перекрывают или превышают \ +размеры бумаги.\nВведите их заново" + PD32_NR_OF_COPIES_EMPTY "Значение ЧиÑла Копий не может быть \ +пуÑтым" + PD32_TOO_LARGE_COPIES "Такое большое количеÑтво копий не \ +может быть напечатано Вашим принтером.\nВведите значение между 1 и %d" + PD32_PRINT_ERROR "Произошла ошибка принтера" + PD32_NO_DEFAULT_PRINTER "Ðет принтера, уÑтановленного по умолчанию" + PD32_CANT_FIND_PRINTER "Ðе удалоÑÑŒ найти принтер" + PD32_OUT_OF_MEMORY "Мало памÑти" + PD32_GENERIC_ERROR "Произошла(и) ошибка(и)" + PD32_DRIVER_UNKNOWN "ÐеизвеÑтный драйвер принтера" + PD32_NO_DEVICES "ОтÑутÑтвуют принтеры в ÑиÑтеме. \ +Проверьте, что Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один принтер уÑтановлен и ÑиÑтема печати запущена. \ " - PD32_DEFAULT_PRINTER "Ïðèíòåð ïî óìîë÷àíèþ; " - PD32_NR_OF_DOCUMENTS_IN_QUEUE "%d äîêóìåíòîâ â î÷åðåäè" - PD32_MARGINS_IN_INCHES "Ãðàíèöû [äþéìû)" - PD32_MARGINS_IN_MILLIMETERS "Ãðàíèöû [ìì]" - PD32_MILLIMETERS "ìì" + PD32_DEFAULT_PRINTER "Принтер по умолчанию; " + PD32_NR_OF_DOCUMENTS_IN_QUEUE "%d документов в очереди" + PD32_MARGINS_IN_INCHES "Границы [дюймы)" + PD32_MARGINS_IN_MILLIMETERS "Границы [мм]" + PD32_MILLIMETERS "мм" - PD32_PRINTER_STATUS_READY "Ãîòîâî" - PD32_PRINTER_STATUS_PAUSED "Ïðèîñòàíîâëåíî; " - PD32_PRINTER_STATUS_ERROR "Îøèáêà; " - PD32_PRINTER_STATUS_PENDING_DELETION "Îæèäàíèå óäàëåíèÿ; " - PD32_PRINTER_STATUS_PAPER_JAM "Áóìàãà çàñòðÿëà; " - PD32_PRINTER_STATUS_PAPER_OUT "Íå õâàòàåò áóìàãè; " - PD32_PRINTER_STATUS_MANUAL_FEED "Âñòàâüòå áóìàãó âðó÷íóþ; " - PD32_PRINTER_STATUS_PAPER_PROBLEM "Ïðîáëåìà ñ áóìàãîé; " - PD32_PRINTER_STATUS_OFFLINE "Ïðèíòåð â ðåæèìå offline; " - PD32_PRINTER_STATUS_IO_ACTIVE "Ââîä/Âûâîä àêòèâåí; " - PD32_PRINTER_STATUS_BUSY "Çàíÿò; " - PD32_PRINTER_STATUS_PRINTING "Èäåò ïå÷àòü; " - PD32_PRINTER_STATUS_OUTPUT_BIN_FULL "Ëîòîê ïåðåïîëíåí áóìàãîé; " - PD32_PRINTER_STATUS_NOT_AVAILABLE "Íå äîñòóïåí; " - PD32_PRINTER_STATUS_WAITING "Îæèäàíèå; " - PD32_PRINTER_STATUS_PROCESSING "Îáðàáîòêà; " - PD32_PRINTER_STATUS_INITIALIZING "Ïîäãîòîâêà; " - PD32_PRINTER_STATUS_WARMING_UP "Ïðîãðåâ; " - PD32_PRINTER_STATUS_TONER_LOW "Òîíåð íà èñõîäå; " - PD32_PRINTER_STATUS_NO_TONER "Íåò òîíåðà; " + PD32_PRINTER_STATUS_READY "Готово" + PD32_PRINTER_STATUS_PAUSED "ПриоÑтановлено; " + PD32_PRINTER_STATUS_ERROR "Ошибка; " + PD32_PRINTER_STATUS_PENDING_DELETION "Ожидание удалениÑ; " + PD32_PRINTER_STATUS_PAPER_JAM "Бумага заÑтрÑла; " + PD32_PRINTER_STATUS_PAPER_OUT "Ðе хватает бумаги; " + PD32_PRINTER_STATUS_MANUAL_FEED "Ð’Ñтавьте бумагу вручную; " + PD32_PRINTER_STATUS_PAPER_PROBLEM "Проблема Ñ Ð±ÑƒÐ¼Ð°Ð³Ð¾Ð¹; " + PD32_PRINTER_STATUS_OFFLINE "Принтер в режиме offline; " + PD32_PRINTER_STATUS_IO_ACTIVE "Ввод/Вывод активен; " + PD32_PRINTER_STATUS_BUSY "ЗанÑÑ‚; " + PD32_PRINTER_STATUS_PRINTING "Идет печать; " + PD32_PRINTER_STATUS_OUTPUT_BIN_FULL "Лоток переполнен бумагой; " + PD32_PRINTER_STATUS_NOT_AVAILABLE "Ðе доÑтупен; " + PD32_PRINTER_STATUS_WAITING "Ожидание; " + PD32_PRINTER_STATUS_PROCESSING "Обработка; " + PD32_PRINTER_STATUS_INITIALIZING "Подготовка; " + PD32_PRINTER_STATUS_WARMING_UP "Прогрев; " + PD32_PRINTER_STATUS_TONER_LOW "Тонер на иÑходе; " + PD32_PRINTER_STATUS_NO_TONER "Ðет тонера; " PD32_PRINTER_STATUS_PAGE_PUNT "Page punt; " - PD32_PRINTER_STATUS_USER_INTERVENTION "Ïðåðâàíî ïîëüçîâàòåëåì; " - PD32_PRINTER_STATUS_OUT_OF_MEMORY "Ìàëî ïàìÿòè; " - PD32_PRINTER_STATUS_DOOR_OPEN "Êðûøêà ïðèíòåðà îòêðûòà; " - PD32_PRINTER_STATUS_SERVER_UNKNOWN "Íåèçâåñòíûé ñåðâåð ïðèíòåðà; " - PD32_PRINTER_STATUS_POWER_SAVE "Ïèòàíèå â áåçîïàñíîì ðåæèìå; " + PD32_PRINTER_STATUS_USER_INTERVENTION "Прервано пользователем; " + PD32_PRINTER_STATUS_OUT_OF_MEMORY "Мало памÑти; " + PD32_PRINTER_STATUS_DOOR_OPEN "Крышка принтера открыта; " + PD32_PRINTER_STATUS_SERVER_UNKNOWN "ÐеизвеÑтный Ñервер принтера; " + PD32_PRINTER_STATUS_POWER_SAVE "Питание в безопаÑном режиме; " } STRINGTABLE DISCARDABLE /* Font styles */ { - IDS_FONT_REGULAR "Íîðìàëüíûé" - IDS_FONT_BOLD "Æèðíûé" - IDS_FONT_ITALIC "Êóðñèâ" - IDS_FONT_BOLD_ITALIC "Æèðíûé êóðñèâ" + IDS_FONT_REGULAR "Ðормальный" + IDS_FONT_BOLD "Жирный" + IDS_FONT_ITALIC "КурÑив" + IDS_FONT_BOLD_ITALIC "Жирный курÑив" } STRINGTABLE DISCARDABLE /* Color names */ { - IDS_COLOR_BLACK "׸ðíûé" - IDS_COLOR_MAROON "Ò¸ìíî-áîðäîâûé" - IDS_COLOR_GREEN "Çåë¸íûé" - IDS_COLOR_OLIVE "Îëèâêîâûé" - IDS_COLOR_NAVY "Ò¸ìíî-ñèíèé" - IDS_COLOR_PURPLE "Ïóðïóðíûé" - IDS_COLOR_TEAL "Ìîðñêîé âîëíû" - IDS_COLOR_GRAY "Ñåðûé" - IDS_COLOR_SILVER "Ñåðåáðÿíûé" - IDS_COLOR_RED "Êðàñíûé" - IDS_COLOR_LIME "Ëèìîííûé" - IDS_COLOR_YELLOW "Ƹëòûé" - IDS_COLOR_BLUE "Ñèíèé" - IDS_COLOR_FUCHSIA "ßðêî-ðîçîâûé" - IDS_COLOR_AQUA "Ãîëóáîé" - IDS_COLOR_WHITE "Áåëûé" + IDS_COLOR_BLACK "Чёрный" + IDS_COLOR_MAROON "Тёмно-бордовый" + IDS_COLOR_GREEN "Зелёный" + IDS_COLOR_OLIVE "Оливковый" + IDS_COLOR_NAVY "Тёмно-Ñиний" + IDS_COLOR_PURPLE "Пурпурный" + IDS_COLOR_TEAL "МорÑкой волны" + IDS_COLOR_GRAY "Серый" + IDS_COLOR_SILVER "СеребрÑный" + IDS_COLOR_RED "КраÑный" + IDS_COLOR_LIME "Лимонный" + IDS_COLOR_YELLOW "Жёлтый" + IDS_COLOR_BLUE "Синий" + IDS_COLOR_FUCHSIA "Ярко-розовый" + IDS_COLOR_AQUA "Голубой" + IDS_COLOR_WHITE "Белый" } STRINGTABLE DISCARDABLE { - IDS_FONT_SIZE "Âûáåðèòå øðèôò ðàçìåðîì %d - %d ïóíêòîâ." - IDS_SAVE_BUTTON "&Ñîõðàíèòü" - IDS_SAVE_IN "Ñîõðàíèòü &â:" - IDS_SAVE "Ñîõðàíèòü" - IDS_SAVE_AS "Ñîõðàíèòü êàê" - IDS_OPEN_FILE "Îòêðûòü ôàéë" + IDS_FONT_SIZE "Выберите шрифт размером %d - %d пунктов." + IDS_SAVE_BUTTON "&Сохранить" + IDS_SAVE_IN "Сохранить &в:" + IDS_SAVE "Сохранить" + IDS_SAVE_AS "Сохранить как" + IDS_OPEN_FILE "Открыть файл" } diff --git a/reactos/dll/win32/comdlg32/cdlg_Si.rc b/reactos/dll/win32/comdlg32/cdlg_Si.rc index 0650f535920..e3d37e93055 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Si.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Si.rc @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ @@ -481,5 +484,3 @@ STRINGTABLE DISCARDABLE IDS_SAVE_AS "Shrani kot" IDS_OPEN_FILE "Odpri datoteko" } - -#pragma code_page(default) diff --git a/reactos/dll/win32/comdlg32/cdlg_Sk.rc b/reactos/dll/win32/comdlg32/cdlg_Sk.rc index 7fbc5a9c66e..4a2ef2745aa 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Sk.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Sk.rc @@ -17,6 +17,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Sv.rc b/reactos/dll/win32/comdlg32/cdlg_Sv.rc index ed763b481fa..21d2ac2c1fe 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Sv.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Sv.rc @@ -17,6 +17,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Th.rc b/reactos/dll/win32/comdlg32/cdlg_Th.rc index 2e7131fd90d..34ef5200ece 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Th.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Th.rc @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Tr.rc b/reactos/dll/win32/comdlg32/cdlg_Tr.rc index ba95000e53a..52e71ba52b8 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Tr.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Tr.rc @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Uk.rc b/reactos/dll/win32/comdlg32/cdlg_Uk.rc index bb23fe93742..730d610e4bf 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Uk.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Uk.rc @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Wa.rc b/reactos/dll/win32/comdlg32/cdlg_Wa.rc index 7eaf41731c3..ea7e23484ec 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Wa.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Wa.rc @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ diff --git a/reactos/dll/win32/comdlg32/cdlg_Zh.rc b/reactos/dll/win32/comdlg32/cdlg_Zh.rc index d17896edc76..fee8bda01d5 100644 --- a/reactos/dll/win32/comdlg32/cdlg_Zh.rc +++ b/reactos/dll/win32/comdlg32/cdlg_Zh.rc @@ -20,6 +20,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "cdlg.h" +#include "filedlgbrowser.h" + /* * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES. */ @@ -709,5 +712,3 @@ STRINGTABLE DISCARDABLE PD32_PRINTER_STATUS_SERVER_UNKNOWN "找ä¸åˆ°åˆ—å°æœå‹™å™¨; " PD32_PRINTER_STATUS_POWER_SAVE "çœé›»ç‹€æ…‹; " } - -#pragma code_page(default) diff --git a/reactos/dll/win32/comdlg32/cdlg_xx.rc b/reactos/dll/win32/comdlg32/cdlg_xx.rc index dcc3ef328db..24139d2e206 100644 --- a/reactos/dll/win32/comdlg32/cdlg_xx.rc +++ b/reactos/dll/win32/comdlg32/cdlg_xx.rc @@ -19,9 +19,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "windef.h" -#include "winbase.h" -#include "winver.h" +#include "cdlg.h" LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL @@ -73,9 +71,6 @@ PD32_PORTRAIT ICON pd32_portrait.ico /* @makedep: pd32_landscape.ico */ PD32_LANDSCAPE ICON pd32_landscape.ico -/* @makedep: 800.bmp */ -800 BITMAP DISCARDABLE LOADONCALL "800.bmp" - /* @makedep: folder.ico */ FOLDER ICON folder.ico diff --git a/reactos/dll/win32/comdlg32/colordlg.c b/reactos/dll/win32/comdlg32/colordlg.c index 52439d39f1d..ed806acf16e 100644 --- a/reactos/dll/win32/comdlg32/colordlg.c +++ b/reactos/dll/win32/comdlg32/colordlg.c @@ -93,7 +93,7 @@ typedef struct CCPRIVATE /*********************************************************************** * CC_HSLtoRGB [internal] */ -int CC_HSLtoRGB(char c, int hue, int sat, int lum) +static int CC_HSLtoRGB(char c, int hue, int sat, int lum) { int res = 0, maxrgb; @@ -138,7 +138,7 @@ int CC_HSLtoRGB(char c, int hue, int sat, int lum) /*********************************************************************** * CC_RGBtoHSL [internal] */ -int CC_RGBtoHSL(char c, int r, int g, int b) +static int CC_RGBtoHSL(char c, int r, int g, int b) { WORD maxi, mini, mmsum, mmdif, result = 0; int iresult = 0; @@ -365,7 +365,7 @@ static int CC_MouseCheckColorGraph( HWND hDlg, int dlgitem, int *hori, int *vert * CC_MouseCheckResultWindow [internal] * test if double click one of the result colors */ -int CC_MouseCheckResultWindow( HWND hDlg, LPARAM lParam ) +static int CC_MouseCheckResultWindow( HWND hDlg, LPARAM lParam ) { HWND hwnd; POINT point; @@ -386,7 +386,7 @@ int CC_MouseCheckResultWindow( HWND hDlg, LPARAM lParam ) /*********************************************************************** * CC_CheckDigitsInEdit [internal] */ -int CC_CheckDigitsInEdit( HWND hwnd, int maxval ) +static int CC_CheckDigitsInEdit( HWND hwnd, int maxval ) { int i, k, m, result, value; long editpos; @@ -428,7 +428,7 @@ int CC_CheckDigitsInEdit( HWND hwnd, int maxval ) /*********************************************************************** * CC_PaintSelectedColor [internal] */ -void CC_PaintSelectedColor( HWND hDlg, COLORREF cr ) +static void CC_PaintSelectedColor( HWND hDlg, COLORREF cr ) { RECT rect; HDC hdc; @@ -452,7 +452,7 @@ void CC_PaintSelectedColor( HWND hDlg, COLORREF cr ) /*********************************************************************** * CC_PaintTriangle [internal] */ -void CC_PaintTriangle( HWND hDlg, int y) +static void CC_PaintTriangle( HWND hDlg, int y) { HDC hDC; long temp; @@ -503,7 +503,7 @@ void CC_PaintTriangle( HWND hDlg, int y) /*********************************************************************** * CC_PaintCross [internal] */ -void CC_PaintCross( HWND hDlg, int x, int y) +static void CC_PaintCross( HWND hDlg, int x, int y) { HDC hDC; int w = GetDialogBaseUnits() - 1; @@ -660,7 +660,7 @@ static void CC_PaintLumBar( HWND hDlg, int hue, int sat ) /*********************************************************************** * CC_EditSetRGB [internal] */ -void CC_EditSetRGB( HWND hDlg, COLORREF cr ) +static void CC_EditSetRGB( HWND hDlg, COLORREF cr ) { char buffer[10]; LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp ); @@ -683,7 +683,7 @@ void CC_EditSetRGB( HWND hDlg, COLORREF cr ) /*********************************************************************** * CC_EditSetHSL [internal] */ -void CC_EditSetHSL( HWND hDlg, int h, int s, int l ) +static void CC_EditSetHSL( HWND hDlg, int h, int s, int l ) { char buffer[10]; LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp ); @@ -705,7 +705,7 @@ void CC_EditSetHSL( HWND hDlg, int h, int s, int l ) /*********************************************************************** * CC_SwitchToFullSize [internal] */ -void CC_SwitchToFullSize( HWND hDlg, COLORREF result, LPCRECT lprect ) +static void CC_SwitchToFullSize( HWND hDlg, COLORREF result, LPCRECT lprect ) { int i; LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp ); @@ -784,7 +784,7 @@ static void CC_PaintPredefColorArray( HWND hDlg, int rows, int cols) * CC_PaintUserColorArray [internal] * Paint the 16 user-selected colors */ -void CC_PaintUserColorArray( HWND hDlg, int rows, int cols, const COLORREF *lpcr ) +static void CC_PaintUserColorArray( HWND hDlg, int rows, int cols, const COLORREF *lpcr ) { HWND hwnd = GetDlgItem(hDlg, 0x2d1); RECT rect, blockrect; @@ -835,7 +835,7 @@ void CC_PaintUserColorArray( HWND hDlg, int rows, int cols, const COLORREF *lpcr /*********************************************************************** * CC_HookCallChk [internal] */ -BOOL CC_HookCallChk( const CHOOSECOLORW *lpcc ) +static BOOL CC_HookCallChk( const CHOOSECOLORW *lpcc ) { if (lpcc) if(lpcc->Flags & CC_ENABLEHOOK) @@ -847,7 +847,7 @@ BOOL CC_HookCallChk( const CHOOSECOLORW *lpcc ) /*********************************************************************** * CC_WMInitDialog [internal] */ -static LONG CC_WMInitDialog( HWND hDlg, WPARAM wParam, LPARAM lParam ) +static LRESULT CC_WMInitDialog( HWND hDlg, WPARAM wParam, LPARAM lParam ) { int i, res; int r, g, b; @@ -1081,7 +1081,7 @@ static LRESULT CC_WMCommand( HWND hDlg, WPARAM wParam, LPARAM lParam, WORD notif /*********************************************************************** * CC_WMPaint [internal] */ -LRESULT CC_WMPaint( HWND hDlg, WPARAM wParam, LPARAM lParam ) +static LRESULT CC_WMPaint( HWND hDlg ) { PAINTSTRUCT ps; LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp ); @@ -1103,7 +1103,7 @@ LRESULT CC_WMPaint( HWND hDlg, WPARAM wParam, LPARAM lParam ) /*********************************************************************** * CC_WMLButtonUp [internal] */ -LRESULT CC_WMLButtonUp( HWND hDlg, WPARAM wParam, LPARAM lParam ) +static LRESULT CC_WMLButtonUp( HWND hDlg ) { LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp ); @@ -1120,7 +1120,7 @@ LRESULT CC_WMLButtonUp( HWND hDlg, WPARAM wParam, LPARAM lParam ) /*********************************************************************** * CC_WMMouseMove [internal] */ -LRESULT CC_WMMouseMove( HWND hDlg, LPARAM lParam ) +static LRESULT CC_WMMouseMove( HWND hDlg, LPARAM lParam ) { LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp ); int r, g, b; @@ -1158,7 +1158,7 @@ LRESULT CC_WMMouseMove( HWND hDlg, LPARAM lParam ) /*********************************************************************** * CC_WMLButtonDown [internal] */ -LRESULT CC_WMLButtonDown( HWND hDlg, WPARAM wParam, LPARAM lParam ) +static LRESULT CC_WMLButtonDown( HWND hDlg, LPARAM lParam ) { LPCCPRIV lpp = GetPropW( hDlg, szColourDialogProp ); int r, g, b, i; @@ -1252,7 +1252,7 @@ static INT_PTR CALLBACK ColorDlgProc( HWND hDlg, UINT message, return TRUE; break; case WM_PAINT: - if ( CC_WMPaint(hDlg, wParam, lParam)) + if (CC_WMPaint(hDlg)) return TRUE; break; case WM_LBUTTONDBLCLK: @@ -1264,11 +1264,11 @@ static INT_PTR CALLBACK ColorDlgProc( HWND hDlg, UINT message, return TRUE; break; case WM_LBUTTONUP: /* FIXME: ClipCursor off (if in color graph)*/ - if (CC_WMLButtonUp(hDlg, wParam, lParam)) + if (CC_WMLButtonUp(hDlg)) return TRUE; break; case WM_LBUTTONDOWN:/* FIXME: ClipCursor on (if in color graph)*/ - if (CC_WMLButtonDown(hDlg, wParam, lParam)) + if (CC_WMLButtonDown(hDlg, lParam)) return TRUE; break; } @@ -1366,7 +1366,7 @@ BOOL WINAPI ChooseColorA( LPCHOOSECOLORA lpChCol ) lpcc->lCustData = lpChCol->lCustData; lpcc->lpfnHook = lpChCol->lpfnHook; if ((lpcc->Flags & CC_ENABLETEMPLATE) && (lpChCol->lpTemplateName)) { - if (HIWORD(lpChCol->lpTemplateName)) { + if (!IS_INTRESOURCE(lpChCol->lpTemplateName)) { INT len = MultiByteToWideChar( CP_ACP, 0, lpChCol->lpTemplateName, -1, NULL, 0); template_name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); MultiByteToWideChar( CP_ACP, 0, lpChCol->lpTemplateName, -1, template_name, len ); diff --git a/reactos/dll/win32/comdlg32/comdlg32.rbuild b/reactos/dll/win32/comdlg32/comdlg32.rbuild index 034626cc29f..d9ea84d9e28 100644 --- a/reactos/dll/win32/comdlg32/comdlg32.rbuild +++ b/reactos/dll/win32/comdlg32/comdlg32.rbuild @@ -12,7 +12,7 @@ filedlg.c filedlg31.c filedlgbrowser.c - finddlg32.c + finddlg.c fontdlg.c printdlg.c rsrc.rc diff --git a/reactos/dll/win32/comdlg32/filedlg.c b/reactos/dll/win32/comdlg32/filedlg.c index a28c4574e9f..58b57ccbbac 100644 --- a/reactos/dll/win32/comdlg32/filedlg.c +++ b/reactos/dll/win32/comdlg32/filedlg.c @@ -105,11 +105,6 @@ typedef struct tagLookInInfo UINT uSelectedItem; } LookInInfos; -typedef struct tagFD32_PRIVATE -{ - OPENFILENAMEA *ofnA; /* original structure if 32bits ansi dialog */ -} FD32_PRIVATE, *PFD32_PRIVATE; - /*********************************************************************** * Defines and global variables @@ -271,6 +266,13 @@ static BOOL GetFileName95(FileOpenDlgInfos *fodInfos) return FALSE; } + /* msdn: explorer style dialogs permit sizing by default. + * The OFN_ENABLESIZING flag is only needed when a hook or + * custom tmeplate 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) { ((LPDLGTEMPLATEW)template)->style |= WS_SIZEBOX; @@ -1320,15 +1322,16 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd) {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 }, }; - TBADDBITMAP tba[2]; + static const TBADDBITMAP tba = {HINST_COMMCTRL, IDB_VIEW_SMALL_COLOR}; + RECT rectTB; RECT rectlook; - FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr); - tba[0].hInst = HINST_COMMCTRL; - tba[0].nID = IDB_VIEW_SMALL_COLOR; - tba[1].hInst = COMDLG32_hInstance; - tba[1].nID = 800; + HIMAGELIST toolbarImageList; + SHFILEINFOA shFileInfo; + ITEMIDLIST *desktopPidl; + + FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr); TRACE("%p\n", fodInfos); @@ -1378,9 +1381,19 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd) /* 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[0]); - SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBITMAP, 1, (LPARAM) &tba[1]); + 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); + SHGetFileInfoA((LPCSTR)desktopPidl, 0, &shFileInfo, sizeof(shFileInfo), + SHGFI_PIDL | SHGFI_ICON | SHGFI_SMALLICON); + ImageList_AddIcon(toolbarImageList, shFileInfo.hIcon); + + DestroyIcon(shFileInfo.hIcon); + CoTaskMemFree(desktopPidl); + + /* Finish Toolbar Construction */ SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBUTTONSW, 9, (LPARAM) tbb); SendMessageW(fodInfos->DlgInfos.hwndTB, TB_AUTOSIZE, 0, 0); @@ -1509,12 +1522,11 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd) if ( win98plus && handledPath == FALSE && fodInfos->filter && *fodInfos->filter) { - BOOL searchMore = TRUE; LPCWSTR lpstrPos = fodInfos->filter; WIN32_FIND_DATAW FindFileData; HANDLE hFind; - while (searchMore) + while (1) { /* filter is a list... title\0ext\0......\0\0 */ @@ -1532,7 +1544,6 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd) lpstrPos += lstrlenW(lpstrPos) + 1; } else { - searchMore = FALSE; MemFree(fodInfos->initdir); fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR)); @@ -1541,6 +1552,7 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd) 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; } } @@ -1977,15 +1989,15 @@ BOOL FILEDLG95_OnOpen(HWND hwnd) 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); - /* try if the user selected a folder in the shellview */ if(nFileCount == 0) - { - BrowseSelectedFolder(hwnd); return FALSE; - } if(nFileCount > 1) { @@ -3189,7 +3201,7 @@ static int FILEDLG95_LOOKIN_RemoveMostExpandedItem(HWND hwnd) if(liInfos->iMaxIndentation <= 2) return -1; - if((iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)liInfos->iMaxIndentation,SEARCH_EXP)) >=0) + if((iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,liInfos->iMaxIndentation,SEARCH_EXP)) >=0) { SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,iItemPos); COMDLG32_SHFree(tmpFolder->pidlItem); @@ -3240,6 +3252,7 @@ static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMet static void FILEDLG95_LOOKIN_Clean(HWND hwnd) { FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr); + LookInInfos *liInfos = GetPropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr); int iPos; int iCount = CBGetCount(fodInfos->DlgInfos.hwndLookInCB); @@ -3258,9 +3271,10 @@ static void FILEDLG95_LOOKIN_Clean(HWND hwnd) } /* LookInInfos structure */ + MemFree(liInfos); RemovePropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr); - } + /*********************************************************************** * FILEDLG95_FILENAME_FillFromSelection * @@ -3344,7 +3358,7 @@ void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd) SetWindowTextW( fodInfos->DlgInfos.hwndFileName, lpstrAllFile ); /* Select the file name like Windows does */ - SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, (LPARAM)-1); + SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1); } HeapFree(GetProcessHeap(),0, lpstrAllFile ); } @@ -3726,10 +3740,10 @@ static void MemFree(void *mem) * by a 32 bits application * */ -static BOOL FD32_GetTemplate(PFD31_DATA lfs) +BOOL FD32_GetTemplate(PFD31_DATA lfs) { LPOPENFILENAMEW ofnW = lfs->ofnW; - PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632; + LPOPENFILENAMEA ofnA = lfs->ofnA; HANDLE hDlgTmpl; if (ofnW->Flags & OFN_ENABLETEMPLATEHANDLE) @@ -3743,9 +3757,9 @@ static BOOL FD32_GetTemplate(PFD31_DATA lfs) else if (ofnW->Flags & OFN_ENABLETEMPLATE) { HRSRC hResInfo; - if (priv->ofnA) - hResInfo = FindResourceA(priv->ofnA->hInstance, - priv->ofnA->lpTemplateName, + if (ofnA) + hResInfo = FindResourceA(ofnA->hInstance, + ofnA->lpTemplateName, (LPSTR)RT_DIALOG); else hResInfo = FindResourceW(ofnW->hInstance, @@ -3782,151 +3796,6 @@ static BOOL FD32_GetTemplate(PFD31_DATA lfs) } -/************************************************************************ - * FD32_Init [internal] - * called from the common 16/32 code to initialize 32 bit data - */ -static BOOL CALLBACK FD32_Init(LPARAM lParam, PFD31_DATA lfs, DWORD data) -{ - BOOL IsUnicode = (BOOL) data; - PFD32_PRIVATE priv; - - priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FD32_PRIVATE)); - lfs->private1632 = priv; - if (NULL == lfs->private1632) return FALSE; - if (IsUnicode) - { - lfs->ofnW = (LPOPENFILENAMEW) lParam; - if (lfs->ofnW->Flags & OFN_ENABLEHOOK) - if (lfs->ofnW->lpfnHook) - lfs->hook = TRUE; - } - else - { - priv->ofnA = (LPOPENFILENAMEA) lParam; - if (priv->ofnA->Flags & OFN_ENABLEHOOK) - if (priv->ofnA->lpfnHook) - lfs->hook = TRUE; - lfs->ofnW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*lfs->ofnW)); - FD31_MapOfnStructA(priv->ofnA, lfs->ofnW, lfs->open); - } - - if (! FD32_GetTemplate(lfs)) return FALSE; - - return TRUE; -} - -/*********************************************************************** - * FD32_CallWindowProc [internal] - * - * called from the common 16/32 code to call the appropriate hook - */ -static BOOL CALLBACK FD32_CallWindowProc(const FD31_DATA *lfs, UINT wMsg, WPARAM wParam, - LPARAM lParam) -{ - BOOL ret; - PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632; - - if (priv->ofnA) - { - TRACE("Call hookA %p (%p, %04x, %08lx, %08lx)\n", - priv->ofnA->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); - ret = priv->ofnA->lpfnHook(lfs->hwnd, wMsg, wParam, lParam); - TRACE("ret hookA %p (%p, %04x, %08lx, %08lx)\n", - priv->ofnA->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); - return ret; - } - - TRACE("Call hookW %p (%p, %04x, %08lx, %08lx)\n", - lfs->ofnW->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); - ret = lfs->ofnW->lpfnHook(lfs->hwnd, wMsg, wParam, lParam); - TRACE("Ret hookW %p (%p, %04x, %08lx, %08lx)\n", - lfs->ofnW->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); - return ret; -} - -/*********************************************************************** - * FD32_UpdateResult [internal] - * update the real client structures if any - */ -static void CALLBACK FD32_UpdateResult(const FD31_DATA *lfs) -{ - PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632; - LPOPENFILENAMEW ofnW = lfs->ofnW; - - if (priv->ofnA) - { - LPSTR lpszTemp; - if (ofnW->nMaxFile && - !WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFile, -1, - priv->ofnA->lpstrFile, ofnW->nMaxFile, NULL, NULL )) - priv->ofnA->lpstrFile[ofnW->nMaxFile-1] = 0; - - /* offsets are not guaranteed to be the same in WCHAR to MULTIBYTE conversion */ - /* set filename offset */ - lpszTemp = PathFindFileNameA(priv->ofnA->lpstrFile); - priv->ofnA->nFileOffset = (lpszTemp - priv->ofnA->lpstrFile); - - /* set extension offset */ - lpszTemp = PathFindExtensionA(priv->ofnA->lpstrFile); - priv->ofnA->nFileExtension = (*lpszTemp) ? (lpszTemp - priv->ofnA->lpstrFile) + 1 : 0; - } -} - -/*********************************************************************** - * FD32_UpdateFileTitle [internal] - * update the real client structures if any - */ -static void CALLBACK FD32_UpdateFileTitle(const FD31_DATA *lfs) -{ - PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632; - LPOPENFILENAMEW ofnW = lfs->ofnW; - - if (priv->ofnA) - { - if (!WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFileTitle, -1, - priv->ofnA->lpstrFileTitle, ofnW->nMaxFileTitle, NULL, NULL )) - priv->ofnA->lpstrFileTitle[ofnW->nMaxFileTitle-1] = 0; - } -} - - -/*********************************************************************** - * FD32_SendLbGetCurSel [internal] - * retrieve selected listbox item - */ -static LRESULT CALLBACK FD32_SendLbGetCurSel(const FD31_DATA *lfs) -{ - return SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETCURSEL, 0, 0); -} - - -/************************************************************************ - * FD32_Destroy [internal] - * called from the common 16/32 code to cleanup 32 bit data - */ -static void CALLBACK FD32_Destroy(const FD31_DATA *lfs) -{ - PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632; - - /* if ofnW has been allocated, have to free everything in it */ - if (NULL != priv && NULL != priv->ofnA) - { - FD31_FreeOfnW(lfs->ofnW); - HeapFree(GetProcessHeap(), 0, lfs->ofnW); - } -} - -static void FD32_SetupCallbacks(PFD31_CALLBACKS callbacks) -{ - callbacks->Init = FD32_Init; - callbacks->CWP = FD32_CallWindowProc; - callbacks->UpdateResult = FD32_UpdateResult; - callbacks->UpdateFileTitle = FD32_UpdateFileTitle; - callbacks->SendLbGetCurSel = FD32_SendLbGetCurSel; - callbacks->Destroy = FD32_Destroy; -} - /*********************************************************************** * FD32_WMMeasureItem [internal] */ @@ -3998,20 +3867,16 @@ static BOOL GetFileName31A(LPOPENFILENAMEA lpofn, /* address of structure with d UINT dlgType /* type dialogue : open/save */ ) { - HINSTANCE hInst; BOOL bRet = FALSE; PFD31_DATA lfs; - FD31_CALLBACKS callbacks; if (!lpofn || !FD31_Init()) return FALSE; TRACE("ofn flags %08x\n", lpofn->Flags); - FD32_SetupCallbacks(&callbacks); - lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, &callbacks, (DWORD) FALSE); + lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, FALSE); if (lfs) { - hInst = (HINSTANCE)GetWindowLongPtrW( lpofn->hwndOwner, GWLP_HINSTANCE ); - bRet = DialogBoxIndirectParamA( hInst, lfs->template, lpofn->hwndOwner, + bRet = DialogBoxIndirectParamA( COMDLG32_hInstance, lfs->template, lpofn->hwndOwner, FD32_FileOpenDlgProc, (LPARAM)lfs); FD31_DestroyPrivate(lfs); } @@ -4029,19 +3894,15 @@ static BOOL GetFileName31W(LPOPENFILENAMEW lpofn, /* address of structure with d UINT dlgType /* type dialogue : open/save */ ) { - HINSTANCE hInst; BOOL bRet = FALSE; PFD31_DATA lfs; - FD31_CALLBACKS callbacks; if (!lpofn || !FD31_Init()) return FALSE; - FD32_SetupCallbacks(&callbacks); - lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, &callbacks, (DWORD) TRUE); + lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, TRUE); if (lfs) { - hInst = (HINSTANCE)GetWindowLongPtrW( lpofn->hwndOwner, GWLP_HINSTANCE ); - bRet = DialogBoxIndirectParamW( hInst, lfs->template, lpofn->hwndOwner, + bRet = DialogBoxIndirectParamW( COMDLG32_hInstance, lfs->template, lpofn->hwndOwner, FD32_FileOpenDlgProc, (LPARAM)lfs); FD31_DestroyPrivate(lfs); } diff --git a/reactos/dll/win32/comdlg32/filedlg31.c b/reactos/dll/win32/comdlg32/filedlg31.c index 3e431782d21..29c63106975 100644 --- a/reactos/dll/win32/comdlg32/filedlg31.c +++ b/reactos/dll/win32/comdlg32/filedlg31.c @@ -109,7 +109,24 @@ static void FD31_StripEditControl(HWND hwnd) BOOL FD31_CallWindowProc(const FD31_DATA *lfs, UINT wMsg, WPARAM wParam, LPARAM lParam) { - return lfs->callbacks->CWP(lfs, wMsg, wParam, lParam); + BOOL ret; + + if (lfs->ofnA) + { + TRACE("Call hookA %p (%p, %04x, %08lx, %08lx)\n", + lfs->ofnA->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); + ret = lfs->ofnA->lpfnHook(lfs->hwnd, wMsg, wParam, lParam); + TRACE("ret hookA %p (%p, %04x, %08lx, %08lx)\n", + lfs->ofnA->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); + return ret; + } + + TRACE("Call hookW %p (%p, %04x, %08lx, %08lx)\n", + lfs->ofnW->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); + ret = lfs->ofnW->lpfnHook(lfs->hwnd, wMsg, wParam, lParam); + TRACE("Ret hookW %p (%p, %04x, %08lx, %08lx)\n", + lfs->ofnW->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); + return ret; } /*********************************************************************** @@ -251,7 +268,7 @@ LONG FD31_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam, SetBkColor( lpdis->hDC, oldBk ); SetTextColor( lpdis->hDC, oldText ); } - DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hFolder); + DrawIconEx( lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hFolder, 16, 16, 0, 0, DI_NORMAL ); HeapFree(GetProcessHeap(), 0, str); return TRUE; } @@ -285,7 +302,7 @@ LONG FD31_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam, SetBkColor( lpdis->hDC, oldBk ); SetTextColor( lpdis->hDC, oldText ); } - DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hIcon); + DrawIconEx( lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hIcon, 16, 16, 0, 0, DI_NORMAL ); HeapFree(GetProcessHeap(), 0, str); return TRUE; } @@ -300,6 +317,7 @@ 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; @@ -329,7 +347,23 @@ static void FD31_UpdateResult(const FD31_DATA *lfs, const WCHAR *tmpstr) debugstr_w(ofnW->lpstrFile), ofnW->nFileOffset, ofnW->nFileExtension); /* update the real client structures if any */ - lfs->callbacks->UpdateResult(lfs); + 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; + } } /*********************************************************************** @@ -340,12 +374,19 @@ 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 ); - lfs->callbacks->UpdateFileTitle(lfs); + if (ofnA) + { + if (!WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFileTitle, -1, + ofnA->lpstrFileTitle, ofnA->nMaxFileTitle, NULL, NULL )) + ofnA->lpstrFileTitle[ofnA->nMaxFileTitle-1] = 0; + } } } @@ -396,7 +437,7 @@ static LRESULT FD31_FileListSelect( const FD31_DATA *lfs ) HWND hWnd = lfs->hwnd; LPWSTR pstr; - lRet = lfs->callbacks->SendLbGetCurSel(lfs); + lRet = SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETCURSEL, 0, 0); if (lRet == LB_ERR) return TRUE; @@ -737,7 +778,7 @@ void FD31_MapOfnStructA(const OPENFILENAMEA *ofnA, LPOPENFILENAMEW ofnW, BOOL op ofnW->lpstrDefExt = FD31_DupToW(ofnA->lpstrDefExt, 3); if ((ofnA->Flags & OFN_ENABLETEMPLATE) && (ofnA->lpTemplateName)) { - if (HIWORD(ofnA->lpTemplateName)) + if (!IS_INTRESOURCE(ofnA->lpTemplateName)) { RtlCreateUnicodeStringFromAsciiz (&usBuffer,ofnA->lpTemplateName); ofnW->lpTemplateName = usBuffer.Buffer; @@ -760,7 +801,7 @@ void FD31_FreeOfnW(OPENFILENAMEW *ofnW) HeapFree(GetProcessHeap(), 0, ofnW->lpstrFileTitle); HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrInitialDir); HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpstrTitle); - if (HIWORD(ofnW->lpTemplateName)) + if (!IS_INTRESOURCE(ofnW->lpTemplateName)) HeapFree(GetProcessHeap(), 0, (LPWSTR) ofnW->lpTemplateName); } @@ -774,7 +815,13 @@ void FD31_DestroyPrivate(PFD31_DATA lfs) if (!lfs) return; hwnd = lfs->hwnd; TRACE("destroying private allocation %p\n", lfs); - lfs->callbacks->Destroy(lfs); + + /* if ofnW has been allocated, have to free everything in it */ + if (lfs->ofnA) + { + FD31_FreeOfnW(lfs->ofnW); + HeapFree(GetProcessHeap(), 0, lfs->ofnW); + } HeapFree(GetProcessHeap(), 0, lfs); RemovePropA(hwnd, FD31_OFN_PROP); } @@ -787,8 +834,7 @@ void FD31_DestroyPrivate(PFD31_DATA lfs) * On entry : type = dialog procedure type (16,32A,32W) * dlgType = dialog type (open or save) */ -PFD31_DATA FD31_AllocPrivate(LPARAM lParam, UINT dlgType, - PFD31_CALLBACKS callbacks, DWORD data) +PFD31_DATA FD31_AllocPrivate(LPARAM lParam, UINT dlgType, BOOL IsUnicode) { PFD31_DATA lfs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FD31_DATA)); @@ -797,8 +843,26 @@ PFD31_DATA FD31_AllocPrivate(LPARAM lParam, UINT dlgType, lfs->hook = FALSE; lfs->lParam = lParam; lfs->open = (dlgType == OPEN_DIALOG); - lfs->callbacks = callbacks; - if (! lfs->callbacks->Init(lParam, lfs, data)) + + 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 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*lfs->ofnW)); + FD31_MapOfnStructA(lfs->ofnA, lfs->ofnW, lfs->open); + } + + if (! FD32_GetTemplate(lfs)) { FD31_DestroyPrivate(lfs); return NULL; diff --git a/reactos/dll/win32/comdlg32/filedlg31.h b/reactos/dll/win32/comdlg32/filedlg31.h index 7328f07d209..79faed75e50 100644 --- a/reactos/dll/win32/comdlg32/filedlg31.h +++ b/reactos/dll/win32/comdlg32/filedlg31.h @@ -21,21 +21,7 @@ #define FD31_OFN_PROP "FILEDLG_OFN" -/* Forward declare */ -typedef struct tagFD31_DATA FD31_DATA, *PFD31_DATA; - -typedef struct tagFD31_CALLBACKS -{ - BOOL (CALLBACK *Init)(LPARAM lParam, PFD31_DATA lfs, DWORD data); - BOOL (CALLBACK *CWP)(const FD31_DATA *lfs, UINT wMsg, WPARAM wParam, - LPARAM lParam); /* CWP instead of CallWindowProc to avoid macro expansion */ - void (CALLBACK *UpdateResult)(const FD31_DATA *lfs); - void (CALLBACK *UpdateFileTitle)(const FD31_DATA *lfs); - LRESULT (CALLBACK *SendLbGetCurSel)(const FD31_DATA *lfs); - void (CALLBACK *Destroy)(const FD31_DATA *lfs); -} FD31_CALLBACKS, *PFD31_CALLBACKS; - -struct tagFD31_DATA +typedef struct tagFD31_DATA { HWND hwnd; /* file dialog window handle */ BOOL hook; /* TRUE if the dialog is hooked */ @@ -46,13 +32,13 @@ struct tagFD31_DATA 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 */ - LPVOID private1632; /* 16/32 bit caller private data */ - PFD31_CALLBACKS callbacks; /* callbacks to handle 16/32 bit differences */ -}; + LPOPENFILENAMEA ofnA; /* original structure if 32bits ansi dialog */ +} FD31_DATA, *PFD31_DATA; + +extern BOOL FD32_GetTemplate(PFD31_DATA lfs); extern BOOL FD31_Init(void); -extern PFD31_DATA FD31_AllocPrivate(LPARAM lParam, UINT dlgType, - PFD31_CALLBACKS callbacks, DWORD data); +extern PFD31_DATA FD31_AllocPrivate(LPARAM lParam, UINT dlgType, BOOL IsUnicode); extern void FD31_DestroyPrivate(PFD31_DATA lfs); extern void FD31_MapOfnStructA(const OPENFILENAMEA *ofnA, LPOPENFILENAMEW ofnW, BOOL open); extern void FD31_FreeOfnW(OPENFILENAMEW *ofnW); diff --git a/reactos/dll/win32/comdlg32/finddlg32.c b/reactos/dll/win32/comdlg32/finddlg.c similarity index 86% rename from reactos/dll/win32/comdlg32/finddlg32.c rename to reactos/dll/win32/comdlg32/finddlg.c index 2a7d7e30810..f6c780e0496 100644 --- a/reactos/dll/win32/comdlg32/finddlg32.c +++ b/reactos/dll/win32/comdlg32/finddlg.c @@ -72,11 +72,11 @@ static DWORD COMDLG32_FR_GetFlags(HWND hDlgWnd) { DWORD flags = 0; if(IsDlgButtonChecked(hDlgWnd, rad2) == BST_CHECKED) - flags |= FR_DOWN; + flags |= FR_DOWN; if(IsDlgButtonChecked(hDlgWnd, chx1) == BST_CHECKED) - flags |= FR_WHOLEWORD; + flags |= FR_WHOLEWORD; if(IsDlgButtonChecked(hDlgWnd, chx2) == BST_CHECKED) - flags |= FR_MATCHCASE; + flags |= FR_MATCHCASE; return flags; } @@ -94,7 +94,7 @@ static void COMDLG32_FR_HandleWMCommand(HWND hDlgWnd, COMDLG32_FR_Data *pData, i if(NotifyCode == BN_CLICKED) { - switch(Id) + switch(Id) { case IDOK: /* Find Next */ if(GetDlgItemTextA(hDlgWnd, edt1, pData->fr.lpstrFindWhat, pData->fr.wFindWhatLen) > 0) @@ -108,7 +108,7 @@ static void COMDLG32_FR_HandleWMCommand(HWND hDlgWnd, COMDLG32_FR_Data *pData, i } else { - strcpy(pData->user_fr.fra->lpstrFindWhat, pData->fr.lpstrFindWhat); + strcpy(pData->user_fr.fra->lpstrFindWhat, pData->fr.lpstrFindWhat); } SendMessageA(pData->fr.hwndOwner, FindReplaceMessage, 0, (LPARAM)pData->user_fr.fra); } @@ -117,15 +117,15 @@ static void COMDLG32_FR_HandleWMCommand(HWND hDlgWnd, COMDLG32_FR_Data *pData, i case IDCANCEL: pData->user_fr.fra->Flags |= COMDLG32_FR_GetFlags(hDlgWnd) | FR_DIALOGTERM; SendMessageA(pData->fr.hwndOwner, FindReplaceMessage, 0, (LPARAM)pData->user_fr.fra); - DestroyWindow(hDlgWnd); + DestroyWindow(hDlgWnd); break; case psh2: /* Replace All */ - flag = FR_REPLACEALL; + flag = FR_REPLACEALL; goto Replace; case psh1: /* Replace */ - flag = FR_REPLACE; + flag = FR_REPLACE; Replace: if((pData->fr.Flags & FR_WINE_REPLACE) && GetDlgItemTextA(hDlgWnd, edt1, pData->fr.lpstrFindWhat, pData->fr.wFindWhatLen) > 0) @@ -144,8 +144,8 @@ Replace: } else { - strcpy(pData->user_fr.fra->lpstrFindWhat, pData->fr.lpstrFindWhat); - strcpy(pData->user_fr.fra->lpstrReplaceWith, pData->fr.lpstrReplaceWith); + strcpy(pData->user_fr.fra->lpstrFindWhat, pData->fr.lpstrFindWhat); + strcpy(pData->user_fr.fra->lpstrReplaceWith, pData->fr.lpstrReplaceWith); } SendMessageA(pData->fr.hwndOwner, FindReplaceMessage, 0, (LPARAM)pData->user_fr.fra); } @@ -181,34 +181,34 @@ static INT_PTR CALLBACK COMDLG32_FindReplaceDlgProc(HWND hDlgWnd, UINT iMsg, WPA if(iMsg == WM_INITDIALOG) { pdata = (COMDLG32_FR_Data *)lParam; - if(!SetPropA(hDlgWnd, (LPSTR)COMDLG32_Atom, (HANDLE)pdata)) + if(!SetPropA(hDlgWnd, (LPSTR)COMDLG32_Atom, (HANDLE)pdata)) { ERR("Could not Set prop; invent a gracefull exit?...\n"); - DestroyWindow(hDlgWnd); + DestroyWindow(hDlgWnd); return FALSE; } - SendDlgItemMessageA(hDlgWnd, edt1, EM_SETLIMITTEXT, (WPARAM)pdata->fr.wFindWhatLen, 0); + SendDlgItemMessageA(hDlgWnd, edt1, EM_SETLIMITTEXT, pdata->fr.wFindWhatLen, 0); SendDlgItemMessageA(hDlgWnd, edt1, WM_SETTEXT, 0, (LPARAM)pdata->fr.lpstrFindWhat); if(pdata->fr.Flags & FR_WINE_REPLACE) { - SendDlgItemMessageA(hDlgWnd, edt2, EM_SETLIMITTEXT, (WPARAM)pdata->fr.wReplaceWithLen, 0); + SendDlgItemMessageA(hDlgWnd, edt2, EM_SETLIMITTEXT, pdata->fr.wReplaceWithLen, 0); SendDlgItemMessageA(hDlgWnd, edt2, WM_SETTEXT, 0, (LPARAM)pdata->fr.lpstrReplaceWith); } - if(!(pdata->fr.Flags & FR_SHOWHELP)) + if(!(pdata->fr.Flags & FR_SHOWHELP)) ShowWindow(GetDlgItem(hDlgWnd, pshHelp), SW_HIDE); if(pdata->fr.Flags & FR_HIDEUPDOWN) - { + { ShowWindow(GetDlgItem(hDlgWnd, rad1), SW_HIDE); ShowWindow(GetDlgItem(hDlgWnd, rad2), SW_HIDE); ShowWindow(GetDlgItem(hDlgWnd, grp1), SW_HIDE); } - else if(pdata->fr.Flags & FR_NOUPDOWN) + else if(pdata->fr.Flags & FR_NOUPDOWN) { EnableWindow(GetDlgItem(hDlgWnd, rad1), FALSE); EnableWindow(GetDlgItem(hDlgWnd, rad2), FALSE); EnableWindow(GetDlgItem(hDlgWnd, grp1), FALSE); - } + } else { SendDlgItemMessageA(hDlgWnd, rad1, BM_SETCHECK, pdata->fr.Flags & FR_DOWN ? 0 : BST_CHECKED, 0); @@ -217,14 +217,14 @@ static INT_PTR CALLBACK COMDLG32_FindReplaceDlgProc(HWND hDlgWnd, UINT iMsg, WPA if(pdata->fr.Flags & FR_HIDEMATCHCASE) ShowWindow(GetDlgItem(hDlgWnd, chx2), SW_HIDE); - else if(pdata->fr.Flags & FR_NOMATCHCASE) + else if(pdata->fr.Flags & FR_NOMATCHCASE) EnableWindow(GetDlgItem(hDlgWnd, chx2), FALSE); else SendDlgItemMessageA(hDlgWnd, chx2, BM_SETCHECK, pdata->fr.Flags & FR_MATCHCASE ? BST_CHECKED : 0, 0); if(pdata->fr.Flags & FR_HIDEWHOLEWORD) ShowWindow(GetDlgItem(hDlgWnd, chx1), SW_HIDE); - else if(pdata->fr.Flags & FR_NOWHOLEWORD) + else if(pdata->fr.Flags & FR_NOWHOLEWORD) EnableWindow(GetDlgItem(hDlgWnd, chx1), FALSE); else SendDlgItemMessageA(hDlgWnd, chx1, BM_SETCHECK, pdata->fr.Flags & FR_WHOLEWORD ? BST_CHECKED : 0, 0); @@ -233,7 +233,7 @@ static INT_PTR CALLBACK COMDLG32_FindReplaceDlgProc(HWND hDlgWnd, UINT iMsg, WPA /* We do not do ShowWindow if hook exists and is FALSE */ /* per MSDN Article Q96135 */ - if((pdata->fr.Flags & FR_ENABLEHOOK) + if((pdata->fr.Flags & FR_ENABLEHOOK) && ! pdata->fr.lpfnHook(hDlgWnd, iMsg, wParam, (LPARAM) &pdata->fr)) return TRUE; ShowWindow(hDlgWnd, SW_SHOWNORMAL); @@ -248,28 +248,28 @@ static INT_PTR CALLBACK COMDLG32_FindReplaceDlgProc(HWND hDlgWnd, UINT iMsg, WPA else retval = FALSE; - if(pdata && !retval) + if(pdata && !retval) { - retval = TRUE; + retval = TRUE; switch(iMsg) - { + { case WM_COMMAND: COMDLG32_FR_HandleWMCommand(hDlgWnd, pdata, LOWORD(wParam), HIWORD(wParam)); - break; + break; case WM_CLOSE: COMDLG32_FR_HandleWMCommand(hDlgWnd, pdata, IDCANCEL, BN_CLICKED); - break; + break; case WM_HELP: - /* Heeeeelp! */ - FIXME("Got WM_HELP. Who is gonna supply it?\n"); + /* Heeeeelp! */ + FIXME("Got WM_HELP. Who is gonna supply it?\n"); break; - case WM_CONTEXTMENU: - /* Heeeeelp! */ - FIXME("Got WM_CONTEXTMENU. Who is gonna supply it?\n"); - break; + case WM_CONTEXTMENU: + /* Heeeeelp! */ + FIXME("Got WM_CONTEXTMENU. Who is gonna supply it?\n"); + break; /* FIXME: Handle F1 help */ default: @@ -283,8 +283,8 @@ static INT_PTR CALLBACK COMDLG32_FindReplaceDlgProc(HWND hDlgWnd, UINT iMsg, WPA */ if(iMsg == WM_DESTROY) { - RemovePropA(hDlgWnd, (LPSTR)COMDLG32_Atom); - HeapFree(GetProcessHeap(), 0, pdata); + RemovePropA(hDlgWnd, (LPSTR)COMDLG32_Atom); + HeapFree(GetProcessHeap(), 0, pdata); } return retval; @@ -304,55 +304,55 @@ static BOOL COMDLG32_FR_CheckPartial( ) { if(!pfr) { - COMDLG32_SetCommDlgExtendedError(CDERR_GENERALCODES); + COMDLG32_SetCommDlgExtendedError(CDERR_GENERALCODES); return FALSE; } if(pfr->lStructSize != sizeof(FINDREPLACEA)) { - COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); - return FALSE; + COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); + return FALSE; } if(!IsWindow(pfr->hwndOwner)) { - COMDLG32_SetCommDlgExtendedError(CDERR_DIALOGFAILURE); - return FALSE; + COMDLG32_SetCommDlgExtendedError(CDERR_DIALOGFAILURE); + return FALSE; } if((pfr->wFindWhatLen < 1 || !pfr->lpstrFindWhat) ||(Replace && (pfr->wReplaceWithLen < 1 || !pfr->lpstrReplaceWith))) { - COMDLG32_SetCommDlgExtendedError(FRERR_BUFFERLENGTHZERO); + COMDLG32_SetCommDlgExtendedError(FRERR_BUFFERLENGTHZERO); return FALSE; } if((FindReplaceMessage = RegisterWindowMessageA(FINDMSGSTRINGA)) == 0) { - COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL); + COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL); return FALSE; } if((HelpMessage = RegisterWindowMessageA(HELPMSGSTRINGA)) == 0) { - COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL); + COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL); return FALSE; } if((pfr->Flags & FR_ENABLEHOOK) && !pfr->lpfnHook) { - COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK); + COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK); return FALSE; } if((pfr->Flags & (FR_ENABLETEMPLATE | FR_ENABLETEMPLATEHANDLE)) && !pfr->hInstance) { - COMDLG32_SetCommDlgExtendedError(CDERR_NOHINSTANCE); + COMDLG32_SetCommDlgExtendedError(CDERR_NOHINSTANCE); return FALSE; } if((pfr->Flags & FR_ENABLETEMPLATE) && !pfr->lpTemplateName) { - COMDLG32_SetCommDlgExtendedError(CDERR_NOTEMPLATE); + COMDLG32_SetCommDlgExtendedError(CDERR_NOTEMPLATE); return FALSE; } @@ -380,7 +380,7 @@ static HWND COMDLG32_FR_DoFindReplace( { HMODULE hmod = COMDLG32_hInstance; HRSRC htemplate; - if(pdata->fr.Flags & FR_ENABLETEMPLATE) + if(pdata->fr.Flags & FR_ENABLETEMPLATE) { hmod = pdata->fr.hInstance; if(pdata->fr.Flags & FR_WINE_UNICODE) @@ -391,18 +391,18 @@ static HWND COMDLG32_FR_DoFindReplace( { htemplate = FindResourceA(hmod, pdata->fr.lpTemplateName, (LPCSTR)RT_DIALOG); } - } + } else - { + { int rcid = pdata->fr.Flags & FR_WINE_REPLACE ? REPLACEDLGORD : FINDDLGORD; htemplate = FindResourceA(hmod, MAKEINTRESOURCEA(rcid), (LPCSTR)RT_DIALOG); } if(!htemplate) - { - error = CDERR_FINDRESFAILURE; - goto cleanup; - } + { + error = CDERR_FINDRESFAILURE; + goto cleanup; + } loadrc = LoadResource(hmod, htemplate); } @@ -424,15 +424,15 @@ static HWND COMDLG32_FR_DoFindReplace( } hdlgwnd = CreateDialogIndirectParamA(COMDLG32_hInstance, - rcs, + rcs, pdata->fr.hwndOwner, COMDLG32_FindReplaceDlgProc, (LPARAM)pdata); if(!hdlgwnd) { - error = CDERR_DIALOGFAILURE; + error = CDERR_DIALOGFAILURE; cleanup: - COMDLG32_SetCommDlgExtendedError(error); + COMDLG32_SetCommDlgExtendedError(error); HeapFree(GetProcessHeap(), 0, pdata); } return hdlgwnd; @@ -451,10 +451,10 @@ HWND WINAPI FindTextA( TRACE("LPFINDREPLACE=%p\n", pfr); if(!COMDLG32_FR_CheckPartial(pfr, FALSE)) - return 0; + return 0; if((pdata = COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data))) == NULL) - return 0; /* Error has been set */ + return 0; /* Error has been set */ pdata->user_fr.fra = pfr; pdata->fr = *pfr; @@ -474,10 +474,10 @@ HWND WINAPI ReplaceTextA( TRACE("LPFINDREPLACE=%p\n", pfr); if(!COMDLG32_FR_CheckPartial(pfr, TRUE)) - return 0; + return 0; if((pdata = COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data))) == NULL) - return 0; /* Error has been set */ + return 0; /* Error has been set */ pdata->user_fr.fra = pfr; pdata->fr = *pfr; @@ -503,7 +503,7 @@ HWND WINAPI FindTextW( TRACE("LPFINDREPLACE=%p\n", pfr); if(!COMDLG32_FR_CheckPartial((LPFINDREPLACEA)pfr, FALSE)) - return 0; + return 0; len = WideCharToMultiByte( CP_ACP, 0, pfr->lpstrFindWhat, pfr->wFindWhatLen, NULL, 0, NULL, NULL ); @@ -537,7 +537,7 @@ HWND WINAPI ReplaceTextW( TRACE("LPFINDREPLACE=%p\n", pfr); if(!COMDLG32_FR_CheckPartial((LPFINDREPLACEA)pfr, FALSE)) - return 0; + return 0; len1 = WideCharToMultiByte( CP_ACP, 0, pfr->lpstrFindWhat, pfr->wFindWhatLen, NULL, 0, NULL, NULL ); diff --git a/reactos/dll/win32/comdlg32/finddlg16.c b/reactos/dll/win32/comdlg32/finddlg16.c deleted file mode 100644 index f30bae80172..00000000000 --- a/reactos/dll/win32/comdlg32/finddlg16.c +++ /dev/null @@ -1,496 +0,0 @@ -/* - * COMMDLG - 16 bits Find & Replace Text 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 "windef.h" -#include "winbase.h" -#include "wine/winbase16.h" -#include "wine/winuser16.h" -#include "wingdi.h" -#include "winuser.h" -#include "commdlg.h" -#include "wine/debug.h" -#include "cderr.h" - -WINE_DEFAULT_DEBUG_CHANNEL(commdlg); - -#include "cdlg.h" -#include "cdlg16.h" - -struct FRPRIVATE -{ - HANDLE16 hDlgTmpl16; /* handle for resource 16 */ - HANDLE16 hResource16; /* handle for allocated resource 16 */ - HANDLE16 hGlobal16; /* 16 bits mem block (resources) */ - LPCVOID template; /* template for 32 bits resource */ - BOOL find; /* TRUE if find dialog, FALSE if replace dialog */ - FINDREPLACE16 *fr16; -}; - -#define LFRPRIVATE struct FRPRIVATE * - -BOOL16 CALLBACK FindTextDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam, - LPARAM lParam); -BOOL16 CALLBACK ReplaceTextDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam, - LPARAM lParam); - -/*********************************************************************** - * FINDDLG_Get16BitsTemplate [internal] - * - * Get a template (FALSE if failure) when 16 bits dialogs are used - * by a 16 bits application - * FIXME : no test was done for the user-provided template cases - */ -static BOOL FINDDLG_Get16BitsTemplate(LFRPRIVATE lfr) -{ - LPFINDREPLACE16 fr16 = lfr->fr16; - - if (fr16->Flags & FR_ENABLETEMPLATEHANDLE) - { - lfr->template = GlobalLock16(fr16->hInstance); - if (!lfr->template) - { - COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE); - return FALSE; - } - } - else if (fr16->Flags & FR_ENABLETEMPLATE) - { - HANDLE16 hResInfo; - if (!(hResInfo = FindResource16(fr16->hInstance, - MapSL(fr16->lpTemplateName), - (LPSTR)RT_DIALOG))) - { - COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); - return FALSE; - } - if (!(lfr->hDlgTmpl16 = LoadResource16( fr16->hInstance, hResInfo ))) - { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return FALSE; - } - lfr->hResource16 = lfr->hDlgTmpl16; - lfr->template = LockResource16(lfr->hResource16); - if (!lfr->template) - { - FreeResource16(lfr->hResource16); - COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE); - return FALSE; - } - } - else - { /* get resource from (32 bits) own Wine resource; convert it to 16 */ - HRSRC hResInfo; - HGLOBAL hDlgTmpl32; - LPCVOID template32; - DWORD size; - HGLOBAL16 hGlobal16; - - if (!(hResInfo = FindResourceA(COMDLG32_hInstance, - lfr->find ? - MAKEINTRESOURCEA(FINDDLGORD):MAKEINTRESOURCEA(REPLACEDLGORD), - (LPSTR)RT_DIALOG))) - { - COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); - return FALSE; - } - if (!(hDlgTmpl32 = LoadResource(COMDLG32_hInstance, hResInfo )) || - !(template32 = LockResource( hDlgTmpl32 ))) - { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return FALSE; - } - size = SizeofResource(COMDLG32_hInstance, hResInfo); - hGlobal16 = GlobalAlloc16(0, size); - if (!hGlobal16) - { - COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE); - ERR("alloc failure for %d bytes\n", size); - return FALSE; - } - lfr->template = GlobalLock16(hGlobal16); - if (!lfr->template) - { - COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE); - ERR("global lock failure for %x handle\n", hGlobal16); - GlobalFree16(hGlobal16); - return FALSE; - } - ConvertDialog32To16(template32, size, (LPVOID)lfr->template); - lfr->hDlgTmpl16 = hGlobal16; - lfr->hGlobal16 = hGlobal16; - } - return TRUE; -} - - -/*********************************************************************** - * FINDDLG_FreeResources [internal] - * - * Free resources allocated - */ -static void FINDDLG_FreeResources(LFRPRIVATE lfr) -{ - /* free resources */ - if (lfr->fr16->Flags & FR_ENABLETEMPLATEHANDLE) - GlobalUnlock16(lfr->fr16->hInstance); - if (lfr->hResource16) - { - GlobalUnlock16(lfr->hResource16); - FreeResource16(lfr->hResource16); - } - if (lfr->hGlobal16) - { - GlobalUnlock16(lfr->hGlobal16); - GlobalFree16(lfr->hGlobal16); - } -} - -/*********************************************************************** - * FindText (COMMDLG.11) - */ -HWND16 WINAPI FindText16( SEGPTR find ) -{ - HANDLE16 hInst; - HWND16 ret = 0; - FARPROC16 ptr; - LFRPRIVATE lfr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct FRPRIVATE)); - - if (!lfr) return 0; - lfr->fr16 = MapSL(find); - lfr->find = TRUE; - if (FINDDLG_Get16BitsTemplate(lfr)) - { - hInst = GetWindowLongPtrA( HWND_32(lfr->fr16->hwndOwner), GWLP_HINSTANCE); - ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR) 13); - ret = CreateDialogIndirectParam16( hInst, lfr->template, - lfr->fr16->hwndOwner, (DLGPROC16) ptr, find); - FINDDLG_FreeResources(lfr); - } - HeapFree(GetProcessHeap(), 0, lfr); - return ret; -} - - -/*********************************************************************** - * ReplaceText (COMMDLG.12) - */ -HWND16 WINAPI ReplaceText16( SEGPTR find ) -{ - HANDLE16 hInst; - HWND16 ret = 0; - FARPROC16 ptr; - LFRPRIVATE lfr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct FRPRIVATE)); - - if (!lfr) return 0; - /* - * FIXME : We should do error checking on the lpFind structure here - * and make CommDlgExtendedError() return the error condition. - */ - lfr->fr16 = MapSL(find); - lfr->find = FALSE; - if (FINDDLG_Get16BitsTemplate(lfr)) - { - hInst = GetWindowLongPtrA( HWND_32(lfr->fr16->hwndOwner), GWLP_HINSTANCE); - ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR) 14); - ret = CreateDialogIndirectParam16( hInst, lfr->template, - lfr->fr16->hwndOwner, (DLGPROC16) ptr, find); - - FINDDLG_FreeResources(lfr); - } - HeapFree(GetProcessHeap(), 0, lfr); - return ret; -} - - -/*********************************************************************** - * FINDDLG_WMInitDialog [internal] - */ -static LRESULT FINDDLG_WMInitDialog(HWND hWnd, LPARAM lParam, LPDWORD lpFlags, - LPCSTR lpstrFindWhat, BOOL fUnicode) -{ - SetWindowLongPtrW(hWnd, DWLP_USER, lParam); - *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM); - /* - * FIXME : If the initial FindWhat string is empty, we should disable the - * FindNext (IDOK) button. Only after typing some text, the button should be - * enabled. - */ - if (fUnicode) SetDlgItemTextW(hWnd, edt1, (LPCWSTR)lpstrFindWhat); - else SetDlgItemTextA(hWnd, edt1, lpstrFindWhat); - CheckRadioButton(hWnd, rad1, rad2, (*lpFlags & FR_DOWN) ? rad2 : rad1); - if (*lpFlags & (FR_HIDEUPDOWN | FR_NOUPDOWN)) { - EnableWindow(GetDlgItem(hWnd, rad1), FALSE); - EnableWindow(GetDlgItem(hWnd, rad2), FALSE); - } - if (*lpFlags & FR_HIDEUPDOWN) { - ShowWindow(GetDlgItem(hWnd, rad1), SW_HIDE); - ShowWindow(GetDlgItem(hWnd, rad2), SW_HIDE); - ShowWindow(GetDlgItem(hWnd, grp1), SW_HIDE); - } - CheckDlgButton(hWnd, chx1, (*lpFlags & FR_WHOLEWORD) ? 1 : 0); - if (*lpFlags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD)) - EnableWindow(GetDlgItem(hWnd, chx1), FALSE); - if (*lpFlags & FR_HIDEWHOLEWORD) - ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE); - CheckDlgButton(hWnd, chx2, (*lpFlags & FR_MATCHCASE) ? 1 : 0); - if (*lpFlags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE)) - EnableWindow(GetDlgItem(hWnd, chx2), FALSE); - if (*lpFlags & FR_HIDEMATCHCASE) - ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE); - if (!(*lpFlags & FR_SHOWHELP)) { - EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE); - ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE); - } - ShowWindow(hWnd, SW_SHOWNORMAL); - return TRUE; -} - - -/*********************************************************************** - * FINDDLG_WMCommand [internal] - */ -static LRESULT FINDDLG_WMCommand(HWND hWnd, WPARAM wParam, - HWND hwndOwner, LPDWORD lpFlags, - LPSTR lpstrFindWhat, WORD wFindWhatLen, - BOOL fUnicode) -{ - int uFindReplaceMessage = RegisterWindowMessageA( FINDMSGSTRINGA ); - int uHelpMessage = RegisterWindowMessageA( HELPMSGSTRINGA ); - - switch (wParam) { - case IDOK: - if (fUnicode) - GetDlgItemTextW(hWnd, edt1, (LPWSTR)lpstrFindWhat, wFindWhatLen/2); - else GetDlgItemTextA(hWnd, edt1, lpstrFindWhat, wFindWhatLen); - if (IsDlgButtonChecked(hWnd, rad2)) - *lpFlags |= FR_DOWN; - else *lpFlags &= ~FR_DOWN; - if (IsDlgButtonChecked(hWnd, chx1)) - *lpFlags |= FR_WHOLEWORD; - else *lpFlags &= ~FR_WHOLEWORD; - if (IsDlgButtonChecked(hWnd, chx2)) - *lpFlags |= FR_MATCHCASE; - else *lpFlags &= ~FR_MATCHCASE; - *lpFlags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM); - *lpFlags |= FR_FINDNEXT; - SendMessageW( hwndOwner, uFindReplaceMessage, 0, - GetWindowLongPtrW(hWnd, DWLP_USER) ); - return TRUE; - case IDCANCEL: - *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL); - *lpFlags |= FR_DIALOGTERM; - SendMessageW( hwndOwner, uFindReplaceMessage, 0, - GetWindowLongPtrW(hWnd, DWLP_USER) ); - DestroyWindow(hWnd); - return TRUE; - case pshHelp: - /* FIXME : should lpfr structure be passed as an argument ??? */ - SendMessageA(hwndOwner, uHelpMessage, 0, 0); - return TRUE; - } - return FALSE; -} - - -/*********************************************************************** - * FindTextDlgProc (COMMDLG.13) - */ -BOOL16 CALLBACK FindTextDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam, - LPARAM lParam) -{ - HWND hWnd = HWND_32(hWnd16); - LPFINDREPLACE16 lpfr; - switch (wMsg) { - case WM_INITDIALOG: - lpfr=MapSL(lParam); - return FINDDLG_WMInitDialog(hWnd, lParam, &(lpfr->Flags), - MapSL(lpfr->lpstrFindWhat), FALSE); - case WM_COMMAND: - lpfr=MapSL(GetWindowLongPtrW(hWnd, DWLP_USER)); - return FINDDLG_WMCommand(hWnd, wParam, HWND_32(lpfr->hwndOwner), - &lpfr->Flags, MapSL(lpfr->lpstrFindWhat), - lpfr->wFindWhatLen, FALSE); - } - return FALSE; -} - - -/*********************************************************************** - * REPLACEDLG_WMInitDialog [internal] - */ -static LRESULT REPLACEDLG_WMInitDialog(HWND hWnd, LPARAM lParam, - LPDWORD lpFlags, LPCSTR lpstrFindWhat, - LPCSTR lpstrReplaceWith, BOOL fUnicode) -{ - SetWindowLongPtrW(hWnd, DWLP_USER, lParam); - *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM); - /* - * FIXME : If the initial FindWhat string is empty, we should disable the FinNext / - * Replace / ReplaceAll buttons. Only after typing some text, the buttons should be - * enabled. - */ - if (fUnicode) - { - SetDlgItemTextW(hWnd, edt1, (LPCWSTR)lpstrFindWhat); - SetDlgItemTextW(hWnd, edt2, (LPCWSTR)lpstrReplaceWith); - } else - { - SetDlgItemTextA(hWnd, edt1, lpstrFindWhat); - SetDlgItemTextA(hWnd, edt2, lpstrReplaceWith); - } - CheckDlgButton(hWnd, chx1, (*lpFlags & FR_WHOLEWORD) ? 1 : 0); - if (*lpFlags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD)) - EnableWindow(GetDlgItem(hWnd, chx1), FALSE); - if (*lpFlags & FR_HIDEWHOLEWORD) - ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE); - CheckDlgButton(hWnd, chx2, (*lpFlags & FR_MATCHCASE) ? 1 : 0); - if (*lpFlags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE)) - EnableWindow(GetDlgItem(hWnd, chx2), FALSE); - if (*lpFlags & FR_HIDEMATCHCASE) - ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE); - if (!(*lpFlags & FR_SHOWHELP)) { - EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE); - ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE); - } - ShowWindow(hWnd, SW_SHOWNORMAL); - return TRUE; -} - - -/*********************************************************************** - * REPLACEDLG_WMCommand [internal] - */ -static LRESULT REPLACEDLG_WMCommand(HWND hWnd, WPARAM16 wParam, - HWND hwndOwner, LPDWORD lpFlags, - LPSTR lpstrFindWhat, WORD wFindWhatLen, - LPSTR lpstrReplaceWith, WORD wReplaceWithLen, - BOOL fUnicode) -{ - int uFindReplaceMessage = RegisterWindowMessageA( FINDMSGSTRINGA ); - int uHelpMessage = RegisterWindowMessageA( HELPMSGSTRINGA ); - - switch (wParam) { - case IDOK: - if (fUnicode) - { - GetDlgItemTextW(hWnd, edt1, (LPWSTR)lpstrFindWhat, wFindWhatLen/2); - GetDlgItemTextW(hWnd, edt2, (LPWSTR)lpstrReplaceWith, wReplaceWithLen/2); - } else - { - GetDlgItemTextA(hWnd, edt1, lpstrFindWhat, wFindWhatLen); - GetDlgItemTextA(hWnd, edt2, lpstrReplaceWith, wReplaceWithLen); - } - if (IsDlgButtonChecked(hWnd, chx1)) - *lpFlags |= FR_WHOLEWORD; - else *lpFlags &= ~FR_WHOLEWORD; - if (IsDlgButtonChecked(hWnd, chx2)) - *lpFlags |= FR_MATCHCASE; - else *lpFlags &= ~FR_MATCHCASE; - *lpFlags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM); - *lpFlags |= FR_FINDNEXT; - SendMessageW( hwndOwner, uFindReplaceMessage, 0, - GetWindowLongPtrW(hWnd, DWLP_USER) ); - return TRUE; - case IDCANCEL: - *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL); - *lpFlags |= FR_DIALOGTERM; - SendMessageW( hwndOwner, uFindReplaceMessage, 0, - GetWindowLongPtrW(hWnd, DWLP_USER) ); - DestroyWindow(hWnd); - return TRUE; - case psh1: - if (fUnicode) - { - GetDlgItemTextW(hWnd, edt1, (LPWSTR)lpstrFindWhat, wFindWhatLen/2); - GetDlgItemTextW(hWnd, edt2, (LPWSTR)lpstrReplaceWith, wReplaceWithLen/2); - } else - { - GetDlgItemTextA(hWnd, edt1, lpstrFindWhat, wFindWhatLen); - GetDlgItemTextA(hWnd, edt2, lpstrReplaceWith, wReplaceWithLen); - } - if (IsDlgButtonChecked(hWnd, chx1)) - *lpFlags |= FR_WHOLEWORD; - else *lpFlags &= ~FR_WHOLEWORD; - if (IsDlgButtonChecked(hWnd, chx2)) - *lpFlags |= FR_MATCHCASE; - else *lpFlags &= ~FR_MATCHCASE; - *lpFlags &= ~(FR_FINDNEXT | FR_REPLACEALL | FR_DIALOGTERM); - *lpFlags |= FR_REPLACE; - SendMessageW( hwndOwner, uFindReplaceMessage, 0, - GetWindowLongPtrW(hWnd, DWLP_USER) ); - return TRUE; - case psh2: - if (fUnicode) - { - GetDlgItemTextW(hWnd, edt1, (LPWSTR)lpstrFindWhat, wFindWhatLen/2); - GetDlgItemTextW(hWnd, edt2, (LPWSTR)lpstrReplaceWith, wReplaceWithLen/2); - } else - { - GetDlgItemTextA(hWnd, edt1, lpstrFindWhat, wFindWhatLen); - GetDlgItemTextA(hWnd, edt2, lpstrReplaceWith, wReplaceWithLen); - } - if (IsDlgButtonChecked(hWnd, chx1)) - *lpFlags |= FR_WHOLEWORD; - else *lpFlags &= ~FR_WHOLEWORD; - if (IsDlgButtonChecked(hWnd, chx2)) - *lpFlags |= FR_MATCHCASE; - else *lpFlags &= ~FR_MATCHCASE; - *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_DIALOGTERM); - *lpFlags |= FR_REPLACEALL; - SendMessageW( hwndOwner, uFindReplaceMessage, 0, - GetWindowLongPtrW(hWnd, DWLP_USER) ); - return TRUE; - case pshHelp: - /* FIXME : should lpfr structure be passed as an argument ??? */ - SendMessageA(hwndOwner, uHelpMessage, 0, 0); - return TRUE; - } - return FALSE; -} - - -/*********************************************************************** - * ReplaceTextDlgProc (COMMDLG.14) - */ -BOOL16 CALLBACK ReplaceTextDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam, - LPARAM lParam) -{ - HWND hWnd = HWND_32(hWnd16); - LPFINDREPLACE16 lpfr; - switch (wMsg) { - case WM_INITDIALOG: - lpfr=MapSL(lParam); - return REPLACEDLG_WMInitDialog(hWnd, lParam, &lpfr->Flags, - MapSL(lpfr->lpstrFindWhat), - MapSL(lpfr->lpstrReplaceWith), FALSE); - case WM_COMMAND: - lpfr=MapSL(GetWindowLongPtrW(hWnd, DWLP_USER)); - return REPLACEDLG_WMCommand(hWnd, wParam, HWND_32(lpfr->hwndOwner), - &lpfr->Flags, MapSL(lpfr->lpstrFindWhat), - lpfr->wFindWhatLen, MapSL(lpfr->lpstrReplaceWith), - lpfr->wReplaceWithLen, FALSE); - } - return FALSE; -} diff --git a/reactos/dll/win32/comdlg32/fontdlg.c b/reactos/dll/win32/comdlg32/fontdlg.c index f61de366683..1ad881c72d2 100644 --- a/reactos/dll/win32/comdlg32/fontdlg.c +++ b/reactos/dll/win32/comdlg32/fontdlg.c @@ -33,16 +33,24 @@ #include "dlgs.h" #include "wine/debug.h" #include "cderr.h" +#include "cdlg.h" WINE_DEFAULT_DEBUG_CHANNEL(commdlg); +typedef struct +{ + HWND hWnd1; + HWND hWnd2; + LPCHOOSEFONTW lpcf32w; + int added; +} CFn_ENUMSTRUCT, *LPCFn_ENUMSTRUCT; + + static const WCHAR strWineFontData[] = {'_','_','W','I','N','E','_','F','O','N','T','D','L','G','D','A','T','A',0}; static const WCHAR strWineFontData_a[] = {'_','_','W','I','N','E','_','F','O','N','T','D','L','G','D','A','T','A','_','A',0}; static const WCHAR chooseFontW[] = {'C','H','O','O','S','E','_','F','O','N','T',0}; -#include "cdlg.h" - /* image list with TrueType bitmaps and more */ static HIMAGELIST himlTT = 0; #define TTBITMAP_XSIZE 20 /* x-size of the bitmaps */ @@ -148,7 +156,7 @@ static const struct { #undef XX }; -void _dump_cf_flags(DWORD cflags) +static void _dump_cf_flags(DWORD cflags) { unsigned int i; @@ -299,8 +307,8 @@ static BOOL CFn_HookCallChk32(const CHOOSEFONTW *lpcf) /************************************************************************* * AddFontFamily [internal] */ -INT AddFontFamily(const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM, - UINT nFontType, const CHOOSEFONTW *lpcf, HWND hwnd, LPCFn_ENUMSTRUCT e) +static INT AddFontFamily(const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM, + UINT nFontType, const CHOOSEFONTW *lpcf, HWND hwnd, LPCFn_ENUMSTRUCT e) { int i; WORD w; @@ -447,6 +455,21 @@ static inline HDC CFn_GetDC(const CHOOSEFONTW *lpcf) return ret; } +/************************************************************************* + * GetScreenDPI [internal] + */ +static inline int GetScreenDPI(void) +{ + HDC hdc; + int result; + + hdc = GetDC(0); + result = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(0, hdc); + + return result; +} + /************************************************************************* * CFn_ReleaseDC [internal] */ @@ -459,9 +482,8 @@ static inline void CFn_ReleaseDC(const CHOOSEFONTW *lpcf, HDC hdc) /*********************************************************************** * AddFontStyle [internal] */ -INT AddFontStyle( const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM, - UINT nFontType, const CHOOSEFONTW *lpcf, HWND hcmb2, HWND hcmb3, - HWND hDlg, BOOL iswin16) +static INT AddFontStyle( const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM, + UINT nFontType, const CHOOSEFONTW *lpcf, HWND hcmb2, HWND hcmb3, HWND hDlg) { int i; const LOGFONTW *lplf = &(lpElfex->elfLogFont); @@ -479,10 +501,8 @@ INT AddFontStyle( const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM, if (nFontType & RASTER_FONTTYPE) { INT points; - if(!(hdc = CFn_GetDC(lpcf))) return 0; points = MulDiv( lpNTM->ntmTm.tmHeight - lpNTM->ntmTm.tmInternalLeading, - 72, GetDeviceCaps(hdc, LOGPIXELSY)); - CFn_ReleaseDC(lpcf, hdc); + 72, GetScreenDPI()); i = AddFontSizeToCombo3(hcmb3, points, lpcf); if(i) return 0; } else if (SetFontSizesToCombo3(hcmb3, lpcf)) return 0; @@ -495,7 +515,7 @@ INT AddFontStyle( const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM, if (i) return 0; } - if( iswin16 || !( hcmb5 = GetDlgItem(hDlg, cmb5))) return 1; + if (!( hcmb5 = GetDlgItem(hDlg, cmb5))) return 1; i = SendMessageW( hcmb5, CB_FINDSTRINGEXACT, 0, (LPARAM)lpElfex->elfScript); if( i == CB_ERR) { @@ -584,14 +604,13 @@ static INT WINAPI FontStyleEnumProc( const ENUMLOGFONTEXW *lpElfex, HWND hcmb3=s->hWnd2; HWND hDlg=GetParent(hcmb3); return AddFontStyle( lpElfex, (const NEWTEXTMETRICEXW *) metrics, - dwFontType, s->lpcf32w, hcmb2, hcmb3, hDlg, FALSE); + dwFontType, s->lpcf32w, hcmb2, hcmb3, hDlg); } /*********************************************************************** * CFn_WMInitDialog [internal] */ -LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam, - LPCHOOSEFONTW lpcf) +static LRESULT CFn_WMInitDialog(HWND hDlg, LPARAM lParam, LPCHOOSEFONTW lpcf) { HDC hdc; int i,j,init=0; @@ -699,7 +718,7 @@ LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam, lpxx->lfHeight; INT points; int charset = lpxx->lfCharSet; - points = MulDiv( height, 72, GetDeviceCaps(hdc, LOGPIXELSY)); + points = MulDiv( height, 72, GetScreenDPI()); pstyle = MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD: FW_NORMAL,lpxx->lfItalic !=0); SendDlgItemMessageW(hDlg, cmb1, CB_SETCURSEL, j, 0); @@ -747,7 +766,7 @@ LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam, /*********************************************************************** * CFn_WMMeasureItem [internal] */ -LRESULT CFn_WMMeasureItem(HWND hDlg, WPARAM wParam, LPARAM lParam) +static LRESULT CFn_WMMeasureItem(HWND hDlg, WPARAM wParam, LPARAM lParam) { HDC hdc; HFONT hfontprev; @@ -775,7 +794,7 @@ LRESULT CFn_WMMeasureItem(HWND hDlg, WPARAM wParam, LPARAM lParam) /*********************************************************************** * CFn_WMDrawItem [internal] */ -LRESULT CFn_WMDrawItem(HWND hDlg, WPARAM wParam, LPARAM lParam) +static LRESULT CFn_WMDrawItem(HWND hDlg, WPARAM wParam, LPARAM lParam) { HBRUSH hBrush; WCHAR buffer[40]; @@ -879,8 +898,7 @@ LRESULT CFn_WMDrawItem(HWND hDlg, WPARAM wParam, LPARAM lParam) /*********************************************************************** * CFn_WMCommand [internal] */ -LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, - LPCHOOSEFONTW lpcf) +static LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcf) { int i; long l; @@ -977,14 +995,8 @@ LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, CB_GETITEMDATA , i, 0)); else lpcf->iPointSize = 100; - hdc = CFn_GetDC(lpcf); - if( hdc) - { - lpxx->lfHeight = - MulDiv( lpcf->iPointSize , - GetDeviceCaps(hdc, LOGPIXELSY), 720); - CFn_ReleaseDC(lpcf, hdc); - } else - lpxx->lfHeight = -lpcf->iPointSize / 10; + lpxx->lfHeight = - MulDiv( lpcf->iPointSize , + GetScreenDPI(), 720); i=SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0); if (i!=CB_ERR) lpxx->lfCharSet=SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0); @@ -1028,8 +1040,6 @@ LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, i=RegisterWindowMessageW( HELPMSGSTRINGW ); if (lpcf->hwndOwner) SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData)); - /* if (CFn_HookCallChk(lpcf)) - CallWindowProc16(lpcf->lpfnHook,hDlg,WM_COMMAND,psh15,(LPARAM)lpcf);*/ break; case IDOK: @@ -1054,7 +1064,7 @@ LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, return(FALSE); } -static LRESULT CFn_WMDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcfw) +static LRESULT CFn_WMDestroy(HWND hwnd, LPCHOOSEFONTW lpcfw) { LPCHOOSEFONTA lpcfa; LPSTR lpszStyle; @@ -1084,7 +1094,7 @@ static LRESULT CFn_WMDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam, LPCHOOSEFO return TRUE; } -LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW *lpcf) +static LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW *lpcf) { WINDOWINFO info; @@ -1137,8 +1147,7 @@ LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW * /*********************************************************************** * FormatCharDlgProcA [internal] */ -INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, - LPARAM lParam) +static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { LPCHOOSEFONTW lpcfw; LPCHOOSEFONTA lpcfa; @@ -1170,7 +1179,7 @@ INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len); } - if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcfw)) + if (!CFn_WMInitDialog(hDlg, lParam, lpcfw)) { TRACE("CFn_WMInitDialog returned FALSE\n"); return FALSE; @@ -1187,7 +1196,7 @@ INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, case WM_COMMAND: return CFn_WMCommand(hDlg, wParam, lParam, lpcfw); case WM_DESTROY: - return CFn_WMDestroy(hDlg, wParam, lParam, lpcfw); + return CFn_WMDestroy(hDlg, lpcfw); case WM_CHOOSEFONT_GETLOGFONT: TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam); FIXME("current logfont back to caller\n"); @@ -1201,8 +1210,7 @@ INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, /*********************************************************************** * FormatCharDlgProcW [internal] */ -INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, - LPARAM lParam) +static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { LPCHOOSEFONTW lpcf; INT_PTR res = FALSE; @@ -1220,7 +1228,7 @@ INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, else { lpcf=(LPCHOOSEFONTW)lParam; - if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcf)) + if (!CFn_WMInitDialog(hDlg, lParam, lpcf)) { TRACE("CFn_WMInitDialog returned FALSE\n"); return FALSE; diff --git a/reactos/dll/win32/comdlg32/fontdlg16.c b/reactos/dll/win32/comdlg32/fontdlg16.c deleted file mode 100644 index c7be1d393da..00000000000 --- a/reactos/dll/win32/comdlg32/fontdlg16.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * COMMDLG - Font Dialog - * - * 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 "wingdi.h" -#include "winuser.h" -#include "winnls.h" -#include "wine/winbase16.h" -#include "wine/winuser16.h" -#include "commdlg.h" -#include "wine/debug.h" -#include "cderr.h" - -WINE_DEFAULT_DEBUG_CHANNEL(commdlg); - -#include "cdlg.h" -#include "cdlg16.h" - -static const WCHAR strWineFontData16[] = - {'_','_','W','I','N','E','_','F','O','N','T','D','L','G','D','A','T','A','1','6',0}; - -static void FONT_LogFont16To32W( const LOGFONT16 *font16, LPLOGFONTW font32 ) -{ - font32->lfHeight = font16->lfHeight; - font32->lfWidth = font16->lfWidth; - font32->lfEscapement = font16->lfEscapement; - font32->lfOrientation = font16->lfOrientation; - font32->lfWeight = font16->lfWeight; - font32->lfItalic = font16->lfItalic; - font32->lfUnderline = font16->lfUnderline; - font32->lfStrikeOut = font16->lfStrikeOut; - font32->lfCharSet = font16->lfCharSet; - font32->lfOutPrecision = font16->lfOutPrecision; - font32->lfClipPrecision = font16->lfClipPrecision; - font32->lfQuality = font16->lfQuality; - font32->lfPitchAndFamily = font16->lfPitchAndFamily; - MultiByteToWideChar(CP_ACP, 0, font16->lfFaceName, - LF_FACESIZE, font32->lfFaceName, LF_FACESIZE); -} - -static void FONT_Metrics16To32W( const TEXTMETRIC16 *pm16, - NEWTEXTMETRICEXW *pnm32w) -{ - ZeroMemory( pnm32w, sizeof(NEWTEXTMETRICEXW)); - /* NOTE: only the fields used by AddFontStyle() are filled in */ - pnm32w->ntmTm.tmHeight = pm16->tmHeight; - pnm32w->ntmTm.tmExternalLeading = pm16->tmExternalLeading; -} - -static void CFn_CHOOSEFONT16to32W(const CHOOSEFONT16 *chf16, LPCHOOSEFONTW chf32w) -{ - int len; - if (chf16->Flags & CF_ENABLETEMPLATE) - { - LPWSTR name32w; - - len = MultiByteToWideChar( CP_ACP, 0, MapSL(chf16->lpTemplateName), -1, NULL, 0); - name32w = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - MultiByteToWideChar( CP_ACP, 0, MapSL(chf16->lpTemplateName), -1, name32w, len); - chf32w->lpTemplateName = name32w; - } - if (chf16->Flags & CF_USESTYLE) - { - len = MultiByteToWideChar( CP_ACP, 0, MapSL(chf16->lpszStyle), -1, NULL, 0); - chf32w->lpszStyle = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - MultiByteToWideChar( CP_ACP, 0, MapSL(chf16->lpszStyle), -1, chf32w->lpszStyle, len); - } - chf32w->lStructSize=sizeof(CHOOSEFONTW); - chf32w->hwndOwner=HWND_32(chf16->hwndOwner); - chf32w->hDC=HDC_32(chf16->hDC); - chf32w->iPointSize=chf16->iPointSize; - chf32w->Flags=chf16->Flags; - chf32w->rgbColors=chf16->rgbColors; - chf32w->lCustData=chf16->lCustData; - chf32w->lpfnHook=NULL; - chf32w->hInstance=HINSTANCE_32(chf16->hInstance); - chf32w->nFontType=chf16->nFontType; - chf32w->nSizeMax=chf16->nSizeMax; - chf32w->nSizeMin=chf16->nSizeMin; - FONT_LogFont16To32W(MapSL(chf16->lpLogFont), chf32w->lpLogFont); -} - -/*********************************************************************** - * CFn_HookCallChk [internal] - */ -static BOOL CFn_HookCallChk(const CHOOSEFONT16 *lpcf) -{ - if (lpcf) - if(lpcf->Flags & CF_ENABLEHOOK) - if (lpcf->lpfnHook) - return TRUE; - return FALSE; -} - -/*********************************************************************** - * FontFamilyEnumProc (COMMDLG.19) - */ -INT16 WINAPI FontFamilyEnumProc16( SEGPTR logfont, SEGPTR metrics, - UINT16 nFontType, LPARAM lParam ) -{ - HWND hwnd=HWND_32(LOWORD(lParam)); - HWND hDlg=GetParent(hwnd); - LPCHOOSEFONT16 lpcf; - LOGFONT16 *lplf = MapSL( logfont ); - TEXTMETRIC16 *lpmtrx16 = MapSL(metrics); - ENUMLOGFONTEXW elf32w; - NEWTEXTMETRICEXW nmtrx32w; - - lpcf = (LPCHOOSEFONT16)GetPropW(hDlg, strWineFontData16); - FONT_LogFont16To32W(lplf, &(elf32w.elfLogFont)); - FONT_Metrics16To32W(lpmtrx16, &nmtrx32w); - return AddFontFamily(&elf32w, &nmtrx32w, nFontType, - (LPCHOOSEFONTW)lpcf->lpTemplateName, hwnd,NULL); -} - -/*********************************************************************** - * FontStyleEnumProc (COMMDLG.18) - */ -INT16 WINAPI FontStyleEnumProc16( SEGPTR logfont, SEGPTR metrics, - UINT16 nFontType, LPARAM lParam ) -{ - HWND hcmb2=HWND_32(LOWORD(lParam)); - HWND hcmb3=HWND_32(HIWORD(lParam)); - HWND hDlg=GetParent(hcmb3); - LPCHOOSEFONT16 lpcf; - LOGFONT16 *lplf = MapSL(logfont); - TEXTMETRIC16 *lpmtrx16 = MapSL(metrics); - ENUMLOGFONTEXW elf32w; - NEWTEXTMETRICEXW nmtrx32w; - - lpcf = (LPCHOOSEFONT16)GetPropW(hDlg, strWineFontData16); - FONT_LogFont16To32W(lplf, &(elf32w.elfLogFont)); - FONT_Metrics16To32W(lpmtrx16, &nmtrx32w); - return AddFontStyle(&elf32w, &nmtrx32w, nFontType, - (LPCHOOSEFONTW)lpcf->lpTemplateName, hcmb2, hcmb3, hDlg, TRUE); -} - -/*********************************************************************** - * ChooseFont (COMMDLG.15) - */ -BOOL16 WINAPI ChooseFont16(LPCHOOSEFONT16 lpChFont) -{ - HINSTANCE16 hInst; - HANDLE16 hDlgTmpl16 = 0; - HGLOBAL16 hGlobal16 = 0; - BOOL16 bRet = FALSE; - LPVOID template; - FARPROC16 ptr; - CHOOSEFONTW cf32w; - LOGFONTW lf32w; - LOGFONT16 *font16; - SEGPTR lpTemplateName; - - TRACE("ChooseFont\n"); - - if (!lpChFont) return FALSE; - - cf32w.lpLogFont=&lf32w; - CFn_CHOOSEFONT16to32W(lpChFont, &cf32w); - - if (TRACE_ON(commdlg)) - _dump_cf_flags(lpChFont->Flags); - - if (lpChFont->Flags & CF_ENABLETEMPLATEHANDLE) - { - if (!LockResource16( lpChFont->hInstance )) - { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return FALSE; - } - } - else if (lpChFont->Flags & CF_ENABLETEMPLATE) - { - HANDLE16 hResInfo; - if (!(hResInfo = FindResource16( lpChFont->hInstance, - MapSL(lpChFont->lpTemplateName), - (LPSTR)RT_DIALOG))) - { - COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); - return FALSE; - } - if (!(hDlgTmpl16 = LoadResource16( lpChFont->hInstance, hResInfo )) || - !LockResource16( hDlgTmpl16 )) - { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return FALSE; - } - } - else - { - HRSRC hResInfo; - HGLOBAL hDlgTmpl32; - LPCVOID template32; - DWORD size; - if (!(hResInfo = FindResourceA(COMDLG32_hInstance, "CHOOSE_FONT", (LPSTR)RT_DIALOG))) - { - COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); - return FALSE; - } - if (!(hDlgTmpl32 = LoadResource(COMDLG32_hInstance, hResInfo)) || - !(template32 = LockResource(hDlgTmpl32))) - { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return FALSE; - } - size = SizeofResource(COMDLG32_hInstance, hResInfo); - hGlobal16 = GlobalAlloc16(0, size); - if (!hGlobal16) - { - COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE); - ERR("alloc failure for %d bytes\n", size); - return FALSE; - } - template = GlobalLock16(hGlobal16); - if (!template) - { - COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE); - ERR("global lock failure for %x handle\n", hGlobal16); - GlobalFree16(hGlobal16); - return FALSE; - } - ConvertDialog32To16(template32, size, template); - hDlgTmpl16 = hGlobal16; - - } - - /* lpTemplateName is not used in the dialog */ - lpTemplateName=lpChFont->lpTemplateName; - lpChFont->lpTemplateName=(SEGPTR)&cf32w; - - ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR) 16); - hInst = GetWindowLongPtrA(HWND_32(lpChFont->hwndOwner), GWLP_HINSTANCE); - bRet = DialogBoxIndirectParam16(hInst, hDlgTmpl16, lpChFont->hwndOwner, - (DLGPROC16) ptr, (DWORD)lpChFont); - if (hGlobal16) - { - GlobalUnlock16(hGlobal16); - GlobalFree16(hGlobal16); - } - lpChFont->lpTemplateName=lpTemplateName; - - lpChFont->iPointSize = cf32w.iPointSize; - lpChFont->Flags = cf32w.Flags; - lpChFont->rgbColors = cf32w.rgbColors; - lpChFont->lCustData = cf32w.lCustData; - lpChFont->nFontType = cf32w.nFontType; - - font16 = MapSL(lpChFont->lpLogFont); - font16->lfHeight = cf32w.lpLogFont->lfHeight; - font16->lfWidth = cf32w.lpLogFont->lfWidth; - font16->lfEscapement = cf32w.lpLogFont->lfEscapement; - font16->lfOrientation = cf32w.lpLogFont->lfOrientation; - font16->lfWeight = cf32w.lpLogFont->lfWeight; - font16->lfItalic = cf32w.lpLogFont->lfItalic; - font16->lfUnderline = cf32w.lpLogFont->lfUnderline; - font16->lfStrikeOut = cf32w.lpLogFont->lfStrikeOut; - font16->lfCharSet = cf32w.lpLogFont->lfCharSet; - font16->lfOutPrecision = cf32w.lpLogFont->lfOutPrecision; - font16->lfClipPrecision = cf32w.lpLogFont->lfClipPrecision; - font16->lfQuality = cf32w.lpLogFont->lfQuality; - font16->lfPitchAndFamily = cf32w.lpLogFont->lfPitchAndFamily; - WideCharToMultiByte(CP_ACP, 0, cf32w.lpLogFont->lfFaceName, - LF_FACESIZE, font16->lfFaceName, LF_FACESIZE, 0, 0); - - HeapFree(GetProcessHeap(), 0, (LPBYTE)cf32w.lpTemplateName); - HeapFree(GetProcessHeap(), 0, cf32w.lpszStyle); - - return bRet; -} - -/*********************************************************************** - * FormatCharDlgProc (COMMDLG.16) - FIXME: 1. some strings are "hardcoded", but it's better load from sysres - 2. some CF_.. flags are not supported - 3. some TType extensions - */ -BOOL16 CALLBACK FormatCharDlgProc16(HWND16 hDlg16, UINT16 message, - WPARAM16 wParam, LPARAM lParam) -{ - HWND hDlg = HWND_32(hDlg16); - LPCHOOSEFONT16 lpcf; - BOOL16 res=0; - if (message!=WM_INITDIALOG) - { - lpcf = (LPCHOOSEFONT16)GetPropW(hDlg, strWineFontData16); - if (!lpcf) - return FALSE; - if (CFn_HookCallChk(lpcf)) - res=CallWindowProc16((WNDPROC16)lpcf->lpfnHook,hDlg16,message,wParam,lParam); - if (res) - return res; - } - else - { - lpcf=(LPCHOOSEFONT16)lParam; - if (!CFn_WMInitDialog(hDlg, wParam, lParam, (LPCHOOSEFONTW)lpcf->lpTemplateName)) - { - TRACE("CFn_WMInitDialog returned FALSE\n"); - return FALSE; - } - SetPropW(hDlg, strWineFontData16, (HANDLE)lParam); - if (CFn_HookCallChk(lpcf)) - return CallWindowProc16((WNDPROC16)lpcf->lpfnHook,hDlg16,WM_INITDIALOG,wParam,lParam); - } - switch (message) - { - case WM_MEASUREITEM: - { - MEASUREITEMSTRUCT16* mis16 = MapSL(lParam); - MEASUREITEMSTRUCT mis; - mis.CtlType = mis16->CtlType; - mis.CtlID = mis16->CtlID; - mis.itemID = mis16->itemID; - mis.itemWidth = mis16->itemWidth; - mis.itemHeight = mis16->itemHeight; - mis.itemData = mis16->itemData; - res = CFn_WMMeasureItem(hDlg, wParam, (LPARAM)&mis); - mis16->itemWidth = (UINT16)mis.itemWidth; - mis16->itemHeight = (UINT16)mis.itemHeight; - } - break; - case WM_DRAWITEM: - { - DRAWITEMSTRUCT16* dis16 = MapSL(lParam); - DRAWITEMSTRUCT dis; - dis.CtlType = dis16->CtlType; - dis.CtlID = dis16->CtlID; - dis.itemID = dis16->itemID; - dis.itemAction = dis16->itemAction; - dis.itemState = dis16->itemState; - dis.hwndItem = HWND_32(dis16->hwndItem); - dis.hDC = HDC_32(dis16->hDC); - dis.itemData = dis16->itemData; - dis.rcItem.left = dis16->rcItem.left; - dis.rcItem.top = dis16->rcItem.top; - dis.rcItem.right = dis16->rcItem.right; - dis.rcItem.bottom = dis16->rcItem.bottom; - res = CFn_WMDrawItem(hDlg, wParam, (LPARAM)&dis); - } - break; - case WM_COMMAND: - res=CFn_WMCommand(hDlg, MAKEWPARAM( wParam, HIWORD(lParam) ), LOWORD(lParam), - (LPCHOOSEFONTW)lpcf->lpTemplateName); - break; - case WM_DESTROY: - return TRUE; - case WM_CHOOSEFONT_GETLOGFONT: - TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam); - FIXME("current logfont back to caller\n"); - break; - case WM_PAINT: - res= CFn_WMPaint(hDlg, wParam, lParam, (LPCHOOSEFONTW)lpcf->lpTemplateName); - break; - } - return res; -} diff --git a/reactos/dll/win32/comdlg32/printdlg.c b/reactos/dll/win32/comdlg32/printdlg.c index 5a4816dcacd..f653251ed16 100644 --- a/reactos/dll/win32/comdlg32/printdlg.c +++ b/reactos/dll/win32/comdlg32/printdlg.c @@ -42,19 +42,53 @@ #include "commdlg.h" #include "dlgs.h" #include "cderr.h" +#include "cdlg.h" WINE_DEFAULT_DEBUG_CHANNEL(commdlg); -#include "cdlg.h" -#include "printdlg.h" - /* Yes these constants are the same, but we're just copying win98 */ #define UPDOWN_ID 0x270f #define MAX_COPIES 9999 -DEVMODEW* WINAPI GdiConvertToDevmodeW(const DEVMODEA*); +/* 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"}, @@ -75,6 +109,31 @@ static const struct pd_flags psd_flags[] = { {-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; @@ -149,7 +208,7 @@ static DEVMODEA *convert_to_devmodeA(const DEVMODEW *dmW) * * Returns TRUE on success else FALSE */ -BOOL PRINTDLG_OpenDefaultPrinter(HANDLE *hprn) +static BOOL PRINTDLG_OpenDefaultPrinter(HANDLE *hprn) { WCHAR buf[260]; DWORD dwBufLen = sizeof(buf) / sizeof(buf[0]); @@ -175,7 +234,7 @@ BOOL PRINTDLG_OpenDefaultPrinter(HANDLE *hprn) * * Returns number of printers added to list. */ -INT PRINTDLG_SetUpPrinterListComboA(HWND hDlg, UINT id, LPCSTR name) +static INT PRINTDLG_SetUpPrinterListComboA(HWND hDlg, UINT id, LPCSTR name) { DWORD needed, num; INT i; @@ -839,8 +898,7 @@ static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg, const PRINTER_INFO_2W *p * PRINTDLG_ChangePrinter * */ -BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name, - PRINT_PTRA *PrintStructures) +static BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name, PRINT_PTRA *PrintStructures) { LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; LPDEVMODEA lpdm = NULL; @@ -921,11 +979,11 @@ BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name, * FIXME: The ico3 is not displayed for some reason. I don't know why. */ if (lppd->Flags & PD_COLLATE) { - SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hCollateIcon); CheckDlgButton(hDlg, chx2, 1); } else { - SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hNoCollateIcon); CheckDlgButton(hDlg, chx2, 0); } @@ -1032,7 +1090,7 @@ BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name, PrintStructures->lpPrinterInfo->pPortName, lpdm); CheckRadioButton(hDlg, rad1, rad2, bPortrait ? rad1: rad2); - SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, (LPARAM)(bPortrait ? PrintStructures->hPortraitIcon : PrintStructures->hLandscapeIcon)); @@ -1128,11 +1186,11 @@ static BOOL PRINTDLG_ChangePrinterW(HWND hDlg, WCHAR *name, * FIXME: The ico3 is not displayed for some reason. I don't know why. */ if (lppd->Flags & PD_COLLATE) { - SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hCollateIcon); CheckDlgButton(hDlg, chx2, 1); } else { - SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hNoCollateIcon); CheckDlgButton(hDlg, chx2, 0); } @@ -1184,7 +1242,7 @@ static BOOL PRINTDLG_ChangePrinterW(HWND hDlg, WCHAR *name, PrintStructures->lpPrinterInfo->pPortName, lpdm); CheckRadioButton(hDlg, rad1, rad2, bPortrait ? rad1: rad2); - SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, (LPARAM)(bPortrait ? PrintStructures->hPortraitIcon : PrintStructures->hLandscapeIcon)); @@ -1225,7 +1283,7 @@ static LRESULT check_printer_setup(HWND hDlg) /*********************************************************************** * PRINTDLG_WMInitDialog [internal] */ -static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, WPARAM wParam, +static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, PRINT_PTRA* PrintStructures) { LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; @@ -1249,7 +1307,7 @@ static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, WPARAM wParam, LoadIconA(COMDLG32_hInstance, "PD32_LANDSCAPE"); /* display the collate/no_collate icon */ - SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hNoCollateIcon); if(PrintStructures->hCollateIcon == 0 || @@ -1333,7 +1391,7 @@ static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, WPARAM wParam, return TRUE; } -static LRESULT PRINTDLG_WMInitDialogW(HWND hDlg, WPARAM wParam, +static LRESULT PRINTDLG_WMInitDialogW(HWND hDlg, PRINT_PTRW* PrintStructures) { LPPRINTDLGW lppd = PrintStructures->lpPrintDlg; @@ -1357,7 +1415,7 @@ static LRESULT PRINTDLG_WMInitDialogW(HWND hDlg, WPARAM wParam, LoadIconW(COMDLG32_hInstance, pd32_landscapeW); /* display the collate/no_collate icon */ - SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hNoCollateIcon); if(PrintStructures->hCollateIcon == 0 || @@ -1445,8 +1503,8 @@ static LRESULT PRINTDLG_WMInitDialogW(HWND hDlg, WPARAM wParam, /*********************************************************************** * PRINTDLG_WMCommand [internal] */ -LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam, - LPARAM lParam, PRINT_PTRA* PrintStructures) +static LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam, + LPARAM lParam, PRINT_PTRA* PrintStructures) { LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; @@ -1475,10 +1533,10 @@ LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam, case chx2: /* collate pages checkbox */ if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) - SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hCollateIcon); else - SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hNoCollateIcon); break; case edt1: /* from page nr editbox */ @@ -1503,24 +1561,6 @@ LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam, } break; -#if 0 - case psh1: /* Print Setup */ - { - PRINTDLG16 pdlg; - - if (!PrintStructures->dlg.lpPrintDlg16) { - FIXME("The 32bit print dialog does not have this button!?\n"); - break; - } - - memcpy(&pdlg,PrintStructures->dlg.lpPrintDlg16,sizeof(pdlg)); - pdlg.Flags |= PD_PRINTSETUP; - pdlg.hwndOwner = HWND_16(hDlg); - if (!PrintDlg16(&pdlg)) - break; - } - break; -#endif case psh2: /* Properties button */ { HANDLE hPrinter; @@ -1543,7 +1583,7 @@ LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam, if (lppd->Flags & PD_PRINTSETUP) { lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; - SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, (LPARAM)(PrintStructures->hPortraitIcon)); } break; @@ -1552,7 +1592,7 @@ LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam, if (lppd->Flags & PD_PRINTSETUP) { lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE; - SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, (LPARAM)(PrintStructures->hLandscapeIcon)); } break; @@ -1597,21 +1637,17 @@ LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam, if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED) { if(lpdm->u1.s1.dmOrientation != DMORIENT_PORTRAIT) { lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; - SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE, - (WPARAM)IMAGE_ICON, + SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hPortraitIcon); - SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, - (WPARAM)IMAGE_ICON, + SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hPortraitIcon); } } else { if(lpdm->u1.s1.dmOrientation != DMORIENT_LANDSCAPE) { lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE; - SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE, - (WPARAM)IMAGE_ICON, + SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hLandscapeIcon); - SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, - (WPARAM)IMAGE_ICON, + SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hLandscapeIcon); } } @@ -1651,10 +1687,10 @@ static LRESULT PRINTDLG_WMCommandW(HWND hDlg, WPARAM wParam, case chx2: /* collate pages checkbox */ if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) - SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hCollateIcon); else - SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hNoCollateIcon); break; case edt1: /* from page nr editbox */ @@ -1679,11 +1715,6 @@ static LRESULT PRINTDLG_WMCommandW(HWND hDlg, WPARAM wParam, } break; - case psh1: /* Print Setup */ - { - ERR("psh1 is called from 16bit code only, we should not get here.\n"); - } - break; case psh2: /* Properties button */ { HANDLE hPrinter; @@ -1706,7 +1737,7 @@ static LRESULT PRINTDLG_WMCommandW(HWND hDlg, WPARAM wParam, if (lppd->Flags & PD_PRINTSETUP) { lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; - SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, (LPARAM)(PrintStructures->hPortraitIcon)); } break; @@ -1715,7 +1746,7 @@ static LRESULT PRINTDLG_WMCommandW(HWND hDlg, WPARAM wParam, if (lppd->Flags & PD_PRINTSETUP) { lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE; - SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, (LPARAM)(PrintStructures->hLandscapeIcon)); } break; @@ -1757,21 +1788,17 @@ static LRESULT PRINTDLG_WMCommandW(HWND hDlg, WPARAM wParam, if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED) { if(lpdm->u1.s1.dmOrientation != DMORIENT_PORTRAIT) { lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; - SendDlgItemMessageW(hDlg, stc10, STM_SETIMAGE, - (WPARAM)IMAGE_ICON, + SendDlgItemMessageW(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hPortraitIcon); - SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, - (WPARAM)IMAGE_ICON, + SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hPortraitIcon); } } else { if(lpdm->u1.s1.dmOrientation != DMORIENT_LANDSCAPE) { lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE; - SendDlgItemMessageW(hDlg, stc10, STM_SETIMAGE, - (WPARAM)IMAGE_ICON, + SendDlgItemMessageW(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hLandscapeIcon); - SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, - (WPARAM)IMAGE_ICON, + SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, (LPARAM)PrintStructures->hLandscapeIcon); } } @@ -1802,7 +1829,7 @@ static INT_PTR CALLBACK PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, EndDialog(hDlg,FALSE); return FALSE; } - res = PRINTDLG_WMInitDialog(hDlg, wParam, PrintStructures); + res = PRINTDLG_WMInitDialog(hDlg, PrintStructures); if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) res = PrintStructures->lpPrintDlg->lpfnPrintHook( @@ -1851,7 +1878,7 @@ static INT_PTR CALLBACK PrintDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, EndDialog(hDlg,FALSE); return FALSE; } - res = PRINTDLG_WMInitDialogW(hDlg, wParam, PrintStructures); + res = PRINTDLG_WMInitDialogW(hDlg, PrintStructures); if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg, uMsg, wParam, (LPARAM)PrintStructures->lpPrintDlg); @@ -2030,7 +2057,6 @@ BOOL WINAPI PrintDlgA(LPPRINTDLGA lppd) return FALSE; } - hInst = (HINSTANCE)GetWindowLongPtrA( lppd->hwndOwner, GWLP_HINSTANCE ); if(TRACE_ON(commdlg)) { char flagstr[1000] = ""; const struct pd_flags *pflag = pd_flags; @@ -2123,6 +2149,8 @@ BOOL WINAPI PrintDlgA(LPPRINTDLGA 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)); @@ -2180,7 +2208,6 @@ BOOL WINAPI PrintDlgW(LPPRINTDLGW lppd) return FALSE; } - hInst = (HINSTANCE)GetWindowLongPtrW( lppd->hwndOwner, GWLP_HINSTANCE ); if(TRACE_ON(commdlg)) { char flagstr[1000] = ""; const struct pd_flags *pflag = pd_flags; @@ -2273,6 +2300,8 @@ BOOL WINAPI PrintDlgW(LPPRINTDLGW 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)); diff --git a/reactos/dll/win32/comdlg32/printdlg16.c b/reactos/dll/win32/comdlg32/printdlg16.c deleted file mode 100644 index 9e867061241..00000000000 --- a/reactos/dll/win32/comdlg32/printdlg16.c +++ /dev/null @@ -1,602 +0,0 @@ -/* - * COMMDLG - Print Dialog - * - * Copyright 1994 Martin Ayotte - * Copyright 1996 Albrecht Kleine - * Copyright 1999 Klaas van Gend - * Copyright 2000 Huw D M Davies - * - * 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 - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "wine/wingdi16.h" -#include "winuser.h" -#include "wine/winuser16.h" -#include "commdlg.h" -#include "dlgs.h" -#include "wine/debug.h" -#include "cderr.h" -#include "winspool.h" - -WINE_DEFAULT_DEBUG_CHANNEL(commdlg); - -#include "cdlg.h" -#include "cdlg16.h" -#include "printdlg.h" - -typedef struct -{ - PRINT_PTRA print32; - LPPRINTDLG16 lpPrintDlg16; -} PRINT_PTRA16; - -/* Internal Functions */ - -static BOOL PRINTDLG_CreateDevNames16(HGLOBAL16 *hmem, const char* DeviceDriverName, - const char* DeviceName, const char* OutputPort) -{ - long size; - char* pDevNamesSpace; - char* pTempPtr; - LPDEVNAMES lpDevNames; - char buf[260]; - DWORD dwBufLen = sizeof(buf); - - size = strlen(DeviceDriverName) + 1 - + strlen(DeviceName) + 1 - + strlen(OutputPort) + 1 - + sizeof(DEVNAMES); - - if(*hmem) - *hmem = GlobalReAlloc16(*hmem, size, GMEM_MOVEABLE); - else - *hmem = GlobalAlloc16(GMEM_MOVEABLE, size); - if (*hmem == 0) - return FALSE; - - pDevNamesSpace = GlobalLock16(*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; - GlobalUnlock16(*hmem); - return TRUE; -} - - -/*********************************************************************** - * PRINTDLG_WMInitDialog [internal] - */ -static LRESULT PRINTDLG_WMInitDialog16(HWND hDlg, WPARAM wParam, PRINT_PTRA16* ptr16) -{ - PRINT_PTRA *PrintStructures = &ptr16->print32; - LPPRINTDLG16 lppd = ptr16->lpPrintDlg16; - DEVNAMES *pdn; - DEVMODEA *pdm; - char *name = NULL; - UINT comboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; - - /* load Collate ICONs */ - PrintStructures->hCollateIcon = - LoadIconA(COMDLG32_hInstance, "PD32_COLLATE"); - PrintStructures->hNoCollateIcon = - LoadIconA(COMDLG32_hInstance, "PD32_NOCOLLATE"); - if(PrintStructures->hCollateIcon == 0 || - PrintStructures->hNoCollateIcon == 0) { - ERR("no icon in resourcefile\n"); - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - EndDialog(hDlg, FALSE); - } - - /* load Paper Orientation ICON */ - /* FIXME: not implemented yet */ - - /* - * 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)) { - /* We have a print quality combo box. What shall we do? */ - if (GetDlgItem(hDlg,cmb1)) { - char buf [20]; - - FIXME("Print quality only displaying currently.\n"); - - pdm = GlobalLock16(lppd->hDevMode); - if(pdm) { - switch (pdm->u1.s1.dmPrintQuality) { - case DMRES_HIGH : strcpy(buf,"High");break; - case DMRES_MEDIUM : strcpy(buf,"Medium");break; - case DMRES_LOW : strcpy(buf,"Low");break; - case DMRES_DRAFT : strcpy(buf,"Draft");break; - case 0 : strcpy(buf,"Default");break; - default : sprintf(buf,"%ddpi",pdm->u1.s1.dmPrintQuality);break; - } - GlobalUnlock16(lppd->hDevMode); - } else - strcpy(buf,"Default"); - SendDlgItemMessageA(hDlg,cmb1,CB_ADDSTRING,0,(LPARAM)buf); - SendDlgItemMessageA(hDlg,cmb1,CB_SETCURSEL,0,0); - EnableWindow(GetDlgItem(hDlg,cmb1),FALSE); - } - } - - /* 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 the printer combo box is in the dialog, fill it */ - if (GetDlgItem(hDlg,comboID)) { - /* Fill Combobox - */ - pdn = GlobalLock16(lppd->hDevNames); - pdm = GlobalLock16(lppd->hDevMode); - if(pdn) - name = (char*)pdn + pdn->wDeviceOffset; - else if(pdm) - name = (char*)pdm->dmDeviceName; - PRINTDLG_SetUpPrinterListComboA(hDlg, comboID, name); - if(pdm) GlobalUnlock16(lppd->hDevMode); - if(pdn) GlobalUnlock16(lppd->hDevNames); - - /* Now find selected printer and update rest of dlg */ - name = HeapAlloc(GetProcessHeap(),0,256); - if (GetDlgItemTextA(hDlg, comboID, name, 255)) - PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); - } else { - /* else just use default printer */ - char name[200]; - DWORD dwBufLen = sizeof(name); - BOOL ret = GetDefaultPrinterA(name, &dwBufLen); - - if (ret) - PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); - else - FIXME("No default printer found, expect problems!\n"); - } - HeapFree(GetProcessHeap(),0,name); - - return TRUE; -} - -/************************************************************ - * - * PRINTDLG_Get16TemplateFrom32 [Internal] - * Generates a 16 bits template from the Wine 32 bits resource - * - */ -static HGLOBAL16 PRINTDLG_Get16TemplateFrom32(LPCSTR PrintResourceName) -{ - HRSRC hResInfo; - HGLOBAL hDlgTmpl32; - LPCVOID template32; - DWORD size; - HGLOBAL16 hGlobal16; - LPVOID template; - - if (!(hResInfo = FindResourceA(COMDLG32_hInstance, - PrintResourceName, (LPSTR)RT_DIALOG))) - { - COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); - return 0; - } - if (!(hDlgTmpl32 = LoadResource(COMDLG32_hInstance, hResInfo )) || - !(template32 = LockResource( hDlgTmpl32 ))) - { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return 0; - } - size = SizeofResource(COMDLG32_hInstance, hResInfo); - hGlobal16 = GlobalAlloc16(0, size); - if (!hGlobal16) - { - COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE); - ERR("alloc failure for %d bytes\n", size); - return 0; - } - template = GlobalLock16(hGlobal16); - if (!template) - { - COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE); - ERR("global lock failure for %x handle\n", hGlobal16); - GlobalFree16(hGlobal16); - return 0; - } - ConvertDialog32To16(template32, size, template); - GlobalUnlock16(hGlobal16); - return hGlobal16; -} - -static BOOL PRINTDLG_CreateDC16(LPPRINTDLG16 lppd) -{ - DEVNAMES *pdn = GlobalLock16(lppd->hDevNames); - DEVMODEA *pdm = GlobalLock16(lppd->hDevMode); - - if(lppd->Flags & PD_RETURNDC) { - lppd->hDC = HDC_16(CreateDCA((char*)pdn + pdn->wDriverOffset, - (char*)pdn + pdn->wDeviceOffset, - (char*)pdn + pdn->wOutputOffset, - pdm )); - } else if(lppd->Flags & PD_RETURNIC) { - lppd->hDC = HDC_16(CreateICA((char*)pdn + pdn->wDriverOffset, - (char*)pdn + pdn->wDeviceOffset, - (char*)pdn + pdn->wOutputOffset, - pdm )); - } - GlobalUnlock16(lppd->hDevNames); - GlobalUnlock16(lppd->hDevMode); - return lppd->hDC ? TRUE : FALSE; -} - -/************************************************************ - * - * PRINTDLG_GetDlgTemplate - * - */ -static HGLOBAL16 PRINTDLG_GetDlgTemplate16(const PRINTDLG16 *lppd) -{ - HGLOBAL16 hDlgTmpl, hResInfo; - - if (lppd->Flags & PD_PRINTSETUP) { - if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE) { - hDlgTmpl = lppd->hSetupTemplate; - } else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) { - hResInfo = FindResource16(lppd->hInstance, - MapSL(lppd->lpSetupTemplateName), (LPSTR)RT_DIALOG); - hDlgTmpl = LoadResource16(lppd->hInstance, hResInfo); - } else { - hDlgTmpl = PRINTDLG_Get16TemplateFrom32("PRINT32_SETUP"); - } - } else { - if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE) { - hDlgTmpl = lppd->hPrintTemplate; - } else if(lppd->Flags & PD_ENABLEPRINTTEMPLATE) { - hResInfo = FindResource16(lppd->hInstance, - MapSL(lppd->lpPrintTemplateName), - (LPSTR)RT_DIALOG); - hDlgTmpl = LoadResource16(lppd->hInstance, hResInfo); - } else { - hDlgTmpl = PRINTDLG_Get16TemplateFrom32("PRINT32"); - } - } - return hDlgTmpl; -} - -/********************************************************************** - * - * 16 bit commdlg - */ - -/*********************************************************************** - * PrintDlg (COMMDLG.20) - * - * Displays the PRINT dialog box, which enables the user to specify - * specific properties of the print job. - * - * RETURNS - * nonzero if the user pressed the OK button - * zero if the user cancelled the window or an error occurred - * - * BUGS - * * calls up to the 32-bit versions of the Dialogs, which look different - * * Customizing is *not* implemented. - */ - -BOOL16 WINAPI PrintDlg16( - LPPRINTDLG16 lppd /* [in/out] ptr to PRINTDLG struct */ -) { - BOOL bRet = FALSE; - LPVOID ptr; - HINSTANCE16 hInst = GetWindowLongPtrW( HWND_32(lppd->hwndOwner), GWLP_HINSTANCE ); - - 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 = %08x, hDevMode = %08x, hDevNames = %08x\n" - "pp. %d-%d, min p %d, max p %d, copies %d, hinst %08x\n" - "flags %08x (%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(PRINTDLG16)) { - ERR("structure size %d\n",lppd->lStructSize); - 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 = HeapAlloc(GetProcessHeap(), 0, needed); - GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed); - GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed); - dbuf = HeapAlloc(GetProcessHeap(),0,needed); - if (!GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed)) { - ERR("GetPrinterDriverA failed for %s, le %d, fix your config!\n", - pbuf->pPrinterName,GetLastError()); - HeapFree(GetProcessHeap(), 0, dbuf); - HeapFree(GetProcessHeap(), 0, pbuf); - COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); - return FALSE; - } - ClosePrinter(hprn); - PRINTDLG_CreateDevNames16(&(lppd->hDevNames), - dbuf->pDriverPath, - pbuf->pPrinterName, - pbuf->pPortName); - lppd->hDevMode = GlobalAlloc16(GMEM_MOVEABLE,pbuf->pDevMode->dmSize+ - pbuf->pDevMode->dmDriverExtra); - ptr = GlobalLock16(lppd->hDevMode); - memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize + - pbuf->pDevMode->dmDriverExtra); - GlobalUnlock16(lppd->hDevMode); - HeapFree(GetProcessHeap(), 0, pbuf); - HeapFree(GetProcessHeap(), 0, dbuf); - bRet = TRUE; - } else { - HGLOBAL16 hDlgTmpl; - PRINT_PTRA *PrintStructures; - PRINT_PTRA16 *ptr16; - - /* load Dialog resources, - * depending on Flags indicates Print32 or Print32_setup dialog - */ - hDlgTmpl = PRINTDLG_GetDlgTemplate16(lppd); - if (!hDlgTmpl) { - COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); - return FALSE; - } - ptr16 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PRINT_PTRA16)); - ptr16->lpPrintDlg16 = lppd; - PrintStructures = &ptr16->print32; - PrintStructures->lpPrintDlg = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PRINTDLGA)); -#define CVAL(x) PrintStructures->lpPrintDlg->x = lppd->x; -#define MVAL(x) PrintStructures->lpPrintDlg->x = MapSL(lppd->x); - CVAL(Flags); - PrintStructures->lpPrintDlg->hwndOwner = HWND_32(lppd->hwndOwner); - PrintStructures->lpPrintDlg->hDC = HDC_32(lppd->hDC); - CVAL(nFromPage);CVAL(nToPage);CVAL(nMinPage);CVAL(nMaxPage); - CVAL(nCopies); - PrintStructures->lpPrintDlg->hInstance = HINSTANCE_32(lppd->hInstance); - CVAL(lCustData); - MVAL(lpPrintTemplateName);MVAL(lpSetupTemplateName); - /* Don't copy rest, it is 16 bit specific */ -#undef MVAL -#undef CVAL - - PrintStructures->lpDevMode = HeapAlloc(GetProcessHeap(),0,sizeof(DEVMODEA)); - - /* and create & process the dialog . - * -1 is failure, 0 is broken hwnd, everything else is ok. - */ - bRet = (0hwndOwner, - (DLGPROC16)GetProcAddress16(GetModuleHandle16("COMMDLG"),(LPCSTR)21), - (LPARAM)PrintStructures - ) - ); - if (!PrintStructures->lpPrinterInfo) bRet = FALSE; - 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 = GlobalAlloc16(GMEM_MOVEABLE, - lpdm->dmSize + lpdm->dmDriverExtra); - } else { - WORD locks; - if((locks = (GlobalFlags16(lppd->hDevMode)&GMEM_LOCKCOUNT))) { - WARN("hDevMode has %d locks on it. Unlocking it now\n", locks); - while(locks--) { - GlobalUnlock16(lppd->hDevMode); - TRACE("Now got %d locks\n", locks); - } - } - lppd->hDevMode = GlobalReAlloc16(lppd->hDevMode, - lpdm->dmSize + lpdm->dmDriverExtra, - GMEM_MOVEABLE); - } - lpdmReturn = GlobalLock16(lppd->hDevMode); - memcpy(lpdmReturn, lpdm, lpdm->dmSize + lpdm->dmDriverExtra); - - if (lppd->hDevNames != 0) { - WORD locks; - if((locks = (GlobalFlags16(lppd->hDevNames)&GMEM_LOCKCOUNT))) { - WARN("hDevNames has %d locks on it. Unlocking it now\n", locks); - while(locks--) - GlobalUnlock16(lppd->hDevNames); - } - } - PRINTDLG_CreateDevNames16(&(lppd->hDevNames), - di->pDriverPath, - pi->pPrinterName, - pi->pPortName - ); - GlobalUnlock16(lppd->hDevMode); - /* Copy back the [out] integer parameters */ -#define CVAL(x) lppd->x = PrintStructures->lpPrintDlg->x; - CVAL(Flags); - CVAL(nFromPage); - CVAL(nToPage); - CVAL(nCopies); -#undef CVAL - - } - if (!(lppd->Flags & (PD_ENABLESETUPTEMPLATEHANDLE | PD_ENABLESETUPTEMPLATE))) - GlobalFree16(hDlgTmpl); /* created from the 32 bits resource */ - HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode); - HeapFree(GetProcessHeap(), 0, PrintStructures->lpPrinterInfo); - HeapFree(GetProcessHeap(), 0, PrintStructures->lpDriverInfo); - HeapFree(GetProcessHeap(), 0, ptr16); - } - if(bRet && (lppd->Flags & PD_RETURNDC || lppd->Flags & PD_RETURNIC)) - bRet = PRINTDLG_CreateDC16(lppd); - - TRACE("exit! (%d)\n", bRet); - return bRet; -} - -/*********************************************************************** - * PrintDlgProc (COMMDLG.21) - */ -BOOL16 CALLBACK PrintDlgProc16(HWND16 hDlg16, UINT16 uMsg, WPARAM16 wParam, - LPARAM lParam) -{ - HWND hDlg = HWND_32(hDlg16); - PRINT_PTRA16 *PrintStructures; - BOOL16 res = FALSE; - - if (uMsg!=WM_INITDIALOG) { - PrintStructures = GetPropA(hDlg,"__WINE_PRINTDLGDATA"); - if (!PrintStructures) - return FALSE; - } else { - PrintStructures = (PRINT_PTRA16*) lParam; - SetPropA(hDlg,"__WINE_PRINTDLGDATA",PrintStructures); - res = PRINTDLG_WMInitDialog16(hDlg, wParam, PrintStructures); - - if(PrintStructures->lpPrintDlg16->Flags & PD_ENABLEPRINTHOOK) { - res = CallWindowProc16( - (WNDPROC16)PrintStructures->lpPrintDlg16->lpfnPrintHook, - hDlg16, uMsg, wParam, (LPARAM)PrintStructures->lpPrintDlg16 - ); - } - return res; - } - - if(PrintStructures->lpPrintDlg16->Flags & PD_ENABLEPRINTHOOK) { - res = CallWindowProc16( - (WNDPROC16)PrintStructures->lpPrintDlg16->lpfnPrintHook, - hDlg16,uMsg, wParam, lParam - ); - if(LOWORD(res)) return res; - } - - switch (uMsg) { - case WM_COMMAND: { - /* We need to map those for the 32bit window procedure, compare - * with 32Ato16 mapper in winproc.c - */ - return PRINTDLG_WMCommandA( - hDlg, - MAKEWPARAM(wParam,HIWORD(lParam)), - LOWORD(lParam), - &PrintStructures->print32 - ); - } - case WM_DESTROY: - DestroyIcon(PrintStructures->print32.hCollateIcon); - DestroyIcon(PrintStructures->print32.hNoCollateIcon); - /* FIXME: don't forget to delete the paper orientation icons here! */ - - return FALSE; - } - return res; -} - -/*********************************************************************** - * PrintSetupDlgProc (COMMDLG.22) - */ -BOOL16 CALLBACK PrintSetupDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam, - LPARAM lParam) -{ - HWND hWnd = HWND_32(hWnd16); - switch (wMsg) - { - case WM_INITDIALOG: - TRACE("WM_INITDIALOG lParam=%08lX\n", lParam); - ShowWindow(hWnd, SW_SHOWNORMAL); - return (TRUE); - case WM_COMMAND: - switch (wParam) { - case IDOK: - EndDialog(hWnd, TRUE); - return(TRUE); - case IDCANCEL: - EndDialog(hWnd, FALSE); - return(TRUE); - } - return(FALSE); - } - return FALSE; -} diff --git a/reactos/dll/win32/comdlg32/rsrc.rc b/reactos/dll/win32/comdlg32/rsrc.rc index d6f160de2ae..4db00685fe6 100644 --- a/reactos/dll/win32/comdlg32/rsrc.rc +++ b/reactos/dll/win32/comdlg32/rsrc.rc @@ -45,29 +45,30 @@ #include "cdlg_Ca.rc" #include "cdlg_Cs.rc" #include "cdlg_Da.rc" -#include "cdlg_De.rc" #include "cdlg_El.rc" #include "cdlg_En.rc" #include "cdlg_Eo.rc" #include "cdlg_Es.rc" #include "cdlg_Fi.rc" -#include "cdlg_Fr.rc" #include "cdlg_Hu.rc" #include "cdlg_It.rc" -#include "cdlg_Ja.rc" #include "cdlg_Ko.rc" -#include "cdlg_Lt.rc" #include "cdlg_Nl.rc" #include "cdlg_No.rc" #include "cdlg_Pl.rc" -#include "cdlg_Pt.rc" -#include "cdlg_Ro.rc" -#include "cdlg_Ru.rc" -#include "cdlg_Si.rc" #include "cdlg_Sk.rc" #include "cdlg_Sv.rc" #include "cdlg_Th.rc" #include "cdlg_Tr.rc" #include "cdlg_Uk.rc" #include "cdlg_Wa.rc" + +#include "cdlg_De.rc" +#include "cdlg_Fr.rc" +#include "cdlg_Ja.rc" +#include "cdlg_Lt.rc" +#include "cdlg_Pt.rc" +#include "cdlg_Ro.rc" +#include "cdlg_Ru.rc" +#include "cdlg_Si.rc" #include "cdlg_Zh.rc" diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 7cd927d7b7a..a588c563353 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -49,7 +49,7 @@ reactos/dll/win32/cabinet # Autosync reactos/dll/win32/clusapi # Autosync reactos/dll/win32/comcat # Autosync reactos/dll/win32/comctl32 # Autosync ?? -reactos/dll/win32/comdlg32 # Autosync ?? +reactos/dll/win32/comdlg32 # Autosync reactos/dll/win32/compstui # Autosync reactos/dll/win32/credui # Autosync reactos/dll/win32/crypt32 # Synced to Wine-1_1_40 From 4e765c23506f11d9c4f2d6de69c1debe6016d869 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Thu, 11 Mar 2010 17:46:15 +0000 Subject: [PATCH 44/64] [WIN32K]: Stop memory corruption when InstalledDisplayDrivers has more than one driver in the list. Note that driver loading is inherently broken right now, as the list of drivers is not parsed properly (this breaks eVb's VGA/VBE driver). svn path=/trunk/; revision=46103 --- .../subsystems/win32/win32k/objects/device.c | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/device.c b/reactos/subsystems/win32/win32k/objects/device.c index 6dfe195ec0c..40a79562ede 100644 --- a/reactos/subsystems/win32/win32k/objects/device.c +++ b/reactos/subsystems/win32/win32k/objects/device.c @@ -59,12 +59,37 @@ GetRegistryPath(PUNICODE_STRING RegistryPath, ULONG DisplayNumber) return TRUE; } + +NTSTATUS +NTAPI +EnumDisplayQueryRoutine(IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext) +{ + if ((Context == NULL) && ((ValueType == REG_SZ) || (ValueType == REG_MULTI_SZ))) + { + *(PULONG)EntryContext = ValueLength; + } + else + { + DPRINT1("Value data: %S %d\n", ValueData, ValueLength); + RtlCopyMemory(Context, ValueData, ValueLength); + } + + return STATUS_SUCCESS; +} + static BOOL FASTCALL FindDriverFileNames(PUNICODE_STRING DriverFileNames, ULONG DisplayNumber) { RTL_QUERY_REGISTRY_TABLE QueryTable[2]; UNICODE_STRING RegistryPath; NTSTATUS Status; + PWCHAR DriverNames = NULL; + ULONG Length = 0; if (! GetRegistryPath(&RegistryPath, DisplayNumber)) { @@ -73,23 +98,40 @@ FindDriverFileNames(PUNICODE_STRING DriverFileNames, ULONG DisplayNumber) } RtlZeroMemory(QueryTable, sizeof(QueryTable)); - QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND; QueryTable[0].Name = L"InstalledDisplayDrivers"; - QueryTable[0].EntryContext = DriverFileNames; + QueryTable[0].EntryContext = &Length; + QueryTable[0].QueryRoutine = EnumDisplayQueryRoutine; Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, RegistryPath.Buffer, QueryTable, NULL, NULL); + // DPRINT1("Status: %lx\n", Status); + if (Length) + { + DriverNames = ExAllocatePool(PagedPool, Length); + // DPRINT1("Length allocated: %d\n", Length); + Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, + RegistryPath.Buffer, + QueryTable, + DriverNames, + NULL); + if (!NT_SUCCESS(Status)) DriverNames = NULL; + } + ExFreePoolWithTag(RegistryPath.Buffer, TAG_RTLREGISTRY); if (! NT_SUCCESS(Status)) { DPRINT1("No InstalledDisplayDrivers value in service entry found\n"); return FALSE; } - - DPRINT("DriverFileNames %S\n", DriverFileNames->Buffer); + + RtlInitUnicodeString(DriverFileNames, DriverNames); + DriverFileNames->Length = Length; + DriverFileNames->MaximumLength = Length; + //DPRINT1("DriverFileNames %wZ\n", DriverFileNames); return TRUE; } @@ -301,7 +343,7 @@ IntPrepareDriver(VOID) continue; } - DPRINT("Display driver %S loaded\n", CurrentName); + DPRINT1("Display driver %S loaded\n", CurrentName); ExFreePoolWithTag(DriverFileNames.Buffer, TAG_RTLREGISTRY); From db54713b7373c4a46c51a241b60f91261057c891 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Thu, 11 Mar 2010 17:49:44 +0000 Subject: [PATCH 45/64] [WIN32K]: EngCreateBitmap/IntCreateBitmap don't make much sense (code written back in 2004...). RLEs don't have scanlines by definitions, bit depth alignments and sizing is not done, newer display formats (compressed) are not supported correctly, zero-width surfaces fail because the size is ignored during scanline calculation, etc. These bugs caused eVb's test VGA display driver to fail as it needs to create a zero-depth shadow surface, which would end up with pv0Bits == NULL in the current implementation (and crash during ROPs/BitBLTs). Attempted to rewrite as much of it to 1) make Windows drivers work with it 2) continue the current hacks needed for ReactOS drawing. Note that the broken IntCreateBitmap is still used by non EngXXX interfaces to reduce the change of breakage, but keep in mind the function is entirely wrong. svn path=/trunk/; revision=46104 --- reactos/subsystems/win32/win32k/eng/surface.c | 415 ++++++++++++++---- 1 file changed, 323 insertions(+), 92 deletions(-) diff --git a/reactos/subsystems/win32/win32k/eng/surface.c b/reactos/subsystems/win32/win32k/eng/surface.c index 5dd61387e08..a33cf6f0157 100644 --- a/reactos/subsystems/win32/win32k/eng/surface.c +++ b/reactos/subsystems/win32/win32k/eng/surface.c @@ -332,138 +332,369 @@ IntCreateBitmap(IN SIZEL Size, IN ULONG Flags, IN PVOID Bits) { - HBITMAP hbmp; SURFOBJ *pso; PSURFACE psurf; - PVOID UncompressedBits; - ULONG UncompressedFormat; + SIZEL LocalSize; + ULONG ScanLine = 0; // Compiler is dumb + ULONG BitsSize; + + ScanLine = abs(Width); - if (Format == 0) - return 0; - - psurf = SURFACE_AllocSurfaceWithHandle(); - if (psurf == NULL) + /* Does the device manage its own surface? */ + if (!Bits) { - return 0; - } - hbmp = psurf->BaseObject.hHmgr; - - if (! SURFACE_InitBitsLock(psurf)) - { - SURFACE_UnlockSurface(psurf); - SURFACE_FreeSurfaceByHandle(hbmp); - return 0; - } - pso = &psurf->SurfObj; - - if (Format == BMF_4RLE) - { - pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_4BPP)); - pso->cjBits = pso->lDelta * Size.cy; - UncompressedFormat = BMF_4BPP; - UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB); - Decompress4bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta); - } - else if (Format == BMF_8RLE) - { - pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_8BPP)); - pso->cjBits = pso->lDelta * Size.cy; - UncompressedFormat = BMF_8BPP; - UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB); - Decompress8bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta); - } - else - { - pso->lDelta = abs(Width); - pso->cjBits = pso->lDelta * Size.cy; - UncompressedBits = Bits; - UncompressedFormat = Format; - } - - if (UncompressedBits != NULL) - { - pso->pvBits = UncompressedBits; - } - else - { - if (pso->cjBits == 0) + /* The height times the bytes for each scanline */ + BitsSize = Size.cy * ScanLine; + if (BitsSize) { - pso->pvBits = NULL; - } - else - { - if (0 != (Flags & BMF_USERMEM)) + /* Check for allocation flag */ + if (Flags & BMF_USERMEM) { - pso->pvBits = EngAllocUserMem(pso->cjBits, 0); + /* Get the bits from user-mode memory */ + Bits = EngAllocUserMem(BitsSize, 'mbuG'); } else { - pso->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ? - 0 : FL_ZERO_MEMORY, - pso->cjBits, TAG_DIB); - } - if (pso->pvBits == NULL) - { - SURFACE_UnlockSurface(psurf); - SURFACE_FreeSurfaceByHandle(hbmp); - SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); - return 0; + /* Get kernel bits (zeroed out if requested) */ + Bits = EngAllocMem((Flags & BMF_NOZEROINIT) ? 0 : FL_ZERO_MEMORY, + BitsSize, + TAG_DIB); } + + /* Bail out if that failed */ + if (!Bits) return NULL; } } - - if (0 == (Flags & BMF_TOPDOWN)) - { - pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - pso->lDelta); - pso->lDelta = - pso->lDelta; - } else { - pso->pvScan0 = pso->pvBits; + /* Should not have asked for user memory */ +// ASSERT((Flags & BMF_USERMEM) == 0); } - pso->dhsurf = 0; /* device managed surface */ - pso->hsurf = (HSURF)hbmp; + /* Allocate the actual surface object structure */ + psurf = SURFACE_AllocSurfaceWithHandle(); + if (!psurf) return NULL; + + /* Lock down the surface */ + if (!SURFACE_InitBitsLock(psurf)) + { + /* Bail out if that failed */ + SURFACE_UnlockSurface(psurf); + SURFACE_FreeSurface(psurf); + return NULL; + } + + /* We should now have our surface object */ + pso = &psurf->SurfObj; + + /* Set bits */ + pso->pvBits = Bits; + + /* Number of bits is based on the height times the scanline */ + pso->cjBits = Size.cy * ScanLine; + if (Flags & BMF_TOPDOWN) + { + /* For topdown, the base address starts with the bits */ + pso->pvScan0 = pso->pvBits; + pso->lDelta = ScanLine; + } + else + { + /* Otherwise we start with the end and go up */ + pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ScanLine); + pso->lDelta = -ScanLine; + } + + /* Save format and flags */ + pso->iBitmapFormat = Format; + pso->fjBitmap = Flags & (BMF_TOPDOWN | BMF_UMPDMEM | BMF_USERMEM); + + /* Save size and type */ + LocalSize.cx = Size.cx; + LocalSize.cy = Size.cy; + pso->sizlBitmap = Size; + pso->iType = STYPE_BITMAP; + + /* Device-managed surface, no flags or dimension */ + pso->dhsurf = 0; pso->dhpdev = NULL; pso->hdev = NULL; - pso->sizlBitmap = Size; - pso->iBitmapFormat = UncompressedFormat; - pso->iType = STYPE_BITMAP; - pso->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT); - pso->iUniq = 0; - - psurf->flHooks = 0; psurf->flFlags = 0; psurf->dimension.cx = 0; psurf->dimension.cy = 0; - psurf->hSecure = NULL; psurf->hDIBSection = NULL; + psurf->flHooks = 0; + + /* Finally set the handle and uniq */ + pso->hsurf = (HSURF)psurf->BaseObject.hHmgr; + pso->iUniq = 0; + + /* Unlock and return the surface */ SURFACE_UnlockSurface(psurf); + return pso->hsurf; +} - return hbmp; +/* Name gleaned from C++ symbol information for SURFMEM::bInitDIB */ +typedef struct _DEVBITMAPINFO +{ + ULONG Format; + ULONG Width; + ULONG Height; + ULONG Flags; + ULONG Size; +} DEVBITMAPINFO, *PDEVBITMAPINFO; + +SURFOBJ* +FASTCALL +SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo, + IN PVOID Bits) +{ + BOOLEAN Compressed = FALSE; + ULONG ScanLine = 0; // Compiler is dumb + ULONG Size; + SURFOBJ *pso; + PSURFACE psurf; + SIZEL LocalSize; + + /* + * First, check the format so we can get the aligned scanline width. + * RLE and the newer fancy-smanshy JPG/PNG support do NOT have scanlines + * since they are compressed surfaces! + */ + switch (BitmapInfo->Format) + { + case BMF_1BPP: + //ScanLine = ((BitmapInfo->Width + 31) & ~31) / 8; + break; + + case BMF_4BPP: + //ScanLine = ((BitmapInfo->Width + 7) & ~7) / 2; + break; + + case BMF_8BPP: + //ScanLine = ((BitmapInfo->Width + 3) & ~3); + break; + + case BMF_16BPP: + //ScanLine = ((BitmapInfo->Width + 1) & ~1) * 2; + break; + + case BMF_24BPP: + //ScanLine = ((BitmapInfo->Width * 3) + 3) & ~3; + break; + + case BMF_32BPP: + // ScanLine = BitmapInfo->Width * 4; + break; + + case BMF_8RLE: + case BMF_4RLE: + case BMF_JPEG: + case BMF_PNG: + Compressed = TRUE; + break; + + default: + DPRINT1("Invalid bitmap format\n"); + return NULL; + } + + ScanLine = BitmapInfo->Width; + + /* Does the device manage its own surface? */ + if (!Bits) + { + /* We need to allocate bits for the caller, figure out the size */ + if (Compressed) + { + /* Note: we should not be seeing this scenario from ENGDDI */ + ASSERT(FALSE); + Size = BitmapInfo->Size; + } + else + { + /* The height times the bytes for each scanline */ + Size = BitmapInfo->Height * ScanLine; + } + + if (Size) + { + /* Check for allocation flag */ + if (BitmapInfo->Flags & BMF_USERMEM) + { + /* Get the bits from user-mode memory */ + Bits = EngAllocUserMem(Size, 'mbuG'); + } + else + { + /* Get kernel bits (zeroed out if requested) */ + Bits = EngAllocMem((BitmapInfo->Flags & BMF_NOZEROINIT) ? 0 : FL_ZERO_MEMORY, + Size, + TAG_DIB); + } + + /* Bail out if that failed */ + if (!Bits) return NULL; + } + } + else + { + /* Should not have asked for user memory */ + ASSERT((BitmapInfo->Flags & BMF_USERMEM) == 0); + } + + /* Allocate the actual surface object structure */ + psurf = SURFACE_AllocSurfaceWithHandle(); + if (!psurf) return NULL; + + /* Lock down the surface */ + if (!SURFACE_InitBitsLock(psurf)) + { + /* Bail out if that failed */ + SURFACE_UnlockSurface(psurf); + SURFACE_FreeSurface(psurf); + return NULL; + } + + /* We should now have our surface object */ + pso = &psurf->SurfObj; + + /* Save format and flags */ + pso->iBitmapFormat = BitmapInfo->Format; + pso->fjBitmap = BitmapInfo->Flags & (BMF_TOPDOWN | BMF_UMPDMEM | BMF_USERMEM); + + /* Save size and type */ + LocalSize.cy = BitmapInfo->Height; + LocalSize.cx = BitmapInfo->Width; + pso->sizlBitmap = LocalSize; + pso->iType = STYPE_BITMAP; + + /* Device-managed surface, no flags or dimension */ + pso->dhsurf = 0; + pso->dhpdev = NULL; + pso->hdev = NULL; + psurf->flFlags = 0; + psurf->dimension.cx = 0; + psurf->dimension.cy = 0; + psurf->hSecure = NULL; + psurf->hDIBSection = NULL; + psurf->flHooks = 0; + + /* Set bits */ + pso->pvBits = Bits; + + /* Check for bitmap type */ + if (!Compressed) + { + /* Number of bits is based on the height times the scanline */ + pso->cjBits = BitmapInfo->Height * ScanLine; + if (BitmapInfo->Flags & BMF_TOPDOWN) + { + /* For topdown, the base address starts with the bits */ + pso->pvScan0 = pso->pvBits; + pso->lDelta = ScanLine; + } + else + { + /* Otherwise we start with the end and go up */ + pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ScanLine); + pso->lDelta = -ScanLine; + } + } + else + { + /* Compressed surfaces don't have scanlines! */ + ASSERT(FALSE); // Should not get here on ENGDDI + pso->lDelta = 0; + pso->cjBits = BitmapInfo->Size; + + /* Check for JPG or PNG */ + if ((BitmapInfo->Format != BMF_JPEG) && (BitmapInfo->Format != BMF_PNG)) + { + /* Wherever the bit data is */ + pso->pvScan0 = pso->pvBits; + } + else + { + /* Fancy formats don't use a base address */ + pso->pvScan0 = NULL; + ASSERT(FALSE); // ENGDDI shouldn't be creating PNGs for drivers ;-) + } + } + + /* Finally set the handle and uniq */ + pso->hsurf = (HSURF)psurf->BaseObject.hHmgr; + pso->iUniq = 0; + + /* Unlock and return the surface */ + SURFACE_UnlockSurface(psurf); + return pso; } /* * @implemented */ -HBITMAP APIENTRY +HBITMAP +APIENTRY EngCreateBitmap(IN SIZEL Size, IN LONG Width, IN ULONG Format, IN ULONG Flags, IN PVOID Bits) { - HBITMAP hNewBitmap; + SURFOBJ* Surface; + DEVBITMAPINFO BitmapInfo; + + /* Capture the parameters */ + BitmapInfo.Format = Format; + BitmapInfo.Width = Size.cx; + BitmapInfo.Height = Size.cy; + BitmapInfo.Flags = Flags; - hNewBitmap = IntCreateBitmap(Size, Width, Format, Flags, Bits); - if ( !hNewBitmap ) - return 0; + /* + * If the display driver supports framebuffer access, use the scanline width + * to determine the actual width of the bitmap, and convert it to pels instead + * of bytes. + */ + if ((Bits) && (Width)) + { + #if 0 + switch (BitmapInfo.Format) + { + /* Do the conversion for each bit depth we support */ + case BMF_1BPP: + BitmapInfo.Width = Width * 8; + break; + case BMF_4BPP: + BitmapInfo.Width = Width * 2; + break; + case BMF_8BPP: + BitmapInfo.Width = Width; + break; + case BMF_16BPP: + BitmapInfo.Width = Width / 2; + break; + case BMF_24BPP: + BitmapInfo.Width = Width / 3; + break; + case BMF_32BPP: + BitmapInfo.Width = Width / 4; + break; + } +#endif + BitmapInfo.Width = Width; - GDIOBJ_SetOwnership(hNewBitmap, NULL); + } + + /* Now create the surface */ + Surface = SURFMEM_bCreateDib(&BitmapInfo, Bits); + if (!Surface) return 0; - return hNewBitmap; + /* Set public ownership and reutrn the handle */ + GDIOBJ_SetOwnership(Surface->hsurf, NULL); + return Surface->hsurf; } /* From ceb6085aa0750a60312dcb61cad56d341605c9af Mon Sep 17 00:00:00 2001 From: evb Date: Thu, 11 Mar 2010 17:56:27 +0000 Subject: [PATCH 46/64] - Added support IOCTRL_QUERY_PUBLIC_ACCESS_RANGES, IOCTRL_SET_PALETTE_REGISTERS, IOCTRL_QUERY_CURRENT_MODE, used by test Standard VGA-only display driver. - Code from NT4 DDK Cirrus miniport with some mods by me. svn path=/trunk/; revision=46106 --- .../drivers/video/miniport/vga_new/modeset.c | 141 +++++++++++++++ reactos/drivers/video/miniport/vga_new/vga.c | 163 +++++++++++++++++- 2 files changed, 300 insertions(+), 4 deletions(-) diff --git a/reactos/drivers/video/miniport/vga_new/modeset.c b/reactos/drivers/video/miniport/vga_new/modeset.c index 83c00011a88..abe1191a8a9 100644 --- a/reactos/drivers/video/miniport/vga_new/modeset.c +++ b/reactos/drivers/video/miniport/vga_new/modeset.c @@ -41,6 +41,14 @@ VgaQueryNumberOfAvailableModes( PULONG OutputSize ); +VP_STATUS +VgaQueryCurrentMode( + PHW_DEVICE_EXTENSION HwDeviceExtension, + PVIDEO_MODE_INFORMATION ModeInformation, + ULONG ModeInformationSize, + PULONG OutputSize + ); + VOID VgaZeroVideoMemory( PHW_DEVICE_EXTENSION HwDeviceExtension @@ -696,6 +704,139 @@ Return Value: return NO_ERROR; } // end VgaGetNumberOfAvailableModes() + +VP_STATUS +VgaQueryCurrentMode( + PHW_DEVICE_EXTENSION HwDeviceExtension, + PVIDEO_MODE_INFORMATION ModeInformation, + ULONG ModeInformationSize, + PULONG OutputSize + ) + +/*++ + +Routine Description: + + This routine returns a description of the current video mode. + +Arguments: + + HwDeviceExtension - Pointer to the miniport driver's device extension. + + ModeInformation - Pointer to the output buffer supplied by the user. + This is where the current mode information is stored. + + ModeInformationSize - Length of the output buffer supplied by the user. + + OutputSize - Pointer to a buffer in which to return the actual size of + the data in the buffer. If the buffer was not large enough, this + contains the minimum required buffer size. + +Return Value: + + ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough + for the data being returned. + + NO_ERROR if the operation completed successfully. + +--*/ + +{ + // + // check if a mode has been set + // + + if (HwDeviceExtension->CurrentMode == NULL ) { + + return ERROR_INVALID_FUNCTION; + + } + + // + // Find out the size of the data to be put in the the buffer and return + // that in the status information (whether or not the information is + // there). If the buffer passed in is not large enough return an + // appropriate error code. + // + + if (ModeInformationSize < (*OutputSize = sizeof(VIDEO_MODE_INFORMATION))) { + + return ERROR_INSUFFICIENT_BUFFER; + + } + + // + // Store the characteristics of the current mode into the buffer. + // + + ModeInformation->Length = sizeof(VIDEO_MODE_INFORMATION); + ModeInformation->ModeIndex = HwDeviceExtension->ModeIndex; + ModeInformation->VisScreenWidth = HwDeviceExtension->CurrentMode->hres; + ModeInformation->ScreenStride = HwDeviceExtension->CurrentMode->wbytes; + ModeInformation->VisScreenHeight = HwDeviceExtension->CurrentMode->vres; + ModeInformation->NumberOfPlanes = HwDeviceExtension->CurrentMode->numPlanes; + ModeInformation->BitsPerPlane = HwDeviceExtension->CurrentMode->bitsPerPlane; + ModeInformation->Frequency = HwDeviceExtension->CurrentMode->Frequency; + ModeInformation->XMillimeter = 320; // temporary hardcoded constant + ModeInformation->YMillimeter = 240; // temporary hardcoded constant + + ModeInformation->AttributeFlags = HwDeviceExtension->CurrentMode->fbType; + + if ((ModeInformation->BitsPerPlane == 32) || + (ModeInformation->BitsPerPlane == 24)) + { + + ModeInformation->NumberRedBits = 8; + ModeInformation->NumberGreenBits = 8; + ModeInformation->NumberBlueBits = 8; + ModeInformation->RedMask = 0xff0000; + ModeInformation->GreenMask = 0x00ff00; + ModeInformation->BlueMask = 0x0000ff; + + } + else if (ModeInformation->BitsPerPlane == 16) + { + + ModeInformation->NumberRedBits = 6; + ModeInformation->NumberGreenBits = 6; + ModeInformation->NumberBlueBits = 6; + ModeInformation->RedMask = 0x1F << 11; + ModeInformation->GreenMask = 0x3F << 5; + ModeInformation->BlueMask = 0x1F; + + } +// eVb: 2.12 [VGA] - Add support for 15bpp modes, which Cirrus doesn't support + else if (ModeInformation->BitsPerPlane == 15) + { + + ModeInformation->NumberRedBits = 6; + ModeInformation->NumberGreenBits = 6; + ModeInformation->NumberBlueBits = 6; + ModeInformation->RedMask = 0x3E << 9; + ModeInformation->GreenMask = 0x1F << 5; + ModeInformation->BlueMask = 0x1F; + } +// eVb: 2.12 [END] + else + { + + ModeInformation->NumberRedBits = 6; + ModeInformation->NumberGreenBits = 6; + ModeInformation->NumberBlueBits = 6; + ModeInformation->RedMask = 0; + ModeInformation->GreenMask = 0; + ModeInformation->BlueMask = 0; + } + +// eVb: 2.13 [VGA] - All modes are palette managed/driven, unlike Cirrus + ModeInformation->AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN | + VIDEO_MODE_MANAGED_PALETTE; +// eVb: 2.13 [END] + + return NO_ERROR; + +} // end VgaQueryCurrentMode() + VOID VgaZeroVideoMemory( diff --git a/reactos/drivers/video/miniport/vga_new/vga.c b/reactos/drivers/video/miniport/vga_new/vga.c index 5b59b53624a..a97c64bdecd 100644 --- a/reactos/drivers/video/miniport/vga_new/vga.c +++ b/reactos/drivers/video/miniport/vga_new/vga.c @@ -58,6 +58,14 @@ VgaQueryNumberOfAvailableModes( PULONG OutputSize ); +VP_STATUS +VgaQueryCurrentMode( + PHW_DEVICE_EXTENSION HwDeviceExtension, + PVIDEO_MODE_INFORMATION ModeInformation, + ULONG ModeInformationSize, + PULONG OutputSize + ); + VP_STATUS VgaSetMode( PHW_DEVICE_EXTENSION HwDeviceExtension, @@ -79,6 +87,13 @@ VgaInterpretCmdStream( PUSHORT pusCmdStream ); +VP_STATUS +VgaSetPaletteReg( + PHW_DEVICE_EXTENSION HwDeviceExtension, + PVIDEO_PALETTE_DATA PaletteBuffer, + ULONG PaletteBufferSize + ); + VP_STATUS VgaSetColorLookup( PHW_DEVICE_EXTENSION HwDeviceExtension, @@ -394,7 +409,7 @@ Return Value: VGA_MAX_IO_PORT - VGA_BASE_IO_PORT + 1, VgaAccessRange->RangeInIoSpace)) == NULL) { - VideoDebugPrint((2, "VgaFindAdapter - Fail to get io address\n")); + VideoDebugPrint((0, "VgaFindAdapter - Fail to get io address\n")); return ERROR_INVALID_PARAMETER; } @@ -445,7 +460,7 @@ Return Value: VgaAccessRange[2].RangeLength, FALSE)) == NULL) { - VideoDebugPrint((1, "VgaFindAdapter - Fail to get memory address\n")); + VideoDebugPrint((0, "VgaFindAdapter - Fail to get memory address\n")); return ERROR_INVALID_PARAMETER; } @@ -681,7 +696,10 @@ Return Value: VideoDebugPrint((2, "VgaStartIO - QueryCurrentMode\n")); - status = ERROR_INVALID_FUNCTION; + status = VgaQueryCurrentMode(HwDeviceExtension, + (PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer, + RequestPacket->OutputBufferLength, + &RequestPacket->StatusBlock->Information); break; @@ -775,7 +793,9 @@ Return Value: VideoDebugPrint((2, "VgaStartIO - SetPaletteRegs\n")); - status = ERROR_INVALID_FUNCTION; + status = VgaSetPaletteReg(HwDeviceExtension, + (PVIDEO_PALETTE_DATA) RequestPacket->InputBuffer, + RequestPacket->InputBufferLength); break; @@ -825,8 +845,53 @@ Return Value: break; case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES: + { + VideoDebugPrint((2, "VgaStartIO - Query Public Address Ranges\n")); + + PVIDEO_PUBLIC_ACCESS_RANGES portAccess; + ULONG physicalPortLength; + + if (RequestPacket->OutputBufferLength < + sizeof(VIDEO_PUBLIC_ACCESS_RANGES)) + { + status = ERROR_INSUFFICIENT_BUFFER; + break; + } + + RequestPacket->StatusBlock->Information = + sizeof(VIDEO_PUBLIC_ACCESS_RANGES); + + portAccess = RequestPacket->OutputBuffer; + + // + // The first public access range is the IO ports. + // + + portAccess->VirtualAddress = (PVOID) NULL; + portAccess->InIoSpace = TRUE; + portAccess->MappedInIoSpace = portAccess->InIoSpace; + physicalPortLength = VGA_MAX_IO_PORT - VGA_BASE_IO_PORT + 1; + + status = VideoPortMapMemory(hwDeviceExtension, + VgaAccessRange->RangeStart, + &physicalPortLength, + &(portAccess->MappedInIoSpace), + &(portAccess->VirtualAddress)); +// eVb: 1.17 [GCG] - Fix lvalue error + portAccess->VirtualAddress = (PVOID)((ULONG_PTR)portAccess->VirtualAddress - VGA_BASE_IO_PORT); +// eVb: 1.17 [END] + VideoDebugPrint((2, "VgaStartIO - mapping ports to (%x)\n", portAccess->VirtualAddress)); + } + + break; + case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES: + VideoDebugPrint((2, "VgaStartIO - Free Public Access Ranges\n")); + + status = ERROR_INVALID_FUNCTION; + break; + // // if we get here, an invalid IoControlCode was specified. // @@ -1180,6 +1245,96 @@ Return Value: } // VgaIsPresent() +//--------------------------------------------------------------------------- +VP_STATUS +VgaSetPaletteReg( + PHW_DEVICE_EXTENSION HwDeviceExtension, + PVIDEO_PALETTE_DATA PaletteBuffer, + ULONG PaletteBufferSize + ) + +/*++ + +Routine Description: + + This routine sets a specified portion of the EGA (not DAC) palette + registers. + +Arguments: + + HwDeviceExtension - Pointer to the miniport driver's device extension. + + PaletteBuffer - Pointer to the structure containing the palette data. + + PaletteBufferSize - Length of the input buffer supplied by the user. + +Return Value: + + NO_ERROR - information returned successfully + + ERROR_INSUFFICIENT_BUFFER - input buffer not large enough for input data. + + ERROR_INVALID_PARAMETER - invalid palette size. + +--*/ + +{ + USHORT i; + + // + // Check if the size of the data in the input buffer is large enough. + // + + if ((PaletteBufferSize) < (sizeof(VIDEO_PALETTE_DATA)) || + (PaletteBufferSize < (sizeof(VIDEO_PALETTE_DATA) + + (sizeof(USHORT) * (PaletteBuffer->NumEntries -1)) ))) { + + return ERROR_INSUFFICIENT_BUFFER; + + } + + // + // Check to see if the parameters are valid. + // + + if ( (PaletteBuffer->FirstEntry > VIDEO_MAX_COLOR_REGISTER ) || + (PaletteBuffer->NumEntries == 0) || + (PaletteBuffer->FirstEntry + PaletteBuffer->NumEntries > + VIDEO_MAX_PALETTE_REGISTER + 1 ) ) { + + return ERROR_INVALID_PARAMETER; + + } + + // + // Reset ATC to index mode + // + + VideoPortReadPortUchar(HwDeviceExtension->IOAddress + + ATT_INITIALIZE_PORT_COLOR); + + // + // Blast out our palette values. + // + + for (i = 0; i < PaletteBuffer->NumEntries; i++) { + + VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_ADDRESS_PORT, + (UCHAR)(i+PaletteBuffer->FirstEntry)); + + VideoPortWritePortUchar(HwDeviceExtension->IOAddress + + ATT_DATA_WRITE_PORT, + (UCHAR)PaletteBuffer->Colors[i]); + } + + VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_ADDRESS_PORT, + VIDEO_ENABLE); + + return NO_ERROR; + +} // end VgaSetPaletteReg() + + //--------------------------------------------------------------------------- VP_STATUS VgaSetColorLookup( From 24d4f279bf6fb99d03bde44eb1ea966caeabe77f Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Thu, 11 Mar 2010 18:19:02 +0000 Subject: [PATCH 47/64] [FRAMEBUF]: Use precompiled header. svn path=/trunk/; revision=46107 --- reactos/drivers/video/displays/framebuf_new/framebuf_new.rbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/drivers/video/displays/framebuf_new/framebuf_new.rbuild b/reactos/drivers/video/displays/framebuf_new/framebuf_new.rbuild index c334ac9ac4a..991954e44e2 100644 --- a/reactos/drivers/video/displays/framebuf_new/framebuf_new.rbuild +++ b/reactos/drivers/video/displays/framebuf_new/framebuf_new.rbuild @@ -15,4 +15,5 @@ -fno-builtin -Wno-unused-variable + driver.h From f34091b0e882a5a0ca4ff6cef8fadd313111c060 Mon Sep 17 00:00:00 2001 From: evb Date: Thu, 11 Mar 2010 18:19:58 +0000 Subject: [PATCH 48/64] - Remove bits saying dithering supported, since code patented and removed (also, ReactOS win32k not support dithering calls!). svn path=/trunk/; revision=46108 --- .../drivers/video/displays/framebuf_new/screen.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/reactos/drivers/video/displays/framebuf_new/screen.c b/reactos/drivers/video/displays/framebuf_new/screen.c index 1973c580866..7ea4443c323 100755 --- a/reactos/drivers/video/displays/framebuf_new/screen.c +++ b/reactos/drivers/video/displays/framebuf_new/screen.c @@ -17,15 +17,18 @@ const DEVINFO gDevInfoFrameBuffer = { ( GCAPS_OPAQUERECT - | GCAPS_MONO_DITHER +// eVb: 2.8 [DDK CHANGE] - No dithering support +// eVb: 2.8 [END] ), /* Graphics capabilities */ SYSTM_LOGFONT, /* Default font description */ HELVE_LOGFONT, /* ANSI variable font description */ COURI_LOGFONT, /* ANSI fixed font description */ 0, /* Count of device fonts */ 0, /* Preferred DIB format */ - 8, /* Width of color dither */ - 8, /* Height of color dither */ +// eVb: 2.9 [DDK CHANGE] - No dithering support + 0, /* Width of color dither */ + 0, /* Height of color dither */ +// eVb: 2.9 [END] 0 /* Default palette to use for this device */ }; @@ -449,9 +452,9 @@ DEVINFO *pDevInfo) pGdiInfo->ulNumColors = 20; pGdiInfo->ulNumPalReg = 1 << ppdev->ulBitCount; - - pDevInfo->flGraphicsCaps |= (GCAPS_PALMANAGED | GCAPS_COLOR_DITHER); - +// eVb: 2.7 [DDK CHANGE] - No dithering support + pDevInfo->flGraphicsCaps |= GCAPS_PALMANAGED; +// eVb: 2.7 [END] pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP; pDevInfo->iDitherFormat = BMF_8BPP; From c97215f5d4a2964eadbe126e47868162a784d189 Mon Sep 17 00:00:00 2001 From: Kamil Hornicek Date: Thu, 11 Mar 2010 18:40:26 +0000 Subject: [PATCH 49/64] - fix build svn path=/trunk/; revision=46109 --- reactos/dll/win32/gdi32/include/gdi32p.h | 4 ---- reactos/dll/win32/gdi32/misc/stubs.c | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/reactos/dll/win32/gdi32/include/gdi32p.h b/reactos/dll/win32/gdi32/include/gdi32p.h index 3bcf6f1454f..f45a0ddd171 100644 --- a/reactos/dll/win32/gdi32/include/gdi32p.h +++ b/reactos/dll/win32/gdi32/include/gdi32p.h @@ -233,10 +233,6 @@ ConvertBitmapInfo( BOOL FollowedByData ); -DEVMODEW * -NTAPI -GdiConvertToDevmodeW(DEVMODEA *dm); - DWORD WINAPI GetAndSetDCDWord( HDC, INT, DWORD, DWORD, DWORD, DWORD ); diff --git a/reactos/dll/win32/gdi32/misc/stubs.c b/reactos/dll/win32/gdi32/misc/stubs.c index 19e1e770d06..5dc10b33284 100644 --- a/reactos/dll/win32/gdi32/misc/stubs.c +++ b/reactos/dll/win32/gdi32/misc/stubs.c @@ -1353,7 +1353,7 @@ GdiConvertMetaFilePict(HGLOBAL hMem) */ DEVMODEW * WINAPI -GdiConvertToDevmodeW(DEVMODEA *dmA) +GdiConvertToDevmodeW(const DEVMODEA *dmA) { DEVMODEW *dmW; WORD dmW_size, dmA_size; From 7d5400708443f276a83c4af782c764850a002bd6 Mon Sep 17 00:00:00 2001 From: Kamil Hornicek Date: Thu, 11 Mar 2010 18:48:46 +0000 Subject: [PATCH 50/64] - missed this one.. fix build? svn path=/trunk/; revision=46110 --- reactos/dll/win32/user32/include/user32p.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/reactos/dll/win32/user32/include/user32p.h b/reactos/dll/win32/user32/include/user32p.h index abf6843f40d..31f38a1a7db 100644 --- a/reactos/dll/win32/user32/include/user32p.h +++ b/reactos/dll/win32/user32/include/user32p.h @@ -128,10 +128,6 @@ typedef struct _USER32_THREAD_DATA PUSER32_THREAD_DATA User32GetThreadData(); -DEVMODEW * -WINAPI -GdiConvertToDevmodeW(DEVMODEA *dm); - /* FIXME: Belongs to some header. */ BOOL WINAPI GdiDllInitialize(HANDLE, DWORD, LPVOID); void InitStockObjects(void); From a17ba7f9af21a73dd2682c5e4b9e94837698d08c Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Thu, 11 Mar 2010 19:26:00 +0000 Subject: [PATCH 51/64] [WIN32K]: Revert accidental changes to IntCreateBitmap. svn path=/trunk/; revision=46111 --- reactos/subsystems/win32/win32k/eng/surface.c | 161 +++++++++--------- 1 file changed, 85 insertions(+), 76 deletions(-) diff --git a/reactos/subsystems/win32/win32k/eng/surface.c b/reactos/subsystems/win32/win32k/eng/surface.c index a33cf6f0157..423972ce3fb 100644 --- a/reactos/subsystems/win32/win32k/eng/surface.c +++ b/reactos/subsystems/win32/win32k/eng/surface.c @@ -332,108 +332,117 @@ IntCreateBitmap(IN SIZEL Size, IN ULONG Flags, IN PVOID Bits) { + HBITMAP hbmp; SURFOBJ *pso; PSURFACE psurf; - SIZEL LocalSize; - ULONG ScanLine = 0; // Compiler is dumb - ULONG BitsSize; - - ScanLine = abs(Width); + PVOID UncompressedBits; + ULONG UncompressedFormat; - /* Does the device manage its own surface? */ - if (!Bits) + if (Format == 0) + return 0; + + psurf = SURFACE_AllocSurfaceWithHandle(); + if (psurf == NULL) { - /* The height times the bytes for each scanline */ - BitsSize = Size.cy * ScanLine; - if (BitsSize) + return 0; + } + hbmp = psurf->BaseObject.hHmgr; + + if (! SURFACE_InitBitsLock(psurf)) + { + SURFACE_UnlockSurface(psurf); + SURFACE_FreeSurfaceByHandle(hbmp); + return 0; + } + pso = &psurf->SurfObj; + + if (Format == BMF_4RLE) + { + pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_4BPP)); + pso->cjBits = pso->lDelta * Size.cy; + UncompressedFormat = BMF_4BPP; + UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB); + Decompress4bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta); + } + else if (Format == BMF_8RLE) + { + pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_8BPP)); + pso->cjBits = pso->lDelta * Size.cy; + UncompressedFormat = BMF_8BPP; + UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB); + Decompress8bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta); + } + else + { + pso->lDelta = abs(Width); + pso->cjBits = pso->lDelta * Size.cy; + UncompressedBits = Bits; + UncompressedFormat = Format; + } + + if (UncompressedBits != NULL) + { + pso->pvBits = UncompressedBits; + } + else + { + if (pso->cjBits == 0) { - /* Check for allocation flag */ - if (Flags & BMF_USERMEM) + pso->pvBits = NULL; + } + else + { + if (0 != (Flags & BMF_USERMEM)) { - /* Get the bits from user-mode memory */ - Bits = EngAllocUserMem(BitsSize, 'mbuG'); + pso->pvBits = EngAllocUserMem(pso->cjBits, 0); } else { - /* Get kernel bits (zeroed out if requested) */ - Bits = EngAllocMem((Flags & BMF_NOZEROINIT) ? 0 : FL_ZERO_MEMORY, - BitsSize, - TAG_DIB); + pso->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ? + 0 : FL_ZERO_MEMORY, + pso->cjBits, TAG_DIB); + } + if (pso->pvBits == NULL) + { + SURFACE_UnlockSurface(psurf); + SURFACE_FreeSurfaceByHandle(hbmp); + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return 0; } - - /* Bail out if that failed */ - if (!Bits) return NULL; } } + + if (0 == (Flags & BMF_TOPDOWN)) + { + pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - pso->lDelta); + pso->lDelta = - pso->lDelta; + } else { - /* Should not have asked for user memory */ -// ASSERT((Flags & BMF_USERMEM) == 0); - } - - /* Allocate the actual surface object structure */ - psurf = SURFACE_AllocSurfaceWithHandle(); - if (!psurf) return NULL; - - /* Lock down the surface */ - if (!SURFACE_InitBitsLock(psurf)) - { - /* Bail out if that failed */ - SURFACE_UnlockSurface(psurf); - SURFACE_FreeSurface(psurf); - return NULL; - } - - /* We should now have our surface object */ - pso = &psurf->SurfObj; - - /* Set bits */ - pso->pvBits = Bits; - - /* Number of bits is based on the height times the scanline */ - pso->cjBits = Size.cy * ScanLine; - if (Flags & BMF_TOPDOWN) - { - /* For topdown, the base address starts with the bits */ pso->pvScan0 = pso->pvBits; - pso->lDelta = ScanLine; - } - else - { - /* Otherwise we start with the end and go up */ - pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ScanLine); - pso->lDelta = -ScanLine; } - /* Save format and flags */ - pso->iBitmapFormat = Format; - pso->fjBitmap = Flags & (BMF_TOPDOWN | BMF_UMPDMEM | BMF_USERMEM); - - /* Save size and type */ - LocalSize.cx = Size.cx; - LocalSize.cy = Size.cy; - pso->sizlBitmap = Size; - pso->iType = STYPE_BITMAP; - - /* Device-managed surface, no flags or dimension */ - pso->dhsurf = 0; + pso->dhsurf = 0; /* device managed surface */ + pso->hsurf = (HSURF)hbmp; pso->dhpdev = NULL; pso->hdev = NULL; + pso->sizlBitmap = Size; + pso->iBitmapFormat = UncompressedFormat; + pso->iType = STYPE_BITMAP; + pso->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT); + pso->iUniq = 0; + + psurf->flHooks = 0; psurf->flFlags = 0; psurf->dimension.cx = 0; psurf->dimension.cy = 0; + psurf->hSecure = NULL; psurf->hDIBSection = NULL; - psurf->flHooks = 0; - - /* Finally set the handle and uniq */ - pso->hsurf = (HSURF)psurf->BaseObject.hHmgr; - pso->iUniq = 0; - - /* Unlock and return the surface */ SURFACE_UnlockSurface(psurf); - return pso->hsurf; + + return hbmp; } /* Name gleaned from C++ symbol information for SURFMEM::bInitDIB */ From 366641540062149b82ca2d3af5edef1b16d8e98e Mon Sep 17 00:00:00 2001 From: Kamil Hornicek Date: Thu, 11 Mar 2010 19:42:59 +0000 Subject: [PATCH 52/64] [SHELL32] - according to msdn ppidl should be set to NULL if an error occurs - fixes shlfolder winetest crash svn path=/trunk/; revision=46112 --- reactos/dll/win32/shell32/shellord.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/shell32/shellord.c b/reactos/dll/win32/shell32/shellord.c index 05adda5c5b3..ff9025c4e0e 100644 --- a/reactos/dll/win32/shell32/shellord.c +++ b/reactos/dll/win32/shell32/shellord.c @@ -2244,12 +2244,21 @@ LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut) HRESULT hr=E_FAIL; ULONG dwAttr=sfgaoIn; - if (!pszName || !ppidl || !psfgaoOut) + if(!ppidl) return E_INVALIDARG; + if (!pszName || !psfgaoOut) + { + *ppidl = NULL; + return E_INVALIDARG; + } + hr = SHGetDesktopFolder(&psfDesktop); if (FAILED(hr)) + { + *ppidl = NULL; return hr; + } hr = IShellFolder_ParseDisplayName(psfDesktop, (HWND)NULL, pbc, (LPOLESTR)pszName, (ULONG *)NULL, ppidl, &dwAttr); @@ -2257,6 +2266,8 @@ LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut) if (SUCCEEDED(hr)) *psfgaoOut = dwAttr; + else + *ppidl = NULL; return hr; } From 05c5b82a0a2e35ae2116e7b11bcafcb8efa8885d Mon Sep 17 00:00:00 2001 From: Dmitry Gorbachev Date: Thu, 11 Mar 2010 20:59:24 +0000 Subject: [PATCH 53/64] Output PCH even when full dependencies are enabled. svn path=/trunk/; revision=46113 --- reactos/tools/rbuild/backend/mingw/compilers/gcc.mak | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/tools/rbuild/backend/mingw/compilers/gcc.mak b/reactos/tools/rbuild/backend/mingw/compilers/gcc.mak index 36857302df9..9769c6d58f2 100644 --- a/reactos/tools/rbuild/backend/mingw/compilers/gcc.mak +++ b/reactos/tools/rbuild/backend/mingw/compilers/gcc.mak @@ -125,7 +125,7 @@ ${call RBUILD_intermediate_dir,$(2)}$$(SEP).gch_$(1)$$(SEP)$(notdir $(2)).gch.d: ${call RBUILD_intermediate_dir,$(2)}$$(SEP).gch_$(1)$$(SEP)$(notdir $(2)).gch: $(2) ${call RBUILD_intermediate_dir,$(2)}$$(SEP).gch_$(1)$$(SEP)$(notdir $(2)).gch.d $(3) | ${call RBUILD_intermediate_dir,$(2)}$$(SEP).gch_$(1) $$(ECHO_PCH) - $${gcc} -MF $$@ ${call RBUILD_cflags,$(1),$(4)} -x c-header -M -MP -MT $$@ $$< + $${gcc} -o $$@ ${call RBUILD_cflags,$(1),$(4)} -x c-header $$< else @@ -152,7 +152,7 @@ ${call RBUILD_intermediate_dir,$(2)}$$(SEP).gch_$(1)$$(SEP)$(notdir $(2)).gch.d: ${call RBUILD_intermediate_dir,$(2)}$$(SEP).gch_$(1)$$(SEP)$(notdir $(2)).gch: $(2) ${call RBUILD_intermediate_dir,$(2)}$$(SEP).gch_$(1)$$(SEP)$(notdir $(2)).gch.d $(3) | ${call RBUILD_intermediate_dir,$(2)}$$(SEP).gch_$(1) $$(ECHO_PCH) - $${gpp} -MF $$@ ${call RBUILD_cxxflags,$(1),$(4)} -x c++-header -M -MP -MT $$@ $$< + $${gpp} -o $$@ ${call RBUILD_cxxflags,$(1),$(4)} -x c++-header $$< else From c785457a1b73830b252256e7fa497f1ed23aa2ab Mon Sep 17 00:00:00 2001 From: Dmitry Gorbachev Date: Thu, 11 Mar 2010 20:59:47 +0000 Subject: [PATCH 54/64] Comment out RegisterServiceProcess' stub. svn path=/trunk/; revision=46114 --- reactos/dll/win32/kernel32/kernel32.pspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/kernel32/kernel32.pspec b/reactos/dll/win32/kernel32/kernel32.pspec index d9622bb715e..1fb88ce3e56 100644 --- a/reactos/dll/win32/kernel32/kernel32.pspec +++ b/reactos/dll/win32/kernel32/kernel32.pspec @@ -732,7 +732,7 @@ @ stdcall RegisterConsoleIME(ptr ptr) @ stdcall RegisterConsoleOS2(long) @ stdcall RegisterConsoleVDM(long long long long long long long long long long long) -@ stub RegisterServiceProcess ; missing in XP SP3 +;@ stub RegisterServiceProcess ; missing in XP SP3 @ stub RegisterSysMsgHandler ; missing in XP SP3 @ stdcall RegisterWaitForInputIdle(ptr) @ stdcall RegisterWaitForSingleObject(ptr long ptr ptr long long) From c506f7fd797716f0cead299ee51826703086b4af Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Thu, 11 Mar 2010 21:15:46 +0000 Subject: [PATCH 55/64] [PSDK] - Add a few types required for ksproxy svn path=/trunk/; revision=46115 --- reactos/include/psdk/ks.h | 160 +++++++++++++++++++++++++++++--------- 1 file changed, 124 insertions(+), 36 deletions(-) diff --git a/reactos/include/psdk/ks.h b/reactos/include/psdk/ks.h index 7384457be1c..a86d4a87c1a 100644 --- a/reactos/include/psdk/ks.h +++ b/reactos/include/psdk/ks.h @@ -501,11 +501,12 @@ typedef enum Properties/Methods/Events */ -#define KSPROPSETID_MediaSeeking \ +#define STATIC_KSPROPSETID_MediaSeeking\ 0xEE904F0CL, 0xD09B, 0x11D0, 0xAB, 0xE9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("EE904F0C-D09B-11D0-ABE9-00A0C9223196", KSPROPSETID_MediaSeeking); +#define KSPROPSETID_MediaSeeking DEFINE_GUIDNAMED(KSPROPSETID_MediaSeeking) -typedef enum -{ +typedef enum { KSPROPERTY_MEDIASEEKING_CAPABILITIES, KSPROPERTY_MEDIASEEKING_FORMATS, KSPROPERTY_MEDIASEEKING_TIMEFORMAT, @@ -518,6 +519,126 @@ typedef enum KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT } KSPROPERTY_MEDIASEEKING; +typedef enum { + KS_SEEKING_NoPositioning, + KS_SEEKING_AbsolutePositioning, + KS_SEEKING_RelativePositioning, + KS_SEEKING_IncrementalPositioning, + KS_SEEKING_PositioningBitsMask = 0x3, + KS_SEEKING_SeekToKeyFrame, + KS_SEEKING_ReturnTime = 0x8 +} KS_SEEKING_FLAGS; + +typedef enum { + KS_SEEKING_CanSeekAbsolute = 0x1, + KS_SEEKING_CanSeekForwards = 0x2, + KS_SEEKING_CanSeekBackwards = 0x4, + KS_SEEKING_CanGetCurrentPos = 0x8, + KS_SEEKING_CanGetStopPos = 0x10, + KS_SEEKING_CanGetDuration = 0x20, + KS_SEEKING_CanPlayBackwards = 0x40 +} KS_SEEKING_CAPABILITIES; + +typedef struct { + LONGLONG Current; + LONGLONG Stop; + KS_SEEKING_FLAGS CurrentFlags; + KS_SEEKING_FLAGS StopFlags; +} KSPROPERTY_POSITIONS, *PKSPROPERTY_POSITIONS; + +typedef struct { + LONGLONG Earliest; + LONGLONG Latest; +} KSPROPERTY_MEDIAAVAILABLE, *PKSPROPERTY_MEDIAAVAILABLE; + +typedef struct { + KSPROPERTY Property; + GUID SourceFormat; + GUID TargetFormat; + LONGLONG Time; +} KSP_TIMEFORMAT, *PKSP_TIMEFORMAT; + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_CAPABILITIES(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_MEDIASEEKING_CAPABILITIES,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(KS_SEEKING_CAPABILITIES),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_FORMATS(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_MEDIASEEKING_FORMATS,\ + (Handler),\ + sizeof(KSPROPERTY),\ + 0,\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_TIMEFORMAT(GetHandler, SetHandler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_MEDIASEEKING_TIMEFORMAT,\ + (GetHandler),\ + sizeof(KSPROPERTY),\ + sizeof(GUID),\ + (SetHandler),\ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_POSITION(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_MEDIASEEKING_POSITION,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(LONGLONG),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_STOPPOSITION(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_MEDIASEEKING_STOPPOSITION,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(LONGLONG),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_POSITIONS(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_MEDIASEEKING_POSITIONS,\ + NULL,\ + sizeof(KSPROPERTY),\ + sizeof(KSPROPERTY_POSITIONS),\ + (Handler),\ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_DURATION(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_MEDIASEEKING_DURATION,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(LONGLONG),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_AVAILABLE(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_MEDIASEEKING_AVAILABLE,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(KSPROPERTY_MEDIAAVAILABLE),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_PREROLL(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_MEDIASEEKING_PREROLL,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(LONGLONG),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_CONVERTTIMEFORMAT(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT,\ + (Handler),\ + sizeof(KSP_TIMEFORMAT),\ + sizeof(LONGLONG),\ + NULL, NULL, 0, NULL, NULL, 0) /* =============================================================== Pin @@ -1383,24 +1504,6 @@ typedef struct #define KSPROPERTY_MEMBER_VALUES 0x00000003 #define KSPROPERTY_MEMBER_FLAG_DEFAULT KSPROPERTY_MEMBER_RANGES -typedef enum { - KS_SEEKING_NoPositioning, - KS_SEEKING_AbsolutePositioning, - KS_SEEKING_RelativePositioning, - KS_SEEKING_IncrementalPositioning, - KS_SEEKING_PositioningBitsMask = 0x3, - KS_SEEKING_SeekToKeyFrame, - KS_SEEKING_ReturnTime = 0x8 -} KS_SEEKING_FLAGS; - -typedef struct -{ - LONGLONG Current; - LONGLONG Stop; - KS_SEEKING_FLAGS CurrentFlags; - KS_SEEKING_FLAGS StopFlags; -} KSPROPERTY_POSITIONS, *PKSPROPERTY_POSITIONS; - typedef struct { GUID PropertySet; @@ -1473,13 +1576,6 @@ typedef struct ULONG Reserved; } KSPROPERTY_DESCRIPTION, *PKSPROPERTY_DESCRIPTION; -typedef struct -{ - LONGLONG Earliest; - LONGLONG Latest; -} KSPROPERTY_MEDIAAVAILABLE, *PKSPROPERTY_MEDIAAVAILABLE; - - typedef struct { ULONG MembersFlags; @@ -1760,14 +1856,6 @@ typedef struct LONGLONG SystemTime; } KSCORRELATED_TIME, *PKSCORRELATED_TIME; -typedef struct -{ - KSPROPERTY Property; - GUID SourceFormat; - GUID TargetFormat; - LONGLONG Time; -} KSP_TIMEFORMAT, *PKSP_TIMEFORMAT; - typedef struct { LONGLONG TimeBase; From 718fb526252de80c6069402d05dc422cda1ce5fc Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Thu, 11 Mar 2010 21:38:13 +0000 Subject: [PATCH 56/64] [KSPROXY] - Recreate resource file with visual studio - Fix compilation with msvc - Copy extra format buffer in IEnumMediaTypes::Next - Create the pin handle in IPin::ReceiveConnection - Implement IPin::Disconnect for the input pin - Enumerate media formats and pass it to constructor of CEnumMediaTypes - Check if the passed format is null in CInputPin::CheckFormat - Copy extra format buffer after KSDATAFORMAT in the pin connection request - Implement KsGetMediaType function - Implement ISpecifyPropertyPages, IKsPropertySet, IKsControl, IStreamBuilder, IKsPinFactory for the output pin - Implement IPin::ReceiveConnection, IPin::EnumMediaTypes for output pin - Stub interfaces for IReferenceClock, IMediaSeeking, IKsTopology, IKsAggregateControl, IKsClockPropertySet, ISpecifyPropertyPages, IPersistStream for proxy filter - Implement IAMDeviceRemoval, IKsControl, IAMFilterMiscFlags, IKsPropertySet interface for proxy filter svn path=/trunk/; revision=46116 --- reactos/dll/directx/ksproxy/clockforward.cpp | 2 + reactos/dll/directx/ksproxy/datatype.cpp | 2 + .../dll/directx/ksproxy/enum_mediatypes.cpp | 27 +- reactos/dll/directx/ksproxy/input_pin.cpp | 186 +-- reactos/dll/directx/ksproxy/ksproxy.cpp | 83 +- reactos/dll/directx/ksproxy/ksproxy.rc | 101 +- reactos/dll/directx/ksproxy/output_pin.cpp | 452 +++++++- reactos/dll/directx/ksproxy/precomp.h | 4 +- reactos/dll/directx/ksproxy/proxy.cpp | 1006 ++++++++++++++++- .../dll/directx/ksproxy/qualityforward.cpp | 4 + 10 files changed, 1751 insertions(+), 116 deletions(-) diff --git a/reactos/dll/directx/ksproxy/clockforward.cpp b/reactos/dll/directx/ksproxy/clockforward.cpp index cba65b3cdf0..80bf00fe421 100644 --- a/reactos/dll/directx/ksproxy/clockforward.cpp +++ b/reactos/dll/directx/ksproxy/clockforward.cpp @@ -8,7 +8,9 @@ */ #include "precomp.h" +#ifndef _MSC_VER const GUID KSCATEGORY_CLOCK = {0x53172480, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +#endif class CKsClockForwarder : public IDistributorNotify, public IKsObject diff --git a/reactos/dll/directx/ksproxy/datatype.cpp b/reactos/dll/directx/ksproxy/datatype.cpp index 3d2d925f19c..3d132890dfd 100644 --- a/reactos/dll/directx/ksproxy/datatype.cpp +++ b/reactos/dll/directx/ksproxy/datatype.cpp @@ -9,7 +9,9 @@ #include "precomp.h" /* FIXME guid mess */ +#ifndef _MSC_VER const GUID IID_IUnknown = {0x00000000, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; +#endif const GUID IID_IClassFactory = {0x00000001, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; class CKsDataTypeHandler : public IKsDataTypeHandler diff --git a/reactos/dll/directx/ksproxy/enum_mediatypes.cpp b/reactos/dll/directx/ksproxy/enum_mediatypes.cpp index 9895c2290cc..462ffda24fc 100644 --- a/reactos/dll/directx/ksproxy/enum_mediatypes.cpp +++ b/reactos/dll/directx/ksproxy/enum_mediatypes.cpp @@ -103,7 +103,31 @@ CEnumMediaTypes::Next( if (!MediaType) break; - CopyMemory(MediaType, &m_MediaTypes[m_Index + i], sizeof(AM_MEDIA_TYPE)); + if (m_MediaTypes[m_Index + i].cbFormat) + { + LPBYTE pFormat = (LPBYTE)CoTaskMemAlloc(m_MediaTypes[m_Index + i].cbFormat); + if (!pFormat) + { + CoTaskMemFree(MediaType); + break; + } + + CopyMemory(MediaType, &m_MediaTypes[m_Index + i], sizeof(AM_MEDIA_TYPE)); + MediaType->pbFormat = pFormat; + CopyMemory(MediaType->pbFormat, m_MediaTypes[m_Index + i].pbFormat, m_MediaTypes[m_Index + i].cbFormat); + MediaType->pUnk = (IUnknown *)this; + MediaType->pUnk->AddRef(); + } + else + { + CopyMemory(MediaType, &m_MediaTypes[m_Index + i], sizeof(AM_MEDIA_TYPE)); + } + + if (MediaType->pUnk) + { + MediaType->pUnk->AddRef(); + } + ppMediaTypes[i] = MediaType; i++; } @@ -114,7 +138,6 @@ CEnumMediaTypes::Next( } m_Index += i; - if (i < cMediaTypes) return S_FALSE; else diff --git a/reactos/dll/directx/ksproxy/input_pin.cpp b/reactos/dll/directx/ksproxy/input_pin.cpp index 2b08b16e89e..ce2cef4600d 100644 --- a/reactos/dll/directx/ksproxy/input_pin.cpp +++ b/reactos/dll/directx/ksproxy/input_pin.cpp @@ -9,8 +9,12 @@ #include "precomp.h" const GUID IID_IKsPinEx = {0x7bb38260L, 0xd19c, 0x11d2, {0xb3, 0x8a, 0x00, 0xa0, 0xc9, 0x5e, 0xc2, 0x2e}}; -const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +#ifndef _MSC_VER +const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +#endif + +#ifndef _MSC_VER KSPIN_INTERFACE StandardPinInterface = { {STATIC_KSINTERFACESETID_Standard}, @@ -25,6 +29,23 @@ KSPIN_MEDIUM StandardPinMedium = 0 }; +#else + +KSPIN_INTERFACE StandardPinInterface = +{ + STATIC_KSINTERFACESETID_Standard, + KSINTERFACE_STANDARD_STREAMING, + 0 +}; + +KSPIN_MEDIUM StandardPinMedium = +{ + STATIC_KSMEDIUMSETID_Standard, + KSMEDIUM_TYPE_ANYINSTANCE, + 0 +}; + +#endif class CInputPin : public IPin, public IKsPropertySet, @@ -117,9 +138,9 @@ public: //--------------------------------------------------------------- HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt); - HRESULT STDMETHODCALLTYPE CreatePin(); - HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, PKSDATAFORMAT DataFormat); - CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, HANDLE hFilter, ULONG PinId, KSPIN_COMMUNICATION Communication) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hFilter(hFilter), m_hPin(0), m_PinId(PinId), m_MemAllocator(0), m_IoCount(0), m_Communication(Communication), m_Pin(0){}; + HRESULT STDMETHODCALLTYPE CreatePin(const AM_MEDIA_TYPE *pmt); + HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, const AM_MEDIA_TYPE *pmt); + CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, HANDLE hFilter, ULONG PinId, KSPIN_COMMUNICATION Communication) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hFilter(hFilter), m_hPin(0), m_PinId(PinId), m_MemAllocator(0), m_IoCount(0), m_Communication(Communication), m_Pin(0), m_ReadOnly(0){}; virtual ~CInputPin(){}; protected: @@ -135,6 +156,7 @@ protected: KSPIN_INTERFACE m_Interface; KSPIN_MEDIUM m_Medium; IPin * m_Pin; + BOOL m_ReadOnly; }; HRESULT @@ -160,39 +182,18 @@ CInputPin::QueryInterface( } else if (IsEqualGUID(refiid, IID_IKsObject)) { - if (!m_hPin) - { - HRESULT hr = CreatePin(); - if (FAILED(hr)) - return hr; - } - *Output = (IKsObject*)(this); reinterpret_cast(*Output)->AddRef(); return NOERROR; } else if (IsEqualGUID(refiid, IID_IKsPropertySet)) { - if (!m_hPin) - { - HRESULT hr = CreatePin(); - if (FAILED(hr)) - return hr; - } - *Output = (IKsPropertySet*)(this); reinterpret_cast(*Output)->AddRef(); return NOERROR; } else if (IsEqualGUID(refiid, IID_IKsControl)) { - if (!m_hPin) - { - HRESULT hr = CreatePin(); - if (FAILED(hr)) - return hr; - } - *Output = (IKsControl*)(this); reinterpret_cast(*Output)->AddRef(); return NOERROR; @@ -200,13 +201,6 @@ CInputPin::QueryInterface( else if (IsEqualGUID(refiid, IID_IKsPin) || IsEqualGUID(refiid, IID_IKsPinEx)) { - if (!m_hPin) - { - HRESULT hr = CreatePin(); - if (FAILED(hr)) - return hr; - } - *Output = (IKsPinEx*)(this); reinterpret_cast(*Output)->AddRef(); return NOERROR; @@ -227,7 +221,7 @@ CInputPin::QueryInterface( // IMemInputPin // - // + HRESULT STDMETHODCALLTYPE CInputPin::GetAllocator(IMemAllocator **ppAllocator) @@ -251,6 +245,7 @@ CInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly) } m_MemAllocator = pAllocator; + m_ReadOnly = bReadOnly; return NOERROR; } @@ -466,7 +461,7 @@ CInputPin::KsNotifyError( //------------------------------------------------------------------- -// IKsPropertySet +// IKsControl // HRESULT STDMETHODCALLTYPE @@ -477,6 +472,7 @@ CInputPin::KsProperty( ULONG DataLength, ULONG* BytesReturned) { + assert(m_hPin != 0); return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned); } @@ -489,6 +485,7 @@ CInputPin::KsMethod( ULONG DataLength, ULONG* BytesReturned) { + assert(m_hPin != 0); return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned); } @@ -501,6 +498,8 @@ CInputPin::KsEvent( ULONG DataLength, ULONG* BytesReturned) { + assert(m_hPin != 0); + if (EventLength) return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned); else @@ -619,10 +618,7 @@ HANDLE STDMETHODCALLTYPE CInputPin::KsGetObjectHandle() { - OutputDebugStringW(L"CInputPin::KsGetObjectHandle CALLED\n"); - - //FIXME - // return pin handle + assert(m_hPin); return m_hPin; } @@ -645,7 +641,6 @@ CInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) if (m_Pin) { - OutputDebugStringW(L"CInputPin::ReceiveConnection already connected\n"); return VFW_E_ALREADY_CONNECTED; } @@ -657,19 +652,36 @@ CInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) if (FAILED(CheckFormat(pmt))) return hr; + hr = CreatePin(pmt); + if (FAILED(hr)) + { + return hr; + } + //FIXME create pin m_Pin = pConnector; m_Pin->AddRef(); - OutputDebugStringW(L"CInputPin::ReceiveConnection NotImplemented\n"); return S_OK; } HRESULT STDMETHODCALLTYPE CInputPin::Disconnect( void) { - OutputDebugStringW(L"CInputPin::Disconnect NotImplemented\n"); - return E_NOTIMPL; + if (!m_Pin) + { + // pin was not connected + return S_FALSE; + } + + //FIXME + //check if filter is active + + m_Pin->Release(); + m_Pin = NULL; + + OutputDebugStringW(L"CInputPin::Disconnect\n"); + return S_OK; } HRESULT STDMETHODCALLTYPE @@ -693,6 +705,9 @@ HRESULT STDMETHODCALLTYPE CInputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt) { + if (!m_Pin) + return VFW_E_NOT_CONNECTED; + OutputDebugStringW(L"CInputPin::ConnectionMediaType NotImplemented\n"); return E_NOTIMPL; } @@ -742,8 +757,41 @@ HRESULT STDMETHODCALLTYPE CInputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) { - return CEnumMediaTypes_fnConstructor(0, NULL, IID_IEnumMediaTypes, (void**)ppEnum); + HRESULT hr; + ULONG MediaTypeCount = 0, Index; + AM_MEDIA_TYPE * MediaTypes; + + // query media type count + hr = KsGetMediaTypeCount(m_hFilter, m_PinId, &MediaTypeCount); + if (FAILED(hr) || !MediaTypeCount) + return hr; + + // allocate media types + MediaTypes = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * MediaTypeCount); + if (!MediaTypes) + { + // not enough memory + return E_OUTOFMEMORY; + } + + // zero media types + ZeroMemory(MediaTypes, sizeof(AM_MEDIA_TYPE) * MediaTypeCount); + + for(Index = 0; Index < MediaTypeCount; Index++) + { + // get media type + hr = KsGetMediaType(Index, &MediaTypes[Index], m_hFilter, m_PinId); + if (FAILED(hr)) + { + // failed + CoTaskMemFree(MediaTypes); + return hr; + } + } + + return CEnumMediaTypes_fnConstructor(MediaTypeCount, MediaTypes, IID_IEnumMediaTypes, (void**)ppEnum); } + HRESULT STDMETHODCALLTYPE CInputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin) @@ -799,6 +847,9 @@ CInputPin::CheckFormat( Property.PinId = m_PinId; Property.Reserved = 0; + if (!pmt) + return E_POINTER; + // query for size of dataranges hr = KsSynchronousDeviceControl(m_hFilter, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), NULL, 0, &BytesReturned); @@ -842,13 +893,12 @@ CInputPin::CheckFormat( HRESULT STDMETHODCALLTYPE -CInputPin::CreatePin() +CInputPin::CreatePin( + const AM_MEDIA_TYPE *pmt) { PKSMULTIPLE_ITEM MediumList; PKSMULTIPLE_ITEM InterfaceList; - PKSMULTIPLE_ITEM DataFormatList = NULL; PKSPIN_MEDIUM Medium; - PKSDATAFORMAT DataFormat; PKSPIN_INTERFACE Interface; HRESULT hr; @@ -866,19 +916,6 @@ CInputPin::CreatePin() return hr; } - // get data ranges - hr = KsGetMultiplePinFactoryItems(m_hFilter, m_PinId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&DataFormatList); - if (FAILED(hr) || DataFormatList->Count == 0) - { - // failed - CoTaskMemFree(MediumList); - CoTaskMemFree(InterfaceList); - if (DataFormatList) - CoTaskMemFree(DataFormatList); - - return hr; - } - if (MediumList->Count) { //use first available medium @@ -901,15 +938,10 @@ CInputPin::CreatePin() Interface = &StandardPinInterface; } - //FIXME determine format - // use first available format - DataFormat = (PKSDATAFORMAT) (DataFormatList + 1); - // now create pin - hr = CreatePinHandle(Medium, Interface, DataFormat); + hr = CreatePinHandle(Medium, Interface, pmt); // free medium / interface / dataformat - CoTaskMemFree(DataFormatList); CoTaskMemFree(MediumList); CoTaskMemFree(InterfaceList); @@ -921,14 +953,15 @@ STDMETHODCALLTYPE CInputPin::CreatePinHandle( PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, - PKSDATAFORMAT DataFormat) + const AM_MEDIA_TYPE *pmt) { PKSPIN_CONNECT PinConnect; + PKSDATAFORMAT DataFormat; ULONG Length; HRESULT hr; // calc format size - Length = sizeof(KSPIN_CONNECT) + DataFormat->FormatSize; + Length = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT) + pmt->cbFormat; // allocate pin connect PinConnect = (PKSPIN_CONNECT)CoTaskMemAlloc(Length); @@ -945,7 +978,24 @@ CInputPin::CreatePinHandle( PinConnect->PinToHandle = NULL; PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; PinConnect->Priority.PrioritySubClass = KSPRIORITY_NORMAL; - CopyMemory((PinConnect + 1), DataFormat, DataFormat->FormatSize); + + // get dataformat offset + DataFormat = (PKSDATAFORMAT)(PinConnect + 1); + + // copy data format + DataFormat->FormatSize = sizeof(KSDATAFORMAT) + pmt->cbFormat; + DataFormat->Flags = 0; + DataFormat->SampleSize = pmt->lSampleSize; + DataFormat->Reserved = 0; + CopyMemory(&DataFormat->MajorFormat, &pmt->majortype, sizeof(GUID)); + CopyMemory(&DataFormat->SubFormat, &pmt->subtype, sizeof(GUID)); + CopyMemory(&DataFormat->Specifier, &pmt->formattype, sizeof(GUID)); + + if (pmt->cbFormat) + { + // copy extended format + CopyMemory((DataFormat + 1), pmt->pbFormat, pmt->cbFormat); + } // create pin hr = KsCreatePin(m_hFilter, PinConnect, GENERIC_WRITE, &m_hPin); diff --git a/reactos/dll/directx/ksproxy/ksproxy.cpp b/reactos/dll/directx/ksproxy/ksproxy.cpp index 927a1dc14b2..237b0390427 100644 --- a/reactos/dll/directx/ksproxy/ksproxy.cpp +++ b/reactos/dll/directx/ksproxy/ksproxy.cpp @@ -10,14 +10,18 @@ #include "precomp.h" -const GUID KSPROPSETID_Pin = {0x8C134960, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; -const GUID KSINTERFACESETID_Standard = {STATIC_KSINTERFACESETID_Standard}; + const GUID CLSID_KsClockForwarder = {0x877e4351, 0x6fea, 0x11d0, {0xb8, 0x63, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}}; const GUID CLSID_KsQualityForwarder = {0xe05592e4, 0xc0b5, 0x11d0, {0xa4, 0x39, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96}}; const GUID CLSID_KsIBasicAudioInterfaceHandler = {0xb9f8ac3e, 0x0f71, 0x11d2, {0xb7, 0x2c, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d}}; -const GUID CLSID_Proxy = {0x17CCA71B, 0xECD7, 0x11D0, {0xB9, 0x08, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +#ifndef _MSC_VER +const GUID KSPROPSETID_Pin = {0x8C134960, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; +const GUID KSINTERFACESETID_Standard = {STATIC_KSINTERFACESETID_Standard}; +const GUID CLSID_Proxy = {0x17CCA71B, 0xECD7, 0x11D0, {0xB9, 0x08, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +#endif + static INTERFACE_TABLE InterfaceTable[] = { {&MEDIATYPE_Audio, CKsDataTypeHandler_Constructor}, @@ -258,7 +262,78 @@ KsGetMediaType( HANDLE FilterHandle, ULONG PinFactoryId) { - //UNIMPLEMENTED + HRESULT hr; + PKSMULTIPLE_ITEM ItemList; + int i = 0; + PKSDATAFORMAT DataFormat; + + if (Position < 0) + return E_INVALIDARG; + + // get current supported ranges + hr = KsGetMultiplePinFactoryItems(FilterHandle, PinFactoryId, KSPROPERTY_PIN_CONSTRAINEDDATARANGES, (PVOID*)&ItemList); + if (FAILED(hr)) + { + // get standard dataranges + hr = KsGetMultiplePinFactoryItems(FilterHandle, PinFactoryId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&ItemList); + + //check for success + if (FAILED(hr)) + return hr; + } + + if ((ULONG)Position >= ItemList->Count) + { + // out of bounds + CoTaskMemFree(ItemList); + return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NO_MORE_ITEMS); + } + + // goto first datarange + DataFormat = (PKSDATAFORMAT)(ItemList + 1); + + while(i != Position) + { + // goto next format; + DataFormat = (PKSDATAFORMAT)(ULONG_PTR)(DataFormat + DataFormat->FormatSize); + i++; + } + + + DataFormat->FormatSize -= sizeof(KSDATAFORMAT); + if (DataFormat->FormatSize) + { + // copy extra format buffer + AmMediaType->pbFormat = (BYTE*)CoTaskMemAlloc(DataFormat->FormatSize); + if (!AmMediaType->pbFormat) + { + // not enough memory + CoTaskMemFree(ItemList); + return E_OUTOFMEMORY; + } + // copy format buffer + CopyMemory(AmMediaType->pbFormat, (DataFormat + 1), DataFormat->FormatSize); + AmMediaType->cbFormat = DataFormat->FormatSize; + } + else + { + // no format buffer + AmMediaType->pbFormat = NULL; + AmMediaType->cbFormat = 0; + } + + // copy type info + CopyMemory(&AmMediaType->majortype, &DataFormat->MajorFormat, sizeof(GUID)); + CopyMemory(&AmMediaType->subtype, &DataFormat->SubFormat, sizeof(GUID)); + CopyMemory(&AmMediaType->formattype, &DataFormat->Specifier, sizeof(GUID)); + AmMediaType->bTemporalCompression = FALSE; //FIXME verify + AmMediaType->pUnk = NULL; //FIXME + AmMediaType->lSampleSize = DataFormat->SampleSize; + AmMediaType->bFixedSizeSamples = (AmMediaType->lSampleSize) ? TRUE : FALSE; + + // free dataformat list + CoTaskMemFree(ItemList); + return NOERROR; } diff --git a/reactos/dll/directx/ksproxy/ksproxy.rc b/reactos/dll/directx/ksproxy/ksproxy.rc index cf8ecb41a6a..f917d67fa1d 100644 --- a/reactos/dll/directx/ksproxy/ksproxy.rc +++ b/reactos/dll/directx/ksproxy/ksproxy.rc @@ -1,9 +1,98 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource." -#define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS WDM Streaming ActiveMovie Proxy\0" -#define REACTOS_STR_INTERNAL_NAME "ksproxy\0" -#define REACTOS_STR_ORIGINAL_FILENAME "ksproxy.ax\0" +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" -#include +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Deutsch (Deutschland) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) +#ifdef _WIN32 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 5,3,2600,3264 + PRODUCTVERSION 5,3,2600,3264 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040704b0" + BEGIN + VALUE "CompanyName", "ReactOS WDM Streaming ActiveMovie Proxy" + VALUE "FileDescription", "ReactOS WDM Streaming ActiveMovie Proxy" + VALUE "FileVersion", "5, 3, 2600, 3264" + VALUE "InternalName", "ksproxy" + VALUE "LegalCopyright", "Copyright (C) 2010" + VALUE "OriginalFilename", "ksproxy.dll" + VALUE "ProductName", "ReactOS WDM Streaming ActiveMovie Proxy" + VALUE "ProductVersion", "5, 3, 2600, 3264" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x407, 1200 + END +END + +#endif // Deutsch (Deutschland) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + ///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED -#include diff --git a/reactos/dll/directx/ksproxy/output_pin.cpp b/reactos/dll/directx/ksproxy/output_pin.cpp index b29d12ac4b2..d21f3832f15 100644 --- a/reactos/dll/directx/ksproxy/output_pin.cpp +++ b/reactos/dll/directx/ksproxy/output_pin.cpp @@ -8,17 +8,21 @@ */ #include "precomp.h" +#ifndef _MSC_VER +const GUID IID_IKsPinFactory = {0xCD5EBE6BL, 0x8B6E, 0x11D1, {0x8A, 0xE0, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +#endif + class COutputPin : public IPin, - public IKsObject + public IKsObject, + public IKsPropertySet, + public IStreamBuilder, + public IKsPinFactory, + public ISpecifyPropertyPages, +// public IKsPinPipe, + public IKsControl /* public IQualityControl, public IKsPinEx, - public IKsPinPipe, - public ISpecifyPropertyPages, - public IStreamBuilder, - public IKsPropertySet, - public IKsPinFactory, - public IKsControl, public IKsAggregateControl public IMediaSeeking, public IAMStreamConfig, @@ -38,12 +42,25 @@ public: InterlockedDecrement(&m_Ref); if (!m_Ref) { - delete this; + //delete this; return 0; } return m_Ref; } + //IKsPinPipe + HRESULT STDMETHODCALLTYPE KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX *FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option); + HRESULT STDMETHODCALLTYPE KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option); + IPin* STDMETHODCALLTYPE KsGetConnectedPin(); + IKsAllocatorEx* STDMETHODCALLTYPE KsGetPipe(KSPEEKOPERATION Operation); + HRESULT STDMETHODCALLTYPE KsSetPipe(IKsAllocatorEx *KsAllocator); + ULONG STDMETHODCALLTYPE KsGetPipeAllocatorFlag(); + HRESULT STDMETHODCALLTYPE KsSetPipeAllocatorFlag(ULONG Flag); + GUID STDMETHODCALLTYPE KsGetPinBusCache(); + HRESULT STDMETHODCALLTYPE KsSetPinBusCache(GUID Bus); + PWCHAR STDMETHODCALLTYPE KsGetPinName(); + PWCHAR STDMETHODCALLTYPE KsGetFilterName(); + //IPin methods HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt); HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt); @@ -61,17 +78,58 @@ public: HRESULT STDMETHODCALLTYPE EndFlush(); HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); + // ISpecifyPropertyPages + HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages); + //IKsObject methods HANDLE STDMETHODCALLTYPE KsGetObjectHandle(); + //IKsPropertySet + HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData); + HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData, DWORD *pcbReturned); + HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport); - COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName){}; - virtual ~COutputPin(){}; + //IKsControl + HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned); + HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned); + HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned); + + //IStreamBuilder + HRESULT STDMETHODCALLTYPE Render(IPin *ppinOut, IGraphBuilder *pGraph); + HRESULT STDMETHODCALLTYPE Backout(IPin *ppinOut, IGraphBuilder *pGraph); + + //IKsPinFactory + HRESULT STDMETHODCALLTYPE KsPinFactory(ULONG* PinFactory); + + COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId); + virtual ~COutputPin(); protected: LONG m_Ref; IBaseFilter * m_ParentFilter; LPCWSTR m_PinName; + HANDLE m_hPin; + ULONG m_PinId; + IKsObject * m_KsObjectParent; + IPin * m_Pin; +}; + +COutputPin::~COutputPin() +{ + if (m_KsObjectParent) + m_KsObjectParent->Release(); +} + +COutputPin::COutputPin( + IBaseFilter * ParentFilter, + LPCWSTR PinName, + ULONG PinId) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hPin(0), m_PinId(PinId), m_KsObjectParent(0), m_Pin(0) +{ + HRESULT hr; + + hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&m_KsObjectParent); + assert(hr == S_OK); + }; HRESULT @@ -94,6 +152,41 @@ COutputPin::QueryInterface( reinterpret_cast(*Output)->AddRef(); return NOERROR; } + else if (IsEqualGUID(refiid, IID_IKsPropertySet)) + { + *Output = (IKsPropertySet*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsControl)) + { + *Output = (IKsControl*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IStreamBuilder)) + { + *Output = (IStreamBuilder*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsPinFactory)) + { + *Output = (IKsPinFactory*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages)) + { + *Output = (ISpecifyPropertyPages*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IBaseFilter)) + { + OutputDebugStringW(L"COutputPin::QueryInterface query IID_IBaseFilter\n"); + DebugBreak(); + } WCHAR Buffer[MAX_PATH]; LPOLESTR lpstr; @@ -105,6 +198,60 @@ COutputPin::QueryInterface( return E_NOINTERFACE; } +//------------------------------------------------------------------- +// ISpecifyPropertyPages +// + +HRESULT +STDMETHODCALLTYPE +COutputPin::GetPages(CAUUID *pPages) +{ + OutputDebugStringW(L"COutputPin::GetPages NotImplemented\n"); + + if (!pPages) + return E_POINTER; + + pPages->cElems = 0; + pPages->pElems = NULL; + + return S_OK; +} + +//------------------------------------------------------------------- +// IKsPinFactory +// + +HRESULT +STDMETHODCALLTYPE +COutputPin::KsPinFactory( + ULONG* PinFactory) +{ + *PinFactory = m_PinId; + return S_OK; +} + + +//------------------------------------------------------------------- +// IStreamBuilder +// + +HRESULT +STDMETHODCALLTYPE +COutputPin::Render( + IPin *ppinOut, + IGraphBuilder *pGraph) +{ + return S_OK; +} + +HRESULT +STDMETHODCALLTYPE +COutputPin::Backout( + IPin *ppinOut, + IGraphBuilder *pGraph) +{ + return S_OK; +} //------------------------------------------------------------------- // IKsObject // @@ -112,13 +259,161 @@ HANDLE STDMETHODCALLTYPE COutputPin::KsGetObjectHandle() { - OutputDebugStringW(L"COutputPin::KsGetObjectHandle CALLED\n"); - - //FIXME - // return pin handle - return NULL; + assert(m_hPin); + return m_hPin; } +//------------------------------------------------------------------- +// IKsControl +// +HRESULT +STDMETHODCALLTYPE +COutputPin::KsProperty( + PKSPROPERTY Property, + ULONG PropertyLength, + LPVOID PropertyData, + ULONG DataLength, + ULONG* BytesReturned) +{ + assert(m_hPin != 0); + return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned); +} + +HRESULT +STDMETHODCALLTYPE +COutputPin::KsMethod( + PKSMETHOD Method, + ULONG MethodLength, + LPVOID MethodData, + ULONG DataLength, + ULONG* BytesReturned) +{ + assert(m_hPin != 0); + return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned); +} + +HRESULT +STDMETHODCALLTYPE +COutputPin::KsEvent( + PKSEVENT Event, + ULONG EventLength, + LPVOID EventData, + ULONG DataLength, + ULONG* BytesReturned) +{ + assert(m_hPin != 0); + + if (EventLength) + return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned); + else + return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned); +} + + +//------------------------------------------------------------------- +// IKsPropertySet +// +HRESULT +STDMETHODCALLTYPE +COutputPin::Set( + REFGUID guidPropSet, + DWORD dwPropID, + LPVOID pInstanceData, + DWORD cbInstanceData, + LPVOID pPropData, + DWORD cbPropData) +{ + ULONG BytesReturned; + + if (cbInstanceData) + { + PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData); + if (!Property) + return E_OUTOFMEMORY; + + Property->Set = guidPropSet; + Property->Id = dwPropID; + Property->Flags = KSPROPERTY_TYPE_SET; + + CopyMemory((Property+1), pInstanceData, cbInstanceData); + + HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned); + CoTaskMemFree(Property); + return hr; + } + else + { + KSPROPERTY Property; + + Property.Set = guidPropSet; + Property.Id = dwPropID; + Property.Flags = KSPROPERTY_TYPE_SET; + + HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned); + return hr; + } +} + +HRESULT +STDMETHODCALLTYPE +COutputPin::Get( + REFGUID guidPropSet, + DWORD dwPropID, + LPVOID pInstanceData, + DWORD cbInstanceData, + LPVOID pPropData, + DWORD cbPropData, + DWORD *pcbReturned) +{ + ULONG BytesReturned; + + if (cbInstanceData) + { + PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData); + if (!Property) + return E_OUTOFMEMORY; + + Property->Set = guidPropSet; + Property->Id = dwPropID; + Property->Flags = KSPROPERTY_TYPE_GET; + + CopyMemory((Property+1), pInstanceData, cbInstanceData); + + HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned); + CoTaskMemFree(Property); + return hr; + } + else + { + KSPROPERTY Property; + + Property.Set = guidPropSet; + Property.Id = dwPropID; + Property.Flags = KSPROPERTY_TYPE_GET; + + HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned); + return hr; + } +} + +HRESULT +STDMETHODCALLTYPE +COutputPin::QuerySupported( + REFGUID guidPropSet, + DWORD dwPropID, + DWORD *pTypeSupport) +{ + KSPROPERTY Property; + ULONG BytesReturned; + + Property.Set = guidPropSet; + Property.Id = dwPropID; + Property.Flags = KSPROPERTY_TYPE_SETSUPPORT; + + return KsProperty(&Property, sizeof(KSPROPERTY), pTypeSupport, sizeof(DWORD), &BytesReturned); +} + + //------------------------------------------------------------------- // IPin interface // @@ -126,30 +421,92 @@ HRESULT STDMETHODCALLTYPE COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) { + AM_MEDIA_TYPE MediaType; + HRESULT hr; + HANDLE hFilter; + OutputDebugStringW(L"COutputPin::Connect called\n"); - return E_NOTIMPL; + if (pmt) + { + hr = pReceivePin->QueryAccept(pmt); + if (FAILED(hr)) + return hr; + } + else + { + // get parent filter handle + hFilter = m_KsObjectParent->KsGetObjectHandle(); + + // get media type count + ZeroMemory(&MediaType, sizeof(AM_MEDIA_TYPE)); + hr = KsGetMediaType(0, &MediaType, hFilter, m_PinId); + if (FAILED(hr)) + return hr; + + // query accept + hr = pReceivePin->QueryAccept(&MediaType); + if (FAILED(hr)) + return hr; + + pmt = &MediaType; + } + + //FIXME create pin handle + + // receive connection; + hr = pReceivePin->ReceiveConnection((IPin*)this, pmt); + if (SUCCEEDED(hr)) + { + // increment reference count + pReceivePin->AddRef(); + m_Pin = pReceivePin; + OutputDebugStringW(L"COutputPin::Connect success\n"); + } + + return hr; } HRESULT STDMETHODCALLTYPE COutputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) { - OutputDebugStringW(L"COutputPin::ReceiveConnection called\n"); - return E_NOTIMPL; + return E_UNEXPECTED; } HRESULT STDMETHODCALLTYPE COutputPin::Disconnect( void) { - OutputDebugStringW(L"COutputPin::Disconnect called\n"); - return E_NOTIMPL; + if (!m_Pin) + { + // pin was not connected + return S_FALSE; + } + + //FIXME + //check if filter is active + + m_Pin->Release(); + m_Pin = NULL; + + OutputDebugStringW(L"COutputPin::Disconnect\n"); + return S_OK; } HRESULT STDMETHODCALLTYPE COutputPin::ConnectedTo(IPin **pPin) { + if (!pPin) + return E_POINTER; + + if (m_Pin) + { + // increment reference count + m_Pin->AddRef(); + *pPin = m_Pin; + return S_OK; + } + *pPin = NULL; - OutputDebugStringW(L"COutputPin::ConnectedTo called\n"); return VFW_E_NOT_CONNECTED; } HRESULT @@ -204,8 +561,56 @@ HRESULT STDMETHODCALLTYPE COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) { + HRESULT hr; + ULONG MediaTypeCount = 0, Index; + AM_MEDIA_TYPE * MediaTypes; + HANDLE hFilter; + OutputDebugStringW(L"COutputPin::EnumMediaTypes called\n"); - return E_NOTIMPL; + + if (!m_KsObjectParent) + { + // no interface + return E_NOINTERFACE; + } + + // get parent filter handle + hFilter = m_KsObjectParent->KsGetObjectHandle(); + + // query media type count + hr = KsGetMediaTypeCount(hFilter, m_PinId, &MediaTypeCount); + if (FAILED(hr) || !MediaTypeCount) + { + OutputDebugStringW(L"COutputPin::EnumMediaTypes failed1\n"); + return hr; + } + + // allocate media types + MediaTypes = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * MediaTypeCount); + if (!MediaTypes) + { + // not enough memory + OutputDebugStringW(L"COutputPin::EnumMediaTypes CoTaskMemAlloc\n"); + return E_OUTOFMEMORY; + } + + // zero media types + ZeroMemory(MediaTypes, sizeof(AM_MEDIA_TYPE) * MediaTypeCount); + + for(Index = 0; Index < MediaTypeCount; Index++) + { + // get media type + hr = KsGetMediaType(Index, &MediaTypes[Index], hFilter, m_PinId); + if (FAILED(hr)) + { + // failed + CoTaskMemFree(MediaTypes); + OutputDebugStringW(L"COutputPin::EnumMediaTypes failed2\n"); + return hr; + } + } + + return CEnumMediaTypes_fnConstructor(MediaTypeCount, MediaTypes, IID_IEnumMediaTypes, (void**)ppEnum); } HRESULT STDMETHODCALLTYPE @@ -248,10 +653,11 @@ WINAPI COutputPin_Constructor( IBaseFilter * ParentFilter, LPCWSTR PinName, + ULONG PinId, REFIID riid, LPVOID * ppv) { - COutputPin * handler = new COutputPin(ParentFilter, PinName); + COutputPin * handler = new COutputPin(ParentFilter, PinName, PinId); if (!handler) return E_OUTOFMEMORY; diff --git a/reactos/dll/directx/ksproxy/precomp.h b/reactos/dll/directx/ksproxy/precomp.h index 32953e94cb5..5078daef9a9 100644 --- a/reactos/dll/directx/ksproxy/precomp.h +++ b/reactos/dll/directx/ksproxy/precomp.h @@ -18,6 +18,7 @@ #include #include #include +#include //#include typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject); @@ -117,6 +118,7 @@ WINAPI COutputPin_Constructor( IBaseFilter * ParentFilter, LPCWSTR PinName, + ULONG PinId, REFIID riid, LPVOID * ppv); @@ -137,4 +139,4 @@ CEnumMediaTypes_fnConstructor( REFIID riid, LPVOID * ppv); - +extern const GUID IID_IKsObject; diff --git a/reactos/dll/directx/ksproxy/proxy.cpp b/reactos/dll/directx/ksproxy/proxy.cpp index 0ff397c2062..d6139622843 100644 --- a/reactos/dll/directx/ksproxy/proxy.cpp +++ b/reactos/dll/directx/ksproxy/proxy.cpp @@ -8,9 +8,16 @@ */ #include "precomp.h" +#ifndef _MSC_VER const GUID IID_IPersistPropertyBag = {0x37D84F60, 0x42CB, 0x11CE, {0x81, 0x35, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51}}; const GUID GUID_NULL = {0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; +#endif + const GUID IID_IBDA_DeviceControl = {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x00, 0xC0, 0x4F, 0x79, 0x71, 0xE0}}; +const GUID IID_IKsAggregateControl = {0x7F40EAC0, 0x3947, 0x11D2, {0x87, 0x4E, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID IID_IKsClockPropertySet = {0x5C5CBD84, 0xE755, 0x11D0, {0xAC, 0x18, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID IID_IKsTopology = {0x28F54683, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; + /* Needs IKsClock, IKsNotifyEvent */ @@ -18,21 +25,19 @@ const GUID IID_IBDA_DeviceControl = {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x class CKsProxy : public IBaseFilter, public IAMovieSetup, public IPersistPropertyBag, - public IKsObject -/* + public IKsObject, public IPersistStream, + public IAMDeviceRemoval, public ISpecifyPropertyPages, public IReferenceClock, public IMediaSeeking, - public IKsObject, public IKsPropertySet, public IKsClockPropertySet, public IAMFilterMiscFlags, public IKsControl, public IKsTopology, - public IKsAggregateControl, - public IAMDeviceRemoval -*/ + public IKsAggregateControl + { public: typedef std::vectorProxyPluginVector; @@ -70,6 +75,64 @@ public: HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName); HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR *pVendorInfo); + //IReferenceClock + HRESULT STDMETHODCALLTYPE GetTime(REFERENCE_TIME *pTime); + HRESULT STDMETHODCALLTYPE AdviseTime(REFERENCE_TIME baseTime, REFERENCE_TIME streamTime, HEVENT hEvent, DWORD_PTR *pdwAdviseCookie); + HRESULT STDMETHODCALLTYPE AdvisePeriodic(REFERENCE_TIME startTime, REFERENCE_TIME periodTime, HSEMAPHORE hSemaphore, DWORD_PTR *pdwAdviseCookie); + HRESULT STDMETHODCALLTYPE Unadvise(DWORD_PTR dwAdviseCookie); + + //IMediaSeeking + HRESULT STDMETHODCALLTYPE GetCapabilities(DWORD *pCapabilities); + HRESULT STDMETHODCALLTYPE CheckCapabilities(DWORD *pCapabilities); + HRESULT STDMETHODCALLTYPE IsFormatSupported(const GUID *pFormat); + HRESULT STDMETHODCALLTYPE QueryPreferredFormat(GUID *pFormat); + HRESULT STDMETHODCALLTYPE GetTimeFormat(GUID *pFormat); + HRESULT STDMETHODCALLTYPE IsUsingTimeFormat(const GUID *pFormat); + HRESULT STDMETHODCALLTYPE SetTimeFormat(const GUID *pFormat); + HRESULT STDMETHODCALLTYPE GetDuration(LONGLONG *pDuration); + HRESULT STDMETHODCALLTYPE GetStopPosition(LONGLONG *pStop); + HRESULT STDMETHODCALLTYPE GetCurrentPosition(LONGLONG *pCurrent); + HRESULT STDMETHODCALLTYPE ConvertTimeFormat(LONGLONG *pTarget, const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat); + HRESULT STDMETHODCALLTYPE SetPositions(LONGLONG *pCurrent, DWORD dwCurrentFlags, LONGLONG *pStop, DWORD dwStopFlags); + HRESULT STDMETHODCALLTYPE GetPositions(LONGLONG *pCurrent, LONGLONG *pStop); + HRESULT STDMETHODCALLTYPE GetAvailable(LONGLONG *pEarliest, LONGLONG *pLatest); + HRESULT STDMETHODCALLTYPE SetRate(double dRate); + HRESULT STDMETHODCALLTYPE GetRate(double *pdRate); + HRESULT STDMETHODCALLTYPE GetPreroll(LONGLONG *pllPreroll); + + //IKsPropertySet + HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData); + HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData, DWORD *pcbReturned); + HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport); + + //IAMFilterMiscFlags + ULONG STDMETHODCALLTYPE GetMiscFlags( void); + + //IKsControl + HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned); + HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned); + HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned); + + //IKsTopolology + HRESULT STDMETHODCALLTYPE CreateNodeInstance(ULONG NodeId, ULONG Flags, ACCESS_MASK DesiredAccess, IUnknown* UnkOuter, REFGUID InterfaceId, LPVOID* Interface); + + //IKsAggregateControl + HRESULT STDMETHODCALLTYPE KsAddAggregate(IN REFGUID AggregateClass); + HRESULT STDMETHODCALLTYPE KsRemoveAggregate(REFGUID AggregateClass); + + //IKsClockPropertySet + HRESULT STDMETHODCALLTYPE KsGetTime(LONGLONG* Time); + HRESULT STDMETHODCALLTYPE KsSetTime(LONGLONG Time); + HRESULT STDMETHODCALLTYPE KsGetPhysicalTime(LONGLONG* Time); + HRESULT STDMETHODCALLTYPE KsSetPhysicalTime(LONGLONG Time); + HRESULT STDMETHODCALLTYPE KsGetCorrelatedTime(KSCORRELATED_TIME* CorrelatedTime); + HRESULT STDMETHODCALLTYPE KsSetCorrelatedTime(KSCORRELATED_TIME* CorrelatedTime); + HRESULT STDMETHODCALLTYPE KsGetCorrelatedPhysicalTime(KSCORRELATED_TIME* CorrelatedTime); + HRESULT STDMETHODCALLTYPE KsSetCorrelatedPhysicalTime(KSCORRELATED_TIME* CorrelatedTime); + HRESULT STDMETHODCALLTYPE KsGetResolution(KSRESOLUTION* Resolution); + HRESULT STDMETHODCALLTYPE KsGetState(KSSTATE* State); + + //IAMovieSetup methods HRESULT STDMETHODCALLTYPE Register( void); HRESULT STDMETHODCALLTYPE Unregister( void); @@ -82,8 +145,23 @@ public: // IKsObject HANDLE STDMETHODCALLTYPE KsGetObjectHandle(); - CKsProxy() : m_Ref(0), m_pGraph(0), m_ReferenceClock(0), m_FilterState(State_Stopped), m_hDevice(0), m_Plugins(), m_Pins() {}; - virtual ~CKsProxy() + //IAMDeviceRemoval + HRESULT STDMETHODCALLTYPE DeviceInfo(CLSID *pclsidInterfaceClass, LPWSTR *pwszSymbolicLink); + HRESULT STDMETHODCALLTYPE Reassociate(void); + HRESULT STDMETHODCALLTYPE Disassociate( void); + + //IPersistStream + HRESULT STDMETHODCALLTYPE IsDirty( void); + HRESULT STDMETHODCALLTYPE Load(IStream *pStm); + HRESULT STDMETHODCALLTYPE Save(IStream *pStm, BOOL fClearDirty); + HRESULT STDMETHODCALLTYPE GetSizeMax(ULARGE_INTEGER *pcbSize); + + // ISpecifyPropertyPages + HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages); + + + CKsProxy() : m_Ref(0), m_pGraph(0), m_ReferenceClock(0), m_FilterState(State_Stopped), m_hDevice(0), m_Plugins(), m_Pins(), m_DevicePath(0) {}; + ~CKsProxy() { if (m_hDevice) CloseHandle(m_hDevice); @@ -105,6 +183,8 @@ protected: HANDLE m_hDevice; ProxyPluginVector m_Plugins; PinVector m_Pins; + LPWSTR m_DevicePath; + CLSID m_DeviceInterfaceGUID; }; HRESULT @@ -113,7 +193,7 @@ CKsProxy::QueryInterface( IN REFIID refiid, OUT PVOID* Output) { - *Output = NULL; + *Output = (PVOID)0xDEADDEAD;//NULL; if (IsEqualGUID(refiid, IID_IUnknown) || IsEqualGUID(refiid, IID_IBaseFilter)) @@ -128,12 +208,78 @@ CKsProxy::QueryInterface( reinterpret_cast(*Output)->AddRef(); return NOERROR; } - if (IsEqualGUID(refiid, IID_IKsObject)) + else if (IsEqualGUID(refiid, IID_IAMDeviceRemoval)) + { + *Output = (IAMDeviceRemoval*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IPersistStream)) + { + *Output = (IPersistStream*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsObject)) { *Output = (IKsObject*)(this); reinterpret_cast(*Output)->AddRef(); return NOERROR; } + else if (IsEqualGUID(refiid, IID_IReferenceClock)) + { + *Output = (IReferenceClock*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IMediaSeeking)) + { + *Output = (IMediaSeeking*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IAMFilterMiscFlags)) + { + *Output = (IAMFilterMiscFlags*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsControl)) + { + *Output = (IKsControl*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsPropertySet)) + { + *Output = (IKsPropertySet*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsTopology)) + { + *Output = (IKsTopology*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsAggregateControl)) + { + *Output = (IKsAggregateControl*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsClockPropertySet)) + { + *Output = (IKsClockPropertySet*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages)) + { + *Output = (ISpecifyPropertyPages*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } for(ULONG Index = 0; Index < m_Plugins.size(); Index++) { @@ -164,6 +310,815 @@ CKsProxy::QueryInterface( return E_NOINTERFACE; } +//------------------------------------------------------------------- +// ISpecifyPropertyPages +// + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetPages(CAUUID *pPages) +{ + OutputDebugStringW(L"CKsProxy::GetPages NotImplemented\n"); + + if (!pPages) + return E_POINTER; + + pPages->cElems = 0; + pPages->pElems = NULL; + + return S_OK; +} + +//------------------------------------------------------------------- +// IKsClockPropertySet interface +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsGetTime( + LONGLONG* Time) +{ + OutputDebugStringW(L"CKsProxy::KsGetTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsSetTime( + LONGLONG Time) +{ + OutputDebugStringW(L"CKsProxy::KsSetTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsGetPhysicalTime( + LONGLONG* Time) +{ + OutputDebugStringW(L"CKsProxy::KsGetPhysicalTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsSetPhysicalTime( + LONGLONG Time) +{ + OutputDebugStringW(L"CKsProxy::KsSetPhysicalTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsGetCorrelatedTime( + KSCORRELATED_TIME* CorrelatedTime) +{ + OutputDebugStringW(L"CKsProxy::KsGetCorrelatedTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsSetCorrelatedTime( + KSCORRELATED_TIME* CorrelatedTime) +{ + OutputDebugStringW(L"CKsProxy::KsSetCorrelatedTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsGetCorrelatedPhysicalTime( + KSCORRELATED_TIME* CorrelatedTime) +{ + OutputDebugStringW(L"CKsProxy::KsGetCorrelatedPhysicalTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsSetCorrelatedPhysicalTime( + KSCORRELATED_TIME* CorrelatedTime) +{ + OutputDebugStringW(L"CKsProxy::KsSetCorrelatedPhysicalTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsGetResolution( + KSRESOLUTION* Resolution) +{ + OutputDebugStringW(L"CKsProxy::KsGetResolution NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsGetState( + KSSTATE* State) +{ + OutputDebugStringW(L"CKsProxy::KsGetState NotImplemented\n"); + return E_NOTIMPL; +} + +//------------------------------------------------------------------- +// IReferenceClock interface +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetTime( + REFERENCE_TIME *pTime) +{ + OutputDebugStringW(L"CKsProxy::GetTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::AdviseTime( + REFERENCE_TIME baseTime, + REFERENCE_TIME streamTime, + HEVENT hEvent, + DWORD_PTR *pdwAdviseCookie) +{ + OutputDebugStringW(L"CKsProxy::AdviseTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::AdvisePeriodic( + REFERENCE_TIME startTime, + REFERENCE_TIME periodTime, + HSEMAPHORE hSemaphore, + DWORD_PTR *pdwAdviseCookie) +{ + OutputDebugStringW(L"CKsProxy::AdvisePeriodic NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::Unadvise( + DWORD_PTR dwAdviseCookie) +{ + OutputDebugStringW(L"CKsProxy::Unadvise NotImplemented\n"); + return E_NOTIMPL; +} + +//------------------------------------------------------------------- +// IMediaSeeking interface +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetCapabilities( + DWORD *pCapabilities) +{ + OutputDebugStringW(L"CKsProxy::GetCapabilities NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::CheckCapabilities( + DWORD *pCapabilities) +{ + OutputDebugStringW(L"CKsProxy::CheckCapabilities NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::IsFormatSupported( + const GUID *pFormat) +{ + KSPROPERTY Property; + PKSMULTIPLE_ITEM FormatList; + LPGUID pGuid; + ULONG Index; + HRESULT hr = S_FALSE; + ULONG BytesReturned; + + OutputDebugStringW(L"CKsProxy::IsFormatSupported\n"); + + if (!pFormat) + return E_POINTER; + + Property.Set = KSPROPSETID_MediaSeeking; + Property.Id = KSPROPERTY_MEDIASEEKING_FORMATS; + Property.Flags = KSPROPERTY_TYPE_GET; + + // query for format size list + hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &BytesReturned); + + if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_MORE_DATA)) + { + // allocate format list + FormatList = (PKSMULTIPLE_ITEM)CoTaskMemAlloc(BytesReturned); + if (!FormatList) + { + // not enough memory + return E_OUTOFMEMORY; + } + + // get format list + hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)FormatList, BytesReturned, &BytesReturned); + if (FAILED(hr)) + { + // failed to query format list + CoTaskMemFree(FormatList); + return hr; + } + + //iterate through format list + pGuid = (LPGUID)(FormatList + 1); + for(Index = 0; Index < FormatList->Count; Index++) + { + if (IsEqualGUID(*pGuid, *pFormat)) + { + OutputDebugStringW(L"CKsProxy::IsFormatSupported found format\n"); + CoTaskMemFree(FormatList); + return S_OK; + } + pGuid++; + } + + OutputDebugStringW(L"CKsProxy::IsFormatSupported FormatNotFound\n"); + // free format list + CoTaskMemFree(FormatList); + } + + // check if all plugins support it + for(Index = 0; Index < m_Plugins.size(); Index++) + { + // get plugin + IUnknown * Plugin = m_Plugins[Index]; + + if (!Plugin) + continue; + + // query for IMediaSeeking interface + IMediaSeeking *pSeek = NULL; + hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek); + if (FAILED(hr)) + { + // plugin does not support interface + hr = S_FALSE; + OutputDebugStringW(L"CKsProxy::IsFormatSupported plugin does not support IMediaSeeking interface\n"); + break; + } + + // query if it is supported + hr = pSeek->IsFormatSupported(pFormat); + // release interface + pSeek->Release(); + + if (FAILED(hr) || hr == S_FALSE) + break; + } + + return hr; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::QueryPreferredFormat( + GUID *pFormat) +{ + OutputDebugStringW(L"CKsProxy::QueryPreferredFormat NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetTimeFormat( + GUID *pFormat) +{ + OutputDebugStringW(L"CKsProxy::GetTimeFormat NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::IsUsingTimeFormat( + const GUID *pFormat) +{ + OutputDebugStringW(L"CKsProxy::IsUsingTimeFormat NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::SetTimeFormat( + const GUID *pFormat) +{ + OutputDebugStringW(L"CKsProxy::SetTimeFormat NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetDuration( + LONGLONG *pDuration) +{ + OutputDebugStringW(L"CKsProxy::GetDuration NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetStopPosition( + LONGLONG *pStop) +{ + OutputDebugStringW(L"CKsProxy::GetStopPosition NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetCurrentPosition( + LONGLONG *pCurrent) +{ + OutputDebugStringW(L"CKsProxy::GetCurrentPosition NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::ConvertTimeFormat( + LONGLONG *pTarget, + const GUID *pTargetFormat, + LONGLONG Source, + const GUID *pSourceFormat) +{ + OutputDebugStringW(L"CKsProxy::ConvertTimeFormat NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::SetPositions( + LONGLONG *pCurrent, + DWORD dwCurrentFlags, + LONGLONG *pStop, + DWORD dwStopFlags) +{ + OutputDebugStringW(L"CKsProxy::SetPositions NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetPositions( + LONGLONG *pCurrent, + LONGLONG *pStop) +{ + OutputDebugStringW(L"CKsProxy::GetPositions NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetAvailable( + LONGLONG *pEarliest, + LONGLONG *pLatest) +{ + OutputDebugStringW(L"CKsProxy::GetAvailable NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::SetRate( + double dRate) +{ + OutputDebugStringW(L"CKsProxy::SetRate NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetRate( + double *pdRate) +{ + OutputDebugStringW(L"CKsProxy::GetRate NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetPreroll( + LONGLONG *pllPreroll) +{ + OutputDebugStringW(L"CKsProxy::GetPreroll NotImplemented\n"); + return E_NOTIMPL; +} + +//------------------------------------------------------------------- +// IAMFilterMiscFlags interface +// + +ULONG +STDMETHODCALLTYPE +CKsProxy::GetMiscFlags() +{ + ULONG Index; + ULONG Flags = 0; + HRESULT hr; + PIN_DIRECTION PinDirection; + KSPIN_COMMUNICATION Communication; + + for(Index = 0; Index < m_Pins.size(); Index++) + { + // get current pin + IPin * pin = m_Pins[Index]; + // query direction + hr = pin->QueryDirection(&PinDirection); + if (SUCCEEDED(hr)) + { + if (PinDirection == PINDIR_INPUT) + { + if (SUCCEEDED(GetPinCommunication(Index, //FIXME verify PinId + &Communication))) + { + if (Communication == KSPIN_COMMUNICATION_NONE || Communication == KSPIN_COMMUNICATION_BRIDGE) + { + Flags |= AM_FILTER_MISC_FLAGS_IS_SOURCE; + } + } + } + } + } + + OutputDebugStringW(L"CKsProxy::GetMiscFlags stub\n"); + return Flags; +} + +//------------------------------------------------------------------- +// IKsControl +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsProperty( + PKSPROPERTY Property, + ULONG PropertyLength, + LPVOID PropertyData, + ULONG DataLength, + ULONG* BytesReturned) +{ + assert(m_hDevice != 0); + return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned); +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsMethod( + PKSMETHOD Method, + ULONG MethodLength, + LPVOID MethodData, + ULONG DataLength, + ULONG* BytesReturned) +{ + assert(m_hDevice != 0); + return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned); +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsEvent( + PKSEVENT Event, + ULONG EventLength, + LPVOID EventData, + ULONG DataLength, + ULONG* BytesReturned) +{ + assert(m_hDevice != 0); + + if (EventLength) + return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned); + else + return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned); +} + + +//------------------------------------------------------------------- +// IKsPropertySet +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::Set( + REFGUID guidPropSet, + DWORD dwPropID, + LPVOID pInstanceData, + DWORD cbInstanceData, + LPVOID pPropData, + DWORD cbPropData) +{ + ULONG BytesReturned; + + if (cbInstanceData) + { + PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData); + if (!Property) + return E_OUTOFMEMORY; + + Property->Set = guidPropSet; + Property->Id = dwPropID; + Property->Flags = KSPROPERTY_TYPE_SET; + + CopyMemory((Property+1), pInstanceData, cbInstanceData); + + HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned); + CoTaskMemFree(Property); + return hr; + } + else + { + KSPROPERTY Property; + + Property.Set = guidPropSet; + Property.Id = dwPropID; + Property.Flags = KSPROPERTY_TYPE_SET; + + HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned); + return hr; + } +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::Get( + REFGUID guidPropSet, + DWORD dwPropID, + LPVOID pInstanceData, + DWORD cbInstanceData, + LPVOID pPropData, + DWORD cbPropData, + DWORD *pcbReturned) +{ + ULONG BytesReturned; + + if (cbInstanceData) + { + PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData); + if (!Property) + return E_OUTOFMEMORY; + + Property->Set = guidPropSet; + Property->Id = dwPropID; + Property->Flags = KSPROPERTY_TYPE_GET; + + CopyMemory((Property+1), pInstanceData, cbInstanceData); + + HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned); + CoTaskMemFree(Property); + return hr; + } + else + { + KSPROPERTY Property; + + Property.Set = guidPropSet; + Property.Id = dwPropID; + Property.Flags = KSPROPERTY_TYPE_GET; + + HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned); + return hr; + } +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::QuerySupported( + REFGUID guidPropSet, + DWORD dwPropID, + DWORD *pTypeSupport) +{ + KSPROPERTY Property; + ULONG BytesReturned; + + Property.Set = guidPropSet; + Property.Id = dwPropID; + Property.Flags = KSPROPERTY_TYPE_SETSUPPORT; + + return KsProperty(&Property, sizeof(KSPROPERTY), pTypeSupport, sizeof(DWORD), &BytesReturned); +} + + +//------------------------------------------------------------------- +// IKsTopology interface +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::CreateNodeInstance( + ULONG NodeId, + ULONG Flags, + ACCESS_MASK DesiredAccess, + IUnknown* UnkOuter, + REFGUID InterfaceId, + LPVOID* Interface) +{ + OutputDebugStringW(L"CKsProxy::CreateNodeInstance NotImplemented\n"); + return E_NOTIMPL; +} + +//------------------------------------------------------------------- +// IKsAggregateControl interface +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsAddAggregate( + IN REFGUID AggregateClass) +{ + OutputDebugStringW(L"CKsProxy::KsAddAggregate NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsRemoveAggregate( + REFGUID AggregateClass) +{ + OutputDebugStringW(L"CKsProxy::KsRemoveAggregate NotImplemented\n"); + return E_NOTIMPL; +} + + +//------------------------------------------------------------------- +// IPersistStream interface +// + +HRESULT +STDMETHODCALLTYPE +CKsProxy::IsDirty() +{ + OutputDebugStringW(L"CKsProxy::IsDirty Notimplemented\n"); + DebugBreak(); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::Load( + IStream *pStm) +{ + HRESULT hr; + WCHAR Buffer[1000]; + AM_MEDIA_TYPE MediaType; + ULONG BytesReturned; + LONG Length; + + ULONG PinId; + LPOLESTR pMajor, pSub, pFormat; + + OutputDebugStringW(L"CKsProxy::Load\n"); + +#if 0 + ULONG Version = ReadInt(pStm, hr); + if (Version != 1) + return E_FAIL; +#endif + + hr = pStm->Read(&Length, sizeof(ULONG), &BytesReturned); + swprintf(Buffer, L"Length hr %x hr length %lu\n", hr, Length); + OutputDebugStringW(Buffer); + + do + { + hr = pStm->Read(&PinId, sizeof(ULONG), &BytesReturned); + swprintf(Buffer, L"Read: hr %08x PinId %lx BytesReturned %lu\n", hr, PinId, BytesReturned); + OutputDebugStringW(Buffer); + + if (FAILED(hr) || !BytesReturned) + break; + + Length -= BytesReturned; + + hr = pStm->Read(&MediaType, sizeof(AM_MEDIA_TYPE), &BytesReturned); + if (FAILED(hr) || BytesReturned != sizeof(AM_MEDIA_TYPE)) + { + swprintf(Buffer, L"Read failed with %lx\n", hr); + OutputDebugStringW(Buffer); + break; + } + + + StringFromIID(MediaType.majortype, &pMajor); + StringFromIID(MediaType.subtype , &pSub); + StringFromIID(MediaType.formattype, &pFormat); + + swprintf(Buffer, L"BytesReturned %lu majortype %s subtype %s bFixedSizeSamples %u bTemporalCompression %u lSampleSize %u formattype %s, pUnk %p cbFormat %u pbFormat %p\n", BytesReturned, pMajor, pSub, MediaType.bFixedSizeSamples, MediaType.bTemporalCompression, MediaType.lSampleSize, pFormat, MediaType.pUnk, MediaType.cbFormat, MediaType.pbFormat); + OutputDebugStringW(Buffer); + + Length -= BytesReturned; + + + if (MediaType.cbFormat) + { + MediaType.pbFormat = (BYTE*)CoTaskMemAlloc(MediaType.cbFormat); + if (!MediaType.pbFormat) + return E_OUTOFMEMORY; + + hr = pStm->Read(&MediaType.pbFormat, sizeof(MediaType.cbFormat), &BytesReturned); + if (FAILED(hr)) + { + swprintf(Buffer, L"ReadFormat failed with %lx\n", hr); + OutputDebugStringW(Buffer); + break; + } + Length -= BytesReturned; + } + + }while(Length > 0); + + DebugBreak(); + return S_OK; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::Save( + IStream *pStm, + BOOL fClearDirty) +{ + OutputDebugStringW(L"CKsProxy::Save Notimplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetSizeMax( + ULARGE_INTEGER *pcbSize) +{ + OutputDebugStringW(L"CKsProxy::GetSizeMax Notimplemented\n"); + DebugBreak(); + return E_NOTIMPL; +} + +//------------------------------------------------------------------- +// IAMDeviceRemoval interface +// + +HRESULT +STDMETHODCALLTYPE +CKsProxy::DeviceInfo(CLSID *pclsidInterfaceClass, LPWSTR *pwszSymbolicLink) +{ + if (!m_DevicePath) + { + // object not initialized + return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND); + } + + // copy device interface guid + CopyMemory(pclsidInterfaceClass, &m_DeviceInterfaceGUID, sizeof(GUID)); + + if (pwszSymbolicLink) + { + *pwszSymbolicLink = (LPWSTR)CoTaskMemAlloc((wcslen(m_DevicePath)+1) * sizeof(WCHAR)); + if (!*pwszSymbolicLink) + return E_OUTOFMEMORY; + + wcscpy(*pwszSymbolicLink, m_DevicePath); + } + return S_OK; +} +HRESULT +STDMETHODCALLTYPE +CKsProxy::Reassociate(void) +{ + if (!m_DevicePath || m_hDevice) + { + // file path not available + return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND); + } + + m_hDevice = CreateFileW(m_DevicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); + if (!m_hDevice) + { + // failed to open device + return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); + } + + // success + return NOERROR; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::Disassociate(void) +{ + if (!m_hDevice) + return E_HANDLE; + + CloseHandle(m_hDevice); + m_hDevice = NULL; + return NOERROR; +} + + + + //------------------------------------------------------------------- // IKsObject interface // @@ -523,7 +1478,7 @@ CKsProxy::CreatePins() } else { - hr = COutputPin_Constructor((IBaseFilter*)this, PinName, IID_IPin, (void**)&pPin); + hr = COutputPin_Constructor((IBaseFilter*)this, PinName, Index, IID_IPin, (void**)&pPin); if (FAILED(hr)) { CoTaskMemFree(PinName); @@ -551,6 +1506,9 @@ CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog) VARIANT varName; LPGUID pGuid; ULONG NumGuids = 0; + HDEVINFO hList; + SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; + // read device path varName.vt = VT_BSTR; @@ -563,6 +1521,27 @@ CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); } + // create device list + hList = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL); + if (hList == INVALID_HANDLE_VALUE) + { + // failed to create device list + return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); + } + + DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + if (!SetupDiOpenDeviceInterfaceW(hList, (PCWSTR)varName.bstrVal, 0, &DeviceInterfaceData)) + { + // failed to open device interface + SetupDiDestroyDeviceInfoList(hList); + } + + // FIXME handle device interface links(aliases) + CopyMemory(&m_DeviceInterfaceGUID, &DeviceInterfaceData.InterfaceClassGuid, sizeof(GUID)); + + // close device info list + SetupDiDestroyDeviceInfoList(hList); + // open device m_hDevice = CreateFileW(varName.bstrVal, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); @@ -575,6 +1554,9 @@ CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); } + // store device path + m_DevicePath = varName.bstrVal; + // get all supported sets hr = GetSupportedSets(&pGuid, &NumGuids); if (FAILED(hr)) @@ -611,7 +1593,7 @@ CKsProxy::Save(IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties //------------------------------------------------------------------- // IBaseFilter interface -// +// HRESULT STDMETHODCALLTYPE diff --git a/reactos/dll/directx/ksproxy/qualityforward.cpp b/reactos/dll/directx/ksproxy/qualityforward.cpp index 3081d834cbf..88459d8275d 100644 --- a/reactos/dll/directx/ksproxy/qualityforward.cpp +++ b/reactos/dll/directx/ksproxy/qualityforward.cpp @@ -8,7 +8,11 @@ */ #include "precomp.h" +#ifndef _MSC_VER const GUID KSCATEGORY_QUALITY = {0x97EBAACB, 0x95BD, 0x11D0, {0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +#endif + +#define IID_IKsQualityForwarder KSCATEGORY_QUALITY class CKsQualityForwarder : public IKsQualityForwarder { From 6cc3c9cd47fecd60a4a369bd970470cd50df2993 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Thu, 11 Mar 2010 21:41:19 +0000 Subject: [PATCH 57/64] [WIN32K]: Enable the alignment code and reduce the number of hacks, leaving only one for 1bpp top-down output (Freetype?) which doesn't seem to like when the lDelta is aligned to the correct bit-boundary. This should fix the crashes and graphic cltches recently introduced. svn path=/trunk/; revision=46117 --- reactos/subsystems/win32/win32k/eng/surface.c | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/reactos/subsystems/win32/win32k/eng/surface.c b/reactos/subsystems/win32/win32k/eng/surface.c index 423972ce3fb..1fcf4cc6b85 100644 --- a/reactos/subsystems/win32/win32k/eng/surface.c +++ b/reactos/subsystems/win32/win32k/eng/surface.c @@ -475,27 +475,27 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo, switch (BitmapInfo->Format) { case BMF_1BPP: - //ScanLine = ((BitmapInfo->Width + 31) & ~31) / 8; + ScanLine = ((BitmapInfo->Width + 31) & ~31) >> 3; break; case BMF_4BPP: - //ScanLine = ((BitmapInfo->Width + 7) & ~7) / 2; + ScanLine = ((BitmapInfo->Width + 7) & ~7) >> 1; break; case BMF_8BPP: - //ScanLine = ((BitmapInfo->Width + 3) & ~3); + ScanLine = (BitmapInfo->Width + 3) & ~3; break; case BMF_16BPP: - //ScanLine = ((BitmapInfo->Width + 1) & ~1) * 2; + ScanLine = ((BitmapInfo->Width + 1) & ~1) << 1; break; case BMF_24BPP: - //ScanLine = ((BitmapInfo->Width * 3) + 3) & ~3; + ScanLine = ((BitmapInfo->Width * 3) + 3) & ~3; break; case BMF_32BPP: - // ScanLine = BitmapInfo->Width * 4; + ScanLine = BitmapInfo->Width << 2; break; case BMF_8RLE: @@ -510,8 +510,6 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo, return NULL; } - ScanLine = BitmapInfo->Width; - /* Does the device manage its own surface? */ if (!Bits) { @@ -604,6 +602,9 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo, /* For topdown, the base address starts with the bits */ pso->pvScan0 = pso->pvBits; pso->lDelta = ScanLine; + + /* Hack for FreeType/Font Rendering, cannot use the Aligned ScanLine */ + if (BitmapInfo->Format == BMF_1BPP) pso->lDelta = BitmapInfo->Width / 8; } else { @@ -669,7 +670,6 @@ EngCreateBitmap(IN SIZEL Size, */ if ((Bits) && (Width)) { - #if 0 switch (BitmapInfo.Format) { /* Do the conversion for each bit depth we support */ @@ -692,9 +692,6 @@ EngCreateBitmap(IN SIZEL Size, BitmapInfo.Width = Width / 4; break; } -#endif - BitmapInfo.Width = Width; - } /* Now create the surface */ From 661dc42775eb2ba3be78b3f118772532121fe9df Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Thu, 11 Mar 2010 21:52:15 +0000 Subject: [PATCH 58/64] [KSPROXY] - Fix trunk svn path=/trunk/; revision=46118 --- reactos/dll/directx/ksproxy/proxy.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/reactos/dll/directx/ksproxy/proxy.cpp b/reactos/dll/directx/ksproxy/proxy.cpp index d6139622843..f74f22ba9f7 100644 --- a/reactos/dll/directx/ksproxy/proxy.cpp +++ b/reactos/dll/directx/ksproxy/proxy.cpp @@ -11,6 +11,9 @@ #ifndef _MSC_VER const GUID IID_IPersistPropertyBag = {0x37D84F60, 0x42CB, 0x11CE, {0x81, 0x35, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51}}; const GUID GUID_NULL = {0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; +const GUID IID_ISpecifyPropertyPages = {0xB196B28B, 0xBAB4, 0x101A, {0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}; +const GUID IID_IPersistStream = {0x00000109, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; +const GUID KSPROPSETID_MediaSeeking = {0xEE904F0CL, 0xD09B, 0x11D0, {0xAB, 0xE9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; #endif const GUID IID_IBDA_DeviceControl = {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x00, 0xC0, 0x4F, 0x79, 0x71, 0xE0}}; From 75c500f4b076ae920c00f95c5fbca52e121d6a04 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 11 Mar 2010 22:15:21 +0000 Subject: [PATCH 59/64] - Fix the resource parsing loops to correct a memory corruption issue - Return the correct failure status if ExAllocatePool fails svn path=/trunk/; revision=46119 --- reactos/drivers/bus/acpi/buspdo.c | 45 +++++++------------------------ 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/reactos/drivers/bus/acpi/buspdo.c b/reactos/drivers/bus/acpi/buspdo.c index e7cc65b0c19..d085eed3cde 100644 --- a/reactos/drivers/bus/acpi/buspdo.c +++ b/reactos/drivers/bus/acpi/buspdo.c @@ -585,7 +585,6 @@ Bus_PDO_QueryResources( PPDO_DEVICE_DATA DeviceData, PIRP Irp ) { - BOOLEAN Done; ULONG NumberOfResources = 0; PCM_RESOURCE_LIST ResourceList; PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor; @@ -595,7 +594,6 @@ Bus_PDO_QueryResources( ULONG ResourceListSize; ULONG i; - /* Get current resources */ Buffer.Length = 0; AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); @@ -619,8 +617,7 @@ Bus_PDO_QueryResources( resource= Buffer.Pointer; /* Count number of resources */ - Done = FALSE; - while (!Done) + while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG) { switch (resource->Type) { @@ -641,13 +638,9 @@ Bus_PDO_QueryResources( NumberOfResources++; break; } - case ACPI_RESOURCE_TYPE_END_TAG: - { - Done = TRUE; - break; - } default: { + DPRINT1("Unknown resource type: %d\n", resource->Type); break; } } @@ -659,7 +652,10 @@ Bus_PDO_QueryResources( ResourceList = (PCM_RESOURCE_LIST)ExAllocatePool(PagedPool, ResourceListSize); if (!ResourceList) - return FALSE; + { + ExFreePool(Buffer.Pointer); + return STATUS_INSUFFICIENT_RESOURCES; + } ResourceList->Count = 1; ResourceList->List[0].InterfaceType = Internal; /* FIXME */ ResourceList->List[0].BusNumber = 0; /* We're the only ACPI bus device in the system */ @@ -669,8 +665,7 @@ Bus_PDO_QueryResources( ResourceDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors; /* Fill resources list structure */ - Done = FALSE; - while (!Done) + while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG) { switch (resource->Type) { @@ -737,14 +732,8 @@ Bus_PDO_QueryResources( ResourceDescriptor++; break; } - case ACPI_RESOURCE_TYPE_END_TAG: - { - Done = TRUE; - break; - } default: { - DPRINT1("Unhandled resource type\n"); break; } } @@ -761,7 +750,6 @@ Bus_PDO_QueryResourceRequirements( PPDO_DEVICE_DATA DeviceData, PIRP Irp ) { - BOOLEAN Done; ULONG NumberOfResources = 0; ACPI_STATUS AcpiStatus; ACPI_BUFFER Buffer; @@ -796,8 +784,7 @@ Bus_PDO_QueryResourceRequirements( resource= Buffer.Pointer; /* Count number of resources */ - Done = FALSE; - while (!Done) + while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG) { switch (resource->Type) { @@ -818,11 +805,6 @@ Bus_PDO_QueryResourceRequirements( NumberOfResources++; break; } - case ACPI_RESOURCE_TYPE_END_TAG: - { - Done = TRUE; - break; - } default: { break; @@ -837,7 +819,7 @@ Bus_PDO_QueryResourceRequirements( if (!RequirementsList) { ExFreePool(Buffer.Pointer); - return STATUS_SUCCESS; + return STATUS_INSUFFICIENT_RESOURCES; } RequirementsList->ListSize = RequirementsListSize; RequirementsList->InterfaceType = Internal; @@ -850,8 +832,7 @@ Bus_PDO_QueryResourceRequirements( RequirementDescriptor = RequirementsList->List[0].Descriptors; /* Fill resources list structure */ - Done = FALSE; - while (!Done) + while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG) { switch (resource->Type) { @@ -920,14 +901,8 @@ Bus_PDO_QueryResourceRequirements( RequirementDescriptor++; break; } - case ACPI_RESOURCE_TYPE_END_TAG: - { - Done = TRUE; - break; - } default: { - DPRINT1("Unhandled resource type\n"); break; } } From 1f5e020800c9818e9c701fe897d7e4d6c5a6f6ef Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 11 Mar 2010 22:36:22 +0000 Subject: [PATCH 60/64] - Use the possible resources not the current resources for IRP_MN_QUERY_RESOURCE_REQUIREMENTS - Initialize MaximumVector for IRQs, MaximumChannel for DMA, and Alignment for Port svn path=/trunk/; revision=46121 --- reactos/drivers/bus/acpi/buspdo.c | 113 +++++++++++++++++------------- 1 file changed, 65 insertions(+), 48 deletions(-) diff --git a/reactos/drivers/bus/acpi/buspdo.c b/reactos/drivers/bus/acpi/buspdo.c index d085eed3cde..eb8f6686086 100644 --- a/reactos/drivers/bus/acpi/buspdo.c +++ b/reactos/drivers/bus/acpi/buspdo.c @@ -695,25 +695,25 @@ Bus_PDO_QueryResources( { ResourceDescriptor->Type = CmResourceTypeDma; ResourceDescriptor->Flags = 0; - switch (dma_data->Type) - { - case ACPI_TYPE_A: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break; - case ACPI_TYPE_B: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break; - case ACPI_TYPE_F: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break; - } - if (dma_data->BusMaster == ACPI_BUS_MASTER) - ResourceDescriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER; - switch (dma_data->Transfer) - { - case ACPI_TRANSFER_8: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8; break; - case ACPI_TRANSFER_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_16; break; - case ACPI_TRANSFER_8_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break; - } - ResourceDescriptor->u.Dma.Channel = dma_data->Channels[i]; + switch (dma_data->Type) + { + case ACPI_TYPE_A: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break; + case ACPI_TYPE_B: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break; + case ACPI_TYPE_F: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break; + } + if (dma_data->BusMaster == ACPI_BUS_MASTER) + ResourceDescriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER; + switch (dma_data->Transfer) + { + case ACPI_TRANSFER_8: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8; break; + case ACPI_TRANSFER_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_16; break; + case ACPI_TRANSFER_8_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break; + } + ResourceDescriptor->u.Dma.Channel = dma_data->Channels[i]; - ResourceDescriptor++; - } - break; + ResourceDescriptor++; + } + break; } case ACPI_RESOURCE_TYPE_IO: { @@ -757,24 +757,39 @@ Bus_PDO_QueryResourceRequirements( ULONG i, RequirementsListSize; PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; PIO_RESOURCE_DESCRIPTOR RequirementDescriptor; + BOOLEAN CurrentRes = FALSE; PAGED_CODE (); /* Get current resources */ - Buffer.Length = 0; - AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); - if ((!ACPI_SUCCESS(AcpiStatus) && AcpiStatus != AE_BUFFER_OVERFLOW) || - Buffer.Length == 0) + while (TRUE) { - return Irp->IoStatus.Status; + Buffer.Length = 0; + if (CurrentRes) + AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); + else + AcpiStatus = AcpiGetPossibleResources(DeviceData->AcpiHandle, &Buffer); + if ((!ACPI_SUCCESS(AcpiStatus) && AcpiStatus != AE_BUFFER_OVERFLOW) || + Buffer.Length == 0) + { + if (!CurrentRes) + CurrentRes = TRUE; + else + return Irp->IoStatus.Status; + } + else + break; } Buffer.Pointer = ExAllocatePool(PagedPool, Buffer.Length); if (!Buffer.Pointer) return STATUS_INSUFFICIENT_RESOURCES; - AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); + if (CurrentRes) + AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); + else + AcpiStatus = AcpiGetPossibleResources(DeviceData->AcpiHandle, &Buffer); if (!ACPI_SUCCESS(AcpiStatus)) { DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus); @@ -841,11 +856,12 @@ Bus_PDO_QueryResourceRequirements( ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*) &resource->Data; for (i = 0; i < irq_data->InterruptCount; i++) { - RequirementDescriptor->Option = 0; /* Required */ + RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; RequirementDescriptor->Type = CmResourceTypeInterrupt; RequirementDescriptor->ShareDisposition = (irq_data->Sharable == ACPI_SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive); RequirementDescriptor->Flags =(irq_data->Triggering == ACPI_LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED); - RequirementDescriptor->u.Interrupt.MinimumVector = irq_data->Interrupts[i]; + RequirementDescriptor->u.Interrupt.MinimumVector = + RequirementDescriptor->u.Interrupt.MaximumVector = irq_data->Interrupts[i]; RequirementDescriptor++; } @@ -858,27 +874,28 @@ Bus_PDO_QueryResourceRequirements( { RequirementDescriptor->Type = CmResourceTypeDma; RequirementDescriptor->Flags = 0; - switch (dma_data->Type) - { - case ACPI_TYPE_A: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break; - case ACPI_TYPE_B: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break; - case ACPI_TYPE_F: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break; - } - if (dma_data->BusMaster == ACPI_BUS_MASTER) - RequirementDescriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER; - switch (dma_data->Transfer) - { - case ACPI_TRANSFER_8: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_8; break; - case ACPI_TRANSFER_16: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_16; break; - case ACPI_TRANSFER_8_16: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break; - } + switch (dma_data->Type) + { + case ACPI_TYPE_A: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break; + case ACPI_TYPE_B: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break; + case ACPI_TYPE_F: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break; + } + if (dma_data->BusMaster == ACPI_BUS_MASTER) + RequirementDescriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER; + switch (dma_data->Transfer) + { + case ACPI_TRANSFER_8: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_8; break; + case ACPI_TRANSFER_16: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_16; break; + case ACPI_TRANSFER_8_16: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break; + } - RequirementDescriptor->Option = 0; /* Required */ - RequirementDescriptor->ShareDisposition = CmResourceShareDriverExclusive; - RequirementDescriptor->u.Dma.MinimumChannel = dma_data->Channels[i]; - RequirementDescriptor++; - } - break; + RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; + RequirementDescriptor->ShareDisposition = CmResourceShareDriverExclusive; + RequirementDescriptor->u.Dma.MinimumChannel = + RequirementDescriptor->u.Dma.MaximumChannel = dma_data->Channels[i]; + RequirementDescriptor++; + } + break; } case ACPI_RESOURCE_TYPE_IO: { @@ -891,10 +908,10 @@ Bus_PDO_QueryResourceRequirements( RequirementDescriptor->u.Port.Length = io_data->AddressLength; - RequirementDescriptor->Option = 0; /* Required */ + RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; RequirementDescriptor->Type = CmResourceTypePort; RequirementDescriptor->ShareDisposition = CmResourceShareDriverExclusive; - RequirementDescriptor->u.Port.Alignment = 1; /* Start address is specified, so it doesn't matter */ + RequirementDescriptor->u.Port.Alignment = io_data->Alignment; RequirementDescriptor->u.Port.MinimumAddress.QuadPart = io_data->Minimum; RequirementDescriptor->u.Port.MaximumAddress.QuadPart = io_data->Maximum; From c23fd826c4dcaec744e90095c552d3d5fdce8b1e Mon Sep 17 00:00:00 2001 From: Kamil Hornicek Date: Thu, 11 Mar 2010 23:11:00 +0000 Subject: [PATCH 61/64] [WIN32K] Prevent a possible memory leak. Use SURFACE_FreeSurfaceByHandle so we don't hit the "Object must not have a handle!" assert in GDIOBJ_FreeObj. svn path=/trunk/; revision=46123 --- reactos/subsystems/win32/win32k/eng/surface.c | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/reactos/subsystems/win32/win32k/eng/surface.c b/reactos/subsystems/win32/win32k/eng/surface.c index 1fcf4cc6b85..126347bff98 100644 --- a/reactos/subsystems/win32/win32k/eng/surface.c +++ b/reactos/subsystems/win32/win32k/eng/surface.c @@ -466,6 +466,7 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo, SURFOBJ *pso; PSURFACE psurf; SIZEL LocalSize; + BOOLEAN AllocatedLocally = FALSE; /* * First, check the format so we can get the aligned scanline width. @@ -526,7 +527,7 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo, Size = BitmapInfo->Height * ScanLine; } - if (Size) + if (Size) { /* Check for allocation flag */ if (BitmapInfo->Flags & BMF_USERMEM) @@ -541,7 +542,7 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo, Size, TAG_DIB); } - + AllocatedLocally = TRUE; /* Bail out if that failed */ if (!Bits) return NULL; } @@ -554,14 +555,24 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo, /* Allocate the actual surface object structure */ psurf = SURFACE_AllocSurfaceWithHandle(); - if (!psurf) return NULL; - + if (!psurf) + { + if(Bits && AllocatedLocally) + { + if(BitmapInfo->Flags & BMF_USERMEM) + EngFreeUserMem(Bits); + else + EngFreeMem(Bits); + } + return NULL; + } + /* Lock down the surface */ if (!SURFACE_InitBitsLock(psurf)) { /* Bail out if that failed */ SURFACE_UnlockSurface(psurf); - SURFACE_FreeSurface(psurf); + SURFACE_FreeSurfaceByHandle(psurf->BaseObject.hHmgr); return NULL; } From bcf41654caf92333d2e7b88042644012107a83e9 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 12 Mar 2010 04:42:23 +0000 Subject: [PATCH 62/64] - Fix acpi_bus_receive_event and acpi_bus_generate_event which will be used for button events later - Uncomment and fix the locking code that protects the event queue and driver list svn path=/trunk/; revision=46127 --- reactos/drivers/bus/acpi/busmgr/bus.c | 89 ++++++++++++++----------- reactos/drivers/bus/acpi/include/glue.h | 2 + 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/reactos/drivers/bus/acpi/busmgr/bus.c b/reactos/drivers/bus/acpi/busmgr/bus.c index 88589023365..949cfd2bd65 100644 --- a/reactos/drivers/bus/acpi/busmgr/bus.c +++ b/reactos/drivers/bus/acpi/busmgr/bus.c @@ -48,7 +48,7 @@ ACPI_MODULE_NAME ("acpi_bus") #define HAS_SIBLINGS(d) (((d)->parent) && ((d)->node.next != &(d)->parent->children)) #define NODE_TO_DEVICE(n) (list_entry(n, struct acpi_device, node)) -extern int event_is_open; +int event_is_open; extern void acpi_pic_sci_set_trigger(unsigned int irq, UINT16 trigger); typedef int (*acpi_bus_walk_callback)(struct acpi_device*, int, void*); @@ -57,6 +57,7 @@ struct acpi_device *acpi_root; KSPIN_LOCK acpi_bus_event_lock; LIST_HEAD(acpi_bus_event_list); //DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue); +KEVENT AcpiEventQueue; static int @@ -463,6 +464,7 @@ acpi_bus_generate_event ( { struct acpi_bus_event *event = NULL; //unsigned long flags = 0; + KIRQL OldIrql; DPRINT1("acpi_bus_generate_event"); @@ -470,8 +472,8 @@ acpi_bus_generate_event ( return_VALUE(AE_BAD_PARAMETER); /* drop event on the floor if no one's listening */ - //if (!event_is_open) - // return_VALUE(0); + if (!event_is_open) + return_VALUE(0); event = ExAllocatePool(NonPagedPool,sizeof(struct acpi_bus_event)); if (!event) @@ -483,9 +485,12 @@ acpi_bus_generate_event ( event->data = data; //spin_lock_irqsave(&acpi_bus_event_lock, flags); + KeAcquireSpinLock(&acpi_bus_event_lock, &OldIrql); list_add_tail(&event->node, &acpi_bus_event_list); + KeReleaseSpinLock(&acpi_bus_event_lock, OldIrql); //spin_unlock_irqrestore(&acpi_bus_event_lock, flags); + KeSetEvent(&AcpiEventQueue, IO_NO_INCREMENT, FALSE); //wake_up_interruptible(&acpi_bus_event_queue); return_VALUE(0); @@ -495,44 +500,43 @@ int acpi_bus_receive_event ( struct acpi_bus_event *event) { - //unsigned long flags = 0; - //struct acpi_bus_event *entry = NULL; +// unsigned long flags = 0; + struct acpi_bus_event *entry = NULL; + KIRQL OldIrql; //DECLARE_WAITQUEUE(wait, current); DPRINT1("acpi_bus_receive_event"); - //if (!event) - // return AE_BAD_PARAMETER; + if (!event) + return AE_BAD_PARAMETER; - //if (list_empty(&acpi_bus_event_list)) { + event_is_open++; + KeWaitForSingleObject(&AcpiEventQueue, + Executive, + KernelMode, + FALSE, + NULL); + event_is_open--; + KeClearEvent(&AcpiEventQueue); - // set_current_state(TASK_INTERRUPTIBLE); - // add_wait_queue(&acpi_bus_event_queue, &wait); + if (list_empty(&acpi_bus_event_list)) + return_VALUE(AE_NOT_FOUND); - // if (list_empty(&acpi_bus_event_list)) - // schedule(); +// spin_lock_irqsave(&acpi_bus_event_lock, flags); + KeAcquireSpinLock(&acpi_bus_event_lock, &OldIrql); + entry = list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node); + if (entry) + list_del(&entry->node); + KeReleaseSpinLock(&acpi_bus_event_lock, OldIrql); +// spin_unlock_irqrestore(&acpi_bus_event_lock, flags); - // remove_wait_queue(&acpi_bus_event_queue, &wait); - // set_current_state(TASK_RUNNING); + if (!entry) + return_VALUE(AE_NOT_FOUND); - // if (signal_pending(current)) - // return_VALUE(-ERESTARTSYS); - //} + memcpy(event, entry, sizeof(struct acpi_bus_event)); - //spin_lock_irqsave(&acpi_bus_event_lock, flags); - //entry = list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node); - //if (entry) - // list_del(&entry->node); - //spin_unlock_irqrestore(&acpi_bus_event_lock, flags); - - //if (!entry) - // return_VALUE(AE_NOT_FOUND); - - //memcpy(event, entry, sizeof(struct acpi_bus_event)); - - //kfree(entry); - UNIMPLEMENTED; + ExFreePool(entry); return_VALUE(0); } @@ -789,6 +793,7 @@ acpi_bus_notify ( static LIST_HEAD(acpi_bus_drivers); //static DECLARE_MUTEX(acpi_bus_drivers_lock); +static FAST_MUTEX acpi_bus_drivers_lock; /** @@ -914,9 +919,9 @@ acpi_bus_attach ( if (result) return_VALUE(result); - //down(&acpi_bus_drivers_lock); + down(&acpi_bus_drivers_lock); ++driver->references; - //up(&acpi_bus_drivers_lock); + up(&acpi_bus_drivers_lock); return_VALUE(0); } @@ -953,9 +958,9 @@ acpi_bus_unattach ( device->driver = NULL; acpi_driver_data(device) = NULL; - //down(&acpi_bus_drivers_lock); + down(&acpi_bus_drivers_lock); driver->references--; - //up(&acpi_bus_drivers_lock); + up(&acpi_bus_drivers_lock); return_VALUE(0); } @@ -978,7 +983,7 @@ acpi_bus_find_driver ( if (!device || device->driver) return_VALUE(AE_BAD_PARAMETER); - //down(&acpi_bus_drivers_lock); + down(&acpi_bus_drivers_lock); list_for_each(entry, &acpi_bus_drivers) { @@ -994,7 +999,7 @@ acpi_bus_find_driver ( break; } - //up(&acpi_bus_drivers_lock); + up(&acpi_bus_drivers_lock); return_VALUE(result); } @@ -1016,9 +1021,9 @@ acpi_bus_register_driver ( //if (acpi_disabled) // return_VALUE(AE_NOT_FOUND); - //down(&acpi_bus_drivers_lock); + down(&acpi_bus_drivers_lock); list_add_tail(&driver->node, &acpi_bus_drivers); - //up(&acpi_bus_drivers_lock); + up(&acpi_bus_drivers_lock); acpi_bus_walk(acpi_root, acpi_bus_attach, WALK_DOWN, driver); @@ -1045,9 +1050,9 @@ acpi_bus_unregister_driver ( if (driver->references) return; - //down(&acpi_bus_drivers_lock); + down(&acpi_bus_drivers_lock); list_del(&driver->node); - //up(&acpi_bus_drivers_lock); + up(&acpi_bus_drivers_lock); return; } @@ -1786,6 +1791,10 @@ acpi_init (void) DPRINT("Subsystem revision %08x\n",ACPI_CA_VERSION); + KeInitializeSpinLock(&acpi_bus_event_lock); + KeInitializeEvent(&AcpiEventQueue, NotificationEvent, FALSE); + ExInitializeFastMutex(&acpi_bus_drivers_lock); + result = acpi_bus_init(); //if (!result) { diff --git a/reactos/drivers/bus/acpi/include/glue.h b/reactos/drivers/bus/acpi/include/glue.h index 6b45ba8f42c..7dd950a0691 100644 --- a/reactos/drivers/bus/acpi/include/glue.h +++ b/reactos/drivers/bus/acpi/include/glue.h @@ -26,5 +26,7 @@ typedef int (*acpi_table_handler) (ACPI_TABLE_HEADER *table); typedef int (*acpi_table_entry_handler) (ACPI_SUBTABLE_HEADER *header, const unsigned long end); +#define down(mutex) ExAcquireFastMutex(mutex) +#define up(mutex) ExReleaseFastMutex(mutex) #endif From fcf8a0b5151e684ce8e86ff18a3bf68937a8cb60 Mon Sep 17 00:00:00 2001 From: Sylvain Petreolle Date: Fri, 12 Mar 2010 15:33:10 +0000 Subject: [PATCH 63/64] [KSPROXY] Comment out a reference to non existent "resource." file in the visual studio generated resource file. This issue was likely ignored by the buildbot. svn path=/trunk/; revision=46133 --- reactos/dll/directx/ksproxy/ksproxy.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/directx/ksproxy/ksproxy.rc b/reactos/dll/directx/ksproxy/ksproxy.rc index f917d67fa1d..2539cac432b 100644 --- a/reactos/dll/directx/ksproxy/ksproxy.rc +++ b/reactos/dll/directx/ksproxy/ksproxy.rc @@ -1,6 +1,6 @@ // Microsoft Visual C++ generated resource script. // -#include "resource." +//#include "resource." #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// From d647d02aa43c24c81d9fa9bb2506fd2840ee9973 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Fri, 12 Mar 2010 16:11:28 +0000 Subject: [PATCH 64/64] - Update more menu types and flags. svn path=/trunk/; revision=46134 --- reactos/include/psdk/winuser.h | 10 ++++++++++ reactos/include/reactos/win32k/ntuser.h | 18 +++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/reactos/include/psdk/winuser.h b/reactos/include/psdk/winuser.h index 8700be78f5d..57c1ac13aac 100644 --- a/reactos/include/psdk/winuser.h +++ b/reactos/include/psdk/winuser.h @@ -2446,8 +2446,18 @@ extern "C" { #define ODS_DISABLED 4 #define ODS_CHECKED 8 #define ODS_FOCUS 16 +#if(WINVER >= 0x0400) #define ODS_DEFAULT 32 #define ODS_COMBOBOXEDIT 4096 +#endif +#if(WINVER >= 0x0500) +#define ODS_HOTLIGHT 0x0040 +#define ODS_INACTIVE 0x0080 +#if(_WIN32_WINNT >= 0x0500) +#define ODS_NOACCEL 0x0100 +#define ODS_NOFOCUSRECT 0x0200 +#endif +#endif #define IDHOT_SNAPWINDOW (-1) #define IDHOT_SNAPDESKTOP (-2) #define DBWF_LPARAMPOINTER 0x8000 diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index a9feb1fb69f..8e59d26b4cc 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -221,12 +221,15 @@ C_ASSERT(sizeof(CLIENTINFO) == FIELD_OFFSET(TEB, glDispatchTable) - FIELD_OFFSET #define GetWin32ClientInfo() ((PCLIENTINFO)(NtCurrentTeb()->Win32ClientInfo)) +/* Menu Item fType. */ +#define MFT_RTOL 0x6000 + typedef struct tagITEM { UINT fType; UINT fState; UINT wID; - struct tagMENU* spSubMenu; /* Pop-up menu. */ + struct tagMENU* spSubMenu; /* Pop-up menu. */ HANDLE hbmpChecked; HANDLE hbmpUnchecked; USHORT* lpstr; /* Item text pointer. */ @@ -250,12 +253,21 @@ typedef struct tagMENULIST struct tagMENU* pMenu; } MENULIST, *PMENULIST; +/* Menu fFlags, upper byte is MNS_X style flags. */ +#define MNF_POPUP 0x0001 +#define MNF_UNDERLINE 0x0004 +#define MNF_INACTIVE 0x0010 +#define MNF_RTOL 0x0020 +#define MNF_DESKTOPMN 0x0040 +#define MNF_SYSDESKMN 0x0080 +#define MNF_SYSSUBMENU 0x0100 + typedef struct tagMENU { PROCDESKHEAD head; - ULONG fFlags; /* Menu flags (MF_POPUP, MF_SYSMENU) */ + ULONG fFlags; /* [Style flags | Menu flags] */ INT iItem; /* nPos of selected item, if -1 not selected. */ - UINT cAlloced; /* Number of allocated items. */ + UINT cAlloced; /* Number of allocated items. Inc's of 8 */ UINT cItems; /* Number of items in the menu */ ULONG cxMenu; /* Width of the whole menu */ ULONG cyMenu; /* Height of the whole menu */