[PATCH] Tests that prove ntdll has no notion of HKCR.

2013-05-21 Thread George Stephanos
As instructed, I added a few lines to the already written tests that
confirm my claim.

Part of the research of the registry merging project was to determine
where the implementation is going to be written: advapi32, ntdll or
the server itself. The server choice was dismissed since HKCR isn't
stored and rather fetched live. These tests prove that advapi32 calls
that reference HKCR are either pointed there to \REGISTRY\MACHINE or
\REGISTRY\USER and hence, that the merge is to be done in advapi32.

http://newtestbot.winehq.org/JobDetails.pl?Key=976
---
 dlls/advapi32/tests/registry.c | 31 ++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index b2483a7..ea61471 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -43,6 +43,7 @@ static DWORD (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR);
 static DWORD (WINAPI *pRegDeleteKeyExA)(HKEY,LPCSTR,REGSAM,DWORD);
 static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
 static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE);
+static NTSTATUS (WINAPI * pNtQueryKey)(HANDLE,int,PVOID,ULONG,PULONG);
 static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(UNICODE_STRING*);
 static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);
 
@@ -136,6 +137,7 @@ static void InitFunctionPtrs(void)
 pRtlFormatCurrentUserKeyPath = (void *)GetProcAddress( hntdll, 
RtlFormatCurrentUserKeyPath );
 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, 
RtlFreeUnicodeString);
 pNtDeleteKey = (void *)GetProcAddress( hntdll, NtDeleteKey );
+pNtQueryKey = (void *)GetProcAddress( hntdll, NtQueryKey );
 }
 
 /* delete key and all its subkeys */
@@ -2099,10 +2101,12 @@ static void test_redirection(void)
 
 static void test_classesroot(void)
 {
+static const WCHAR reg_user[] = { 
'\\','R','E','G','I','S','T','R','Y','\\','U','S','E','R',0 };
+static const WCHAR reg_machine[] = { 
'\\','R','E','G','I','S','T','R','Y','\\','M','A','C','H','I','N','E',0 };
 HKEY hkey, hklm, hkcr, hkeysub1, hklmsub1, hkcrsub1, hklmsub2, hkcrsub2;
 DWORD size = 8;
 DWORD type = REG_SZ;
-static CHAR buffer[8];
+static CHAR buffer[100*sizeof(WCHAR)];
 LONG res;
 
 /* create a key in the user's classes */
@@ -2132,6 +2136,11 @@ static void test_classesroot(void)
 RegCloseKey( hkey );
 return;
 }
+pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buffer, 
sizeof(buffer)/sizeof(buffer[0]), (ULONG*)res );
+todo_wine ok( CompareStringW( LOCALE_INVARIANT, NORM_IGNORECASE, 
+(WCHAR*)(buffer)+2, sizeof(reg_user)/sizeof(reg_user[0]), 
+reg_user, sizeof(reg_user)/sizeof(reg_user[0]) ) == CSTR_EQUAL,
+key not from \\REGISTRY\\USER\n);
 
 /* set a value in user's classes */
 res = RegSetValueExA(hkey, val1, 0, REG_SZ, (const BYTE *)user, 
sizeof(user));
@@ -2200,6 +2209,11 @@ static void test_classesroot(void)
 RegCloseKey( hklm );
 return;
 }
+pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buffer, 
sizeof(buffer)/sizeof(buffer[0]), (ULONG*)res );
+todo_wine ok( CompareStringW( LOCALE_INVARIANT, NORM_IGNORECASE, 
+(WCHAR*)(buffer)+2, sizeof(reg_user)/sizeof(reg_user[0]), 
+reg_user, sizeof(reg_user)/sizeof(reg_user[0]) ) == CSTR_EQUAL,
+key not from \\REGISTRY\\USER\n);
 
 /* set a value in hklm classes */
 res = RegSetValueExA(hklm, val2, 0, REG_SZ, (const BYTE *)hklm, 
sizeof(hklm));
@@ -2227,6 +2241,11 @@ static void test_classesroot(void)
  KEY_QUERY_VALUE|KEY_SET_VALUE, hkcr );
 ok(res == ERROR_SUCCESS,
test key not found in hkcr: %d\n, res);
+pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buffer, 
sizeof(buffer)/sizeof(buffer[0]), (ULONG*)res );
+todo_wine ok( CompareStringW( LOCALE_INVARIANT, NORM_IGNORECASE, 
+(WCHAR*)(buffer)+2, sizeof(reg_user)/sizeof(reg_user[0]), 
+reg_user, sizeof(reg_user)/sizeof(reg_user[0]) ) == CSTR_EQUAL,
+key not from \\REGISTRY\\USER\n);
 
 /* set a value in user's classes */
 res = RegSetValueExA(hkey, val2, 0, REG_SZ, (const BYTE *)user, 
sizeof(user));
@@ -2267,6 +2286,11 @@ static void test_classesroot(void)
 /* try to open that subkey in hkcr */
 res = RegOpenKeyExA( hkcr, subkey1, 0, KEY_QUERY_VALUE|KEY_SET_VALUE, 
hkcrsub1 );
 ok(res == ERROR_SUCCESS, test key not found in hkcr: %d\n, res);
+pNtQueryKey( hkcrsub1, 3 /*KeyNameInformation*/, buffer, 
sizeof(buffer)/sizeof(buffer[0]), (ULONG*)res );
+ok( CompareStringW( LOCALE_INVARIANT, NORM_IGNORECASE, 
+(WCHAR*)(buffer)+2, sizeof(reg_machine)/sizeof(reg_machine[0]), 
+reg_machine, sizeof(reg_machine)/sizeof(reg_machine[0]) ) == 
CSTR_EQUAL,
+key not from \\REGISTRY\\MACHINE\n);
 
 /* set a value in hklm classes */
 res = RegSetValueExA(hklmsub1, subval1, 0, REG_SZ, (const BYTE *)hklm, 
sizeof(hklm));
@@ -2326,6 +2350,11 @@ 

Re: [PATCH] Tests that prove ntdll has no notion of HKCR.

2013-05-20 Thread Juan Lang
Hi George,

 static void test_classesroot(void)
  {
 +static const WCHAR reg_user[] = {
 '\\','R','E','G','I','S','T','R','Y','\\','U','S','E','R' };
 +static const WCHAR reg_machine[] = {
 '\\','R','E','G','I','S','T','R','Y','\\','M','A','C','H','I','N','E' };


Almost, but these have to be NULL terminated, i.e.

 +static const WCHAR reg_user[] = {
 '\\','R','E','G','I','S','T','R','Y','\\','U','S','E','R',0 };
 +static const WCHAR reg_machine[] = {
 '\\','R','E','G','I','S','T','R','Y','\\','M','A','C','H','I','N','E',0 };

--Juan



Re: [PATCH] Tests that prove ntdll has no notion of HKCR.

2013-05-19 Thread Dmitry Timoshkov
George Stephanos gaf.stepha...@gmail.com wrote:

  Ah, well, strcmp comes from the C library your compiler uses. wcsncmp can
  only come from msvcrt. When compiling for Wine, this can result in mixing C
  runtime libraries, and hilarity can result.
...
 Perhaps I could just use memcmp?

Use lstrcmpW/lstrcmpiW for unicode string comparisons, and lstrcmpA/lstrcmpiA
for ANSI strings (you can't use glibc ones because of locale differencies),
they are kernel32 exports, and exist in all Windows versions.

-- 
Dmitry.




Re: [PATCH] Tests that prove ntdll has no notion of HKCR.

2013-05-19 Thread George Stephanos
On Sun, May 19, 2013 at 8:20 AM, Dmitry Timoshkov dmi...@baikal.ru wrote:

 George Stephanos gaf.stepha...@gmail.com wrote:

   Ah, well, strcmp comes from the C library your compiler uses. wcsncmp
 can
   only come from msvcrt. When compiling for Wine, this can result in
 mixing C
   runtime libraries, and hilarity can result.
 ...
  Perhaps I could just use memcmp?

 Use lstrcmpW/lstrcmpiW for unicode string comparisons, and
 lstrcmpA/lstrcmpiA
 for ANSI strings (you can't use glibc ones because of locale differencies),
 they are kernel32 exports, and exist in all Windows versions.

 --
 Dmitry.


Well I do need the functions to be boundable by length, or else I'd need to
do some copying.
I'm going to post the updated patch with memcmp until a better solution
comes up.



[PATCH] Tests that prove ntdll has no notion of HKCR.

2013-05-19 Thread George Stephanos
As instructed, I added a few lines to the already written tests that
confirm my claim.

Part of the research of the registry merging project was to determine
where the implementation is going to be written: advapi32, ntdll or
the server itself. The server choice was dismissed since HKCR isn't
stored and rather fetched live. These tests prove that advapi32 calls
that reference HKCR are either pointed there to \REGISTRY\MACHINE or
\REGISTRY\USER and hence, that the merge is to be done in advapi32.

http://newtestbot.winehq.org/JobDetails.pl?Key=976
---
 dlls/advapi32/tests/registry.c | 21 -
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index b2483a7..0113639 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -43,6 +43,7 @@ static DWORD (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR);
 static DWORD (WINAPI *pRegDeleteKeyExA)(HKEY,LPCSTR,REGSAM,DWORD);
 static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
 static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE);
+static NTSTATUS (WINAPI * pNtQueryKey)(HANDLE,int,PVOID,ULONG,PULONG);
 static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(UNICODE_STRING*);
 static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);
 
@@ -136,6 +137,7 @@ static void InitFunctionPtrs(void)
 pRtlFormatCurrentUserKeyPath = (void *)GetProcAddress( hntdll, 
RtlFormatCurrentUserKeyPath );
 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, 
RtlFreeUnicodeString);
 pNtDeleteKey = (void *)GetProcAddress( hntdll, NtDeleteKey );
+pNtQueryKey = (void *)GetProcAddress( hntdll, NtQueryKey );
 }
 
 /* delete key and all its subkeys */
@@ -2099,10 +2101,12 @@ static void test_redirection(void)
 
 static void test_classesroot(void)
 {
+static const WCHAR reg_user[] = { 
'\\','R','E','G','I','S','T','R','Y','\\','U','S','E','R' };
+static const WCHAR reg_machine[] = { 
'\\','R','E','G','I','S','T','R','Y','\\','M','A','C','H','I','N','E' };
 HKEY hkey, hklm, hkcr, hkeysub1, hklmsub1, hkcrsub1, hklmsub2, hkcrsub2;
 DWORD size = 8;
 DWORD type = REG_SZ;
-static CHAR buffer[8];
+static CHAR buffer[100*sizeof(WCHAR)];
 LONG res;
 
 /* create a key in the user's classes */
@@ -2132,6 +2136,9 @@ static void test_classesroot(void)
 RegCloseKey( hkey );
 return;
 }
+pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buffer, 
sizeof(buffer)/sizeof(buffer[0]), (ULONG*)res );
+todo_wine ok( !memcmp( (WCHAR*)(buffer)+2, reg_user, 
sizeof(reg_user)/sizeof(reg_user[0]) ),
+key not from \\REGISTRY\\USER\n);
 
 /* set a value in user's classes */
 res = RegSetValueExA(hkey, val1, 0, REG_SZ, (const BYTE *)user, 
sizeof(user));
@@ -2200,6 +2207,9 @@ static void test_classesroot(void)
 RegCloseKey( hklm );
 return;
 }
+pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buffer, 
sizeof(buffer)/sizeof(buffer[0]), (ULONG*)res );
+todo_wine ok( !memcmp( (WCHAR*)(buffer)+2, reg_user, 
sizeof(reg_user)/sizeof(reg_user[0]) ),
+key not from \\REGISTRY\\USER\n);
 
 /* set a value in hklm classes */
 res = RegSetValueExA(hklm, val2, 0, REG_SZ, (const BYTE *)hklm, 
sizeof(hklm));
@@ -2227,6 +2237,9 @@ static void test_classesroot(void)
  KEY_QUERY_VALUE|KEY_SET_VALUE, hkcr );
 ok(res == ERROR_SUCCESS,
test key not found in hkcr: %d\n, res);
+pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buffer, 
sizeof(buffer)/sizeof(buffer[0]), (ULONG*)res );
+todo_wine ok( !memcmp( (WCHAR*)(buffer)+2, reg_user, 
sizeof(reg_user)/sizeof(reg_user[0]) ),
+key not from \\REGISTRY\\USER\n);
 
 /* set a value in user's classes */
 res = RegSetValueExA(hkey, val2, 0, REG_SZ, (const BYTE *)user, 
sizeof(user));
@@ -2267,6 +2280,9 @@ static void test_classesroot(void)
 /* try to open that subkey in hkcr */
 res = RegOpenKeyExA( hkcr, subkey1, 0, KEY_QUERY_VALUE|KEY_SET_VALUE, 
hkcrsub1 );
 ok(res == ERROR_SUCCESS, test key not found in hkcr: %d\n, res);
+pNtQueryKey( hkcrsub1, 3 /*KeyNameInformation*/, buffer, 
sizeof(buffer)/sizeof(buffer[0]), (ULONG*)res );
+ok( !memcmp( (WCHAR*)(buffer)+2, reg_machine, 
sizeof(reg_machine)/sizeof(reg_machine[0]) ),
+key not from \\REGISTRY\\MACHINE\n);
 
 /* set a value in hklm classes */
 res = RegSetValueExA(hklmsub1, subval1, 0, REG_SZ, (const BYTE *)hklm, 
sizeof(hklm));
@@ -2326,6 +2342,9 @@ static void test_classesroot(void)
 /* new subkey in hkcr */
 if (RegCreateKeyExA( hkcr, subkey2, 0, NULL, 0,
  KEY_QUERY_VALUE|KEY_SET_VALUE, NULL, hkcrsub2, NULL 
)) return;
+pNtQueryKey( hkcrsub2, 3 /*KeyNameInformation*/, buffer, 
sizeof(buffer)/sizeof(buffer[0]), (ULONG*)res );
+ok( !memcmp( (WCHAR*)(buffer)+2, reg_machine, 
sizeof(reg_machine)/sizeof(reg_machine[0]) ),
+key not from \\REGISTRY\\MACHINE\n);
 res = 

Re: [PATCH] Tests that prove ntdll has no notion of HKCR.

2013-05-19 Thread Dmitry Timoshkov
George Stephanos gaf.stepha...@gmail.com wrote:

 Well I do need the functions to be boundable by length, or else I'd need to
 do some copying.
 I'm going to post the updated patch with memcmp until a better solution
 comes up.

Then CompareStringA/W would better work for you.

-- 
Dmitry.




[PATCH] Tests that prove ntdll has no notion of HKCR.

2013-05-19 Thread George Stephanos
As instructed, I added a few lines to the already written tests that
confirm my claim.

Part of the research of the registry merging project was to determine
where the implementation is going to be written: advapi32, ntdll or
the server itself. The server choice was dismissed since HKCR isn't
stored and rather fetched live. These tests prove that advapi32 calls
that reference HKCR are either pointed there to \REGISTRY\MACHINE or
\REGISTRY\USER and hence, that the merge is to be done in advapi32.

http://newtestbot.winehq.org/JobDetails.pl?Key=976
---
 dlls/advapi32/tests/registry.c | 31 ++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index b2483a7..d006de9 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -43,6 +43,7 @@ static DWORD (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR);
 static DWORD (WINAPI *pRegDeleteKeyExA)(HKEY,LPCSTR,REGSAM,DWORD);
 static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
 static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE);
+static NTSTATUS (WINAPI * pNtQueryKey)(HANDLE,int,PVOID,ULONG,PULONG);
 static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(UNICODE_STRING*);
 static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);
 
@@ -136,6 +137,7 @@ static void InitFunctionPtrs(void)
 pRtlFormatCurrentUserKeyPath = (void *)GetProcAddress( hntdll, 
RtlFormatCurrentUserKeyPath );
 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, 
RtlFreeUnicodeString);
 pNtDeleteKey = (void *)GetProcAddress( hntdll, NtDeleteKey );
+pNtQueryKey = (void *)GetProcAddress( hntdll, NtQueryKey );
 }
 
 /* delete key and all its subkeys */
@@ -2099,10 +2101,12 @@ static void test_redirection(void)
 
 static void test_classesroot(void)
 {
+static const WCHAR reg_user[] = { 
'\\','R','E','G','I','S','T','R','Y','\\','U','S','E','R' };
+static const WCHAR reg_machine[] = { 
'\\','R','E','G','I','S','T','R','Y','\\','M','A','C','H','I','N','E' };
 HKEY hkey, hklm, hkcr, hkeysub1, hklmsub1, hkcrsub1, hklmsub2, hkcrsub2;
 DWORD size = 8;
 DWORD type = REG_SZ;
-static CHAR buffer[8];
+static CHAR buffer[100*sizeof(WCHAR)];
 LONG res;
 
 /* create a key in the user's classes */
@@ -2132,6 +2136,11 @@ static void test_classesroot(void)
 RegCloseKey( hkey );
 return;
 }
+pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buffer, 
sizeof(buffer)/sizeof(buffer[0]), (ULONG*)res );
+todo_wine ok( CompareStringW( LOCALE_INVARIANT, NORM_IGNORECASE, 
+(WCHAR*)(buffer)+2, sizeof(reg_user)/sizeof(reg_user[0]), 
+reg_user, sizeof(reg_user)/sizeof(reg_user[0]) ) == CSTR_EQUAL,
+key not from \\REGISTRY\\USER\n);
 
 /* set a value in user's classes */
 res = RegSetValueExA(hkey, val1, 0, REG_SZ, (const BYTE *)user, 
sizeof(user));
@@ -2200,6 +2209,11 @@ static void test_classesroot(void)
 RegCloseKey( hklm );
 return;
 }
+pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buffer, 
sizeof(buffer)/sizeof(buffer[0]), (ULONG*)res );
+todo_wine ok( CompareStringW( LOCALE_INVARIANT, NORM_IGNORECASE, 
+(WCHAR*)(buffer)+2, sizeof(reg_user)/sizeof(reg_user[0]), 
+reg_user, sizeof(reg_user)/sizeof(reg_user[0]) ) == CSTR_EQUAL,
+key not from \\REGISTRY\\USER\n);
 
 /* set a value in hklm classes */
 res = RegSetValueExA(hklm, val2, 0, REG_SZ, (const BYTE *)hklm, 
sizeof(hklm));
@@ -2227,6 +2241,11 @@ static void test_classesroot(void)
  KEY_QUERY_VALUE|KEY_SET_VALUE, hkcr );
 ok(res == ERROR_SUCCESS,
test key not found in hkcr: %d\n, res);
+pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buffer, 
sizeof(buffer)/sizeof(buffer[0]), (ULONG*)res );
+todo_wine ok( CompareStringW( LOCALE_INVARIANT, NORM_IGNORECASE, 
+(WCHAR*)(buffer)+2, sizeof(reg_user)/sizeof(reg_user[0]), 
+reg_user, sizeof(reg_user)/sizeof(reg_user[0]) ) == CSTR_EQUAL,
+key not from \\REGISTRY\\USER\n);
 
 /* set a value in user's classes */
 res = RegSetValueExA(hkey, val2, 0, REG_SZ, (const BYTE *)user, 
sizeof(user));
@@ -2267,6 +2286,11 @@ static void test_classesroot(void)
 /* try to open that subkey in hkcr */
 res = RegOpenKeyExA( hkcr, subkey1, 0, KEY_QUERY_VALUE|KEY_SET_VALUE, 
hkcrsub1 );
 ok(res == ERROR_SUCCESS, test key not found in hkcr: %d\n, res);
+pNtQueryKey( hkcrsub1, 3 /*KeyNameInformation*/, buffer, 
sizeof(buffer)/sizeof(buffer[0]), (ULONG*)res );
+ok( CompareStringW( LOCALE_INVARIANT, NORM_IGNORECASE, 
+(WCHAR*)(buffer)+2, sizeof(reg_machine)/sizeof(reg_machine[0]), 
+reg_machine, sizeof(reg_machine)/sizeof(reg_machine[0]) ) == 
CSTR_EQUAL,
+key not from \\REGISTRY\\MACHINE\n);
 
 /* set a value in hklm classes */
 res = RegSetValueExA(hklmsub1, subval1, 0, REG_SZ, (const BYTE *)hklm, 
sizeof(hklm));
@@ -2326,6 +2350,11 @@ 

Re: [PATCH] Tests that prove ntdll has no notion of HKCR.

2013-05-18 Thread Juan Lang
Hi George,
(consider subscribing to wine-devel so your emails don't get stuck in
moderation.)


On Sat, May 11, 2013 at 7:43 AM, George Stephanos
gaf.stepha...@gmail.comwrote:

 As instructed, I added a few lines to the already written tests that
 confirm my claim.

 Part of the research of the registry merging project was to determine
 where the implementation is going to be written: advapi32, ntdll or
 the server itself. The server choice was dismissed since HKCR isn't
 stored and rather fetched live. These tests prove that advapi32 calls
 that reference HKCR are either pointed there to \REGISTRY\MACHINE or
 \REGISTRY\USER and hence, that the merge is to be done in advapi32.

 http://newtestbot.winehq.org/JobDetails.pl?Key=976
 ---
  dlls/advapi32/tests/registry.c | 18 ++
  1 file changed, 18 insertions(+)

 diff --git a/dlls/advapi32/tests/registry.c
 b/dlls/advapi32/tests/registry.c
 index b2483a7..8437e4d 100644
 --- a/dlls/advapi32/tests/registry.c
 +++ b/dlls/advapi32/tests/registry.c
 @@ -43,6 +43,7 @@ static DWORD (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR);
  static DWORD (WINAPI *pRegDeleteKeyExA)(HKEY,LPCSTR,REGSAM,DWORD);
  static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
  static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE);
 +static NTSTATUS (WINAPI * pNtQueryKey)(HANDLE,int,PVOID,ULONG,PULONG);
  static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(UNICODE_STRING*);
  static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);

 @@ -136,6 +137,7 @@ static void InitFunctionPtrs(void)
  pRtlFormatCurrentUserKeyPath = (void *)GetProcAddress( hntdll,
 RtlFormatCurrentUserKeyPath );
  pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll,
 RtlFreeUnicodeString);
  pNtDeleteKey = (void *)GetProcAddress( hntdll, NtDeleteKey );
 +pNtQueryKey = (void *)GetProcAddress( hntdll, NtQueryKey );
  }

  /* delete key and all its subkeys */
 @@ -2104,6 +2106,7 @@ static void test_classesroot(void)
  DWORD type = REG_SZ;
  static CHAR buffer[8];
  LONG res;
 +void *buf = malloc(300*sizeof(wchar_t));


You could just allocate a buffer on the stack. 300 is probably overkill,
100 looks like it would do it. You want to use WCHAR rather than wchar_t.

 /* create a key in the user's classes */
  if (!RegOpenKeyA( HKEY_CURRENT_USER,
 Software\\Classes\\WineTestCls, hkey ))
 @@ -2132,6 +2135,9 @@ static void test_classesroot(void)
  RegCloseKey( hkey );
  return;
  }
 +pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buf,
 500*sizeof(wchar_t), (ULONG*)res );


Not that this will actually overflow, but you specify 500, but only
allocated 300. A straightforward way to accomplish agreement is to use
sizeof(buf) / sizeof(buf[0]) as the size, if it's not dynamically allocated.


 +ok( wcsncmp((wchar_t*)buf+2, L\\REGISTRY\\USER, 14) == 0,
 +key not from \\REGISTRY\\USER\n);


Using L constructs isn't portable, you'll need to declare these the
tedious way you'll find in other Wine tests:
static const WCHAR reg_user[] = { '\\','R',''E,'G','I','S','T','R',Y',
etc. Then you can use the sizeof(reg_user) / sizeof(reg_user[0]) trick to
specify the length.
I think Alexandre will object to using msvcrt functions (wcsncmp in this
case), but I don't have a straightforward alternative yet.

Welcome to Wine development :)
--Juan



Re: [PATCH] Tests that prove ntdll has no notion of HKCR.

2013-05-18 Thread George Stephanos
On Sat, May 18, 2013 at 11:57 PM, Juan Lang juan.l...@gmail.com wrote:

 Hi George,
 (consider subscribing to wine-devel so your emails don't get stuck in
 moderation.)

Hmm but I am already!



 On Sat, May 11, 2013 at 7:43 AM, George Stephanos gaf.stepha...@gmail.com
  wrote:

 As instructed, I added a few lines to the already written tests that
 confirm my claim.

 Part of the research of the registry merging project was to determine
 where the implementation is going to be written: advapi32, ntdll or
 the server itself. The server choice was dismissed since HKCR isn't
 stored and rather fetched live. These tests prove that advapi32 calls
 that reference HKCR are either pointed there to \REGISTRY\MACHINE or
 \REGISTRY\USER and hence, that the merge is to be done in advapi32.

 http://newtestbot.winehq.org/JobDetails.pl?Key=976
 ---
  dlls/advapi32/tests/registry.c | 18 ++
  1 file changed, 18 insertions(+)

 diff --git a/dlls/advapi32/tests/registry.c
 b/dlls/advapi32/tests/registry.c
 index b2483a7..8437e4d 100644
 --- a/dlls/advapi32/tests/registry.c
 +++ b/dlls/advapi32/tests/registry.c
 @@ -43,6 +43,7 @@ static DWORD (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR);
  static DWORD (WINAPI *pRegDeleteKeyExA)(HKEY,LPCSTR,REGSAM,DWORD);
  static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
  static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE);
 +static NTSTATUS (WINAPI * pNtQueryKey)(HANDLE,int,PVOID,ULONG,PULONG);
  static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(UNICODE_STRING*);
  static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);

 @@ -136,6 +137,7 @@ static void InitFunctionPtrs(void)
  pRtlFormatCurrentUserKeyPath = (void *)GetProcAddress( hntdll,
 RtlFormatCurrentUserKeyPath );
  pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll,
 RtlFreeUnicodeString);
  pNtDeleteKey = (void *)GetProcAddress( hntdll, NtDeleteKey );
 +pNtQueryKey = (void *)GetProcAddress( hntdll, NtQueryKey );
  }

  /* delete key and all its subkeys */
 @@ -2104,6 +2106,7 @@ static void test_classesroot(void)
  DWORD type = REG_SZ;
  static CHAR buffer[8];
  LONG res;
 +void *buf = malloc(300*sizeof(wchar_t));


 You could just allocate a buffer on the stack. 300 is probably overkill,
 100 looks like it would do it. You want to use WCHAR rather than wchar_t.

  /* create a key in the user's classes */
  if (!RegOpenKeyA( HKEY_CURRENT_USER,
 Software\\Classes\\WineTestCls, hkey ))
 @@ -2132,6 +2135,9 @@ static void test_classesroot(void)
  RegCloseKey( hkey );
  return;
  }
 +pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buf,
 500*sizeof(wchar_t), (ULONG*)res );


 Not that this will actually overflow, but you specify 500, but only
 allocated 300. A straightforward way to accomplish agreement is to use
 sizeof(buf) / sizeof(buf[0]) as the size, if it's not dynamically allocated.

This slipped :|



 +ok( wcsncmp((wchar_t*)buf+2, L\\REGISTRY\\USER, 14) == 0,
 +key not from \\REGISTRY\\USER\n);


 Using L constructs isn't portable, you'll need to declare these the
 tedious way you'll find in other Wine tests:
 static const WCHAR reg_user[] = { '\\','R',''E,'G','I','S','T','R',Y',
 etc. Then you can use the sizeof(reg_user) / sizeof(reg_user[0]) trick to
 specify the length.
 I think Alexandre will object to using msvcrt functions (wcsncmp in this
 case), but I don't have a straightforward alternative yet.

strcmp is already used. What's the difference?


 Welcome to Wine development :)

:)

 --Juan




Re: [PATCH] Tests that prove ntdll has no notion of HKCR.

2013-05-18 Thread Juan Lang

 (consider subscribing to wine-devel so your emails don't get stuck in
 moderation.)

 Hmm but I am already!


Ok, that's strange. Maybe I just got it late.


 I think Alexandre will object to using msvcrt functions (wcsncmp in this
 case), but I don't have a straightforward alternative yet.

 strcmp is already used. What's the difference?


Ah, well, strcmp comes from the C library your compiler uses. wcsncmp can
only come from msvcrt. When compiling for Wine, this can result in mixing C
runtime libraries, and hilarity can result.

Say, do these tests work on Wine? If not, you'll want to mark them with
todo_wine, i.e. todo_wine ok(...).
--Juan



Re: [PATCH] Tests that prove ntdll has no notion of HKCR.

2013-05-18 Thread George Stephanos
On Sun, May 19, 2013 at 2:24 AM, Juan Lang juan.l...@gmail.com wrote:

 (consider subscribing to wine-devel so your emails don't get stuck in
 moderation.)

 Hmm but I am already!


 Ok, that's strange. Maybe I just got it late.


  I think Alexandre will object to using msvcrt functions (wcsncmp in
 this case), but I don't have a straightforward alternative yet.

 strcmp is already used. What's the difference?


 Ah, well, strcmp comes from the C library your compiler uses. wcsncmp can
 only come from msvcrt. When compiling for Wine, this can result in mixing C
 runtime libraries, and hilarity can result.

 Say, do these tests work on Wine? If not, you'll want to mark them with
 todo_wine, i.e. todo_wine ok(...).
 --Juan


Perhaps I could just use memcmp?
Only the \REGISTRY\USER portion of these tests don't work on wine. Marked.



[PATCH] Tests that prove ntdll has no notion of HKCR.

2013-05-17 Thread George Stephanos
As instructed, I added a few lines to the already written tests that
confirm my claim.

Part of the research of the registry merging project was to determine
where the implementation is going to be written: advapi32, ntdll or
the server itself. The server choice was dismissed since HKCR isn't
stored and rather fetched live. These tests prove that advapi32 calls
that reference HKCR are either pointed there to \REGISTRY\MACHINE or
\REGISTRY\USER and hence, that the merge is to be done in advapi32.

http://newtestbot.winehq.org/JobDetails.pl?Key=976
---
 dlls/advapi32/tests/registry.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index b2483a7..8437e4d 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -43,6 +43,7 @@ static DWORD (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR);
 static DWORD (WINAPI *pRegDeleteKeyExA)(HKEY,LPCSTR,REGSAM,DWORD);
 static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
 static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE);
+static NTSTATUS (WINAPI * pNtQueryKey)(HANDLE,int,PVOID,ULONG,PULONG);
 static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(UNICODE_STRING*);
 static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);
 
@@ -136,6 +137,7 @@ static void InitFunctionPtrs(void)
 pRtlFormatCurrentUserKeyPath = (void *)GetProcAddress( hntdll, 
RtlFormatCurrentUserKeyPath );
 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, 
RtlFreeUnicodeString);
 pNtDeleteKey = (void *)GetProcAddress( hntdll, NtDeleteKey );
+pNtQueryKey = (void *)GetProcAddress( hntdll, NtQueryKey );
 }
 
 /* delete key and all its subkeys */
@@ -2104,6 +2106,7 @@ static void test_classesroot(void)
 DWORD type = REG_SZ;
 static CHAR buffer[8];
 LONG res;
+void *buf = malloc(300*sizeof(wchar_t));
 
 /* create a key in the user's classes */
 if (!RegOpenKeyA( HKEY_CURRENT_USER, Software\\Classes\\WineTestCls, 
hkey ))
@@ -2132,6 +2135,9 @@ static void test_classesroot(void)
 RegCloseKey( hkey );
 return;
 }
+pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buf, 500*sizeof(wchar_t), 
(ULONG*)res );
+ok( wcsncmp((wchar_t*)buf+2, L\\REGISTRY\\USER, 14) == 0,
+key not from \\REGISTRY\\USER\n);
 
 /* set a value in user's classes */
 res = RegSetValueExA(hkey, val1, 0, REG_SZ, (const BYTE *)user, 
sizeof(user));
@@ -2200,6 +2206,9 @@ static void test_classesroot(void)
 RegCloseKey( hklm );
 return;
 }
+pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buf, 500*sizeof(wchar_t), 
(ULONG*)res );
+ok( wcsncmp( (wchar_t*)buf+2, L\\REGISTRY\\USER, 14) == 0,
+key not from \\REGISTRY\\USER\n);
 
 /* set a value in hklm classes */
 res = RegSetValueExA(hklm, val2, 0, REG_SZ, (const BYTE *)hklm, 
sizeof(hklm));
@@ -2227,6 +2236,9 @@ static void test_classesroot(void)
  KEY_QUERY_VALUE|KEY_SET_VALUE, hkcr );
 ok(res == ERROR_SUCCESS,
test key not found in hkcr: %d\n, res);
+pNtQueryKey( hkcr, 3 /*KeyNameInformation*/, buf, 500*sizeof(wchar_t), 
(ULONG*)res );
+ok( wcsncmp( (wchar_t*)buf+2, L\\REGISTRY\\USER, 14) == 0,
+key not from \\REGISTRY\\USER\n);
 
 /* set a value in user's classes */
 res = RegSetValueExA(hkey, val2, 0, REG_SZ, (const BYTE *)user, 
sizeof(user));
@@ -2267,6 +2279,9 @@ static void test_classesroot(void)
 /* try to open that subkey in hkcr */
 res = RegOpenKeyExA( hkcr, subkey1, 0, KEY_QUERY_VALUE|KEY_SET_VALUE, 
hkcrsub1 );
 ok(res == ERROR_SUCCESS, test key not found in hkcr: %d\n, res);
+pNtQueryKey( hkcrsub1, 3 /*KeyNameInformation*/, buf, 500*sizeof(wchar_t), 
(ULONG*)res );
+ok( wcsncmp( (wchar_t*)buf+2, L\\REGISTRY\\MACHINE, 17) == 0,
+key created in hkcr not found in \\REGISTRY\\MACHINE\n);
 
 /* set a value in hklm classes */
 res = RegSetValueExA(hklmsub1, subval1, 0, REG_SZ, (const BYTE *)hklm, 
sizeof(hklm));
@@ -2326,6 +2341,9 @@ static void test_classesroot(void)
 /* new subkey in hkcr */
 if (RegCreateKeyExA( hkcr, subkey2, 0, NULL, 0,
  KEY_QUERY_VALUE|KEY_SET_VALUE, NULL, hkcrsub2, NULL 
)) return;
+pNtQueryKey( hkcrsub2, 3 /*KeyNameInformation*/, buf, 256*sizeof(wchar_t), 
(ULONG*)res );
+ok( wcsncmp( (wchar_t*)buf+2, L\\REGISTRY\\MACHINE, 17) == 0,
+key not found in \\REGISTRY\\MACHINE);
 res = RegSetValueExA(hkcrsub2, subval1, 0, REG_SZ, (const BYTE *)hkcr, 
sizeof(hkcr));
 ok(res == ERROR_SUCCESS, RegSetValueExA failed: %d, GLE=%x\n, res, 
GetLastError());
 
-- 
1.8.1.msysgit.1