Module: wine Branch: refs/heads/master Commit: 9b3d8a3527352e9ad2927b608987246b53dddd9b URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=9b3d8a3527352e9ad2927b60...
Author: Mike McCormack mike@codeweavers.com Date: Mon May 15 22:03:41 2006 +0900
advapi32: Implement and test SystemFunction005.
---
dlls/advapi32/advapi32.spec | 2 + dlls/advapi32/crypt_lmhash.c | 61 +++++++++++++++++++++++++++++++++++ dlls/advapi32/tests/crypt_lmhash.c | 63 ++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 1 deletions(-)
diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec index 9f815f5..abdab0b 100644 --- a/dlls/advapi32/advapi32.spec +++ b/dlls/advapi32/advapi32.spec @@ -599,7 +599,7 @@ # @ stub StopTraceW @ stdcall SystemFunction002(ptr ptr ptr) @ stdcall SystemFunction003(ptr ptr) @ stdcall SystemFunction004(ptr ptr ptr) -@ stub SystemFunction005 +@ stdcall SystemFunction005(ptr ptr ptr) @ stdcall SystemFunction006(ptr ptr) @ stdcall SystemFunction007(ptr ptr) @ stdcall SystemFunction008(ptr ptr ptr) diff --git a/dlls/advapi32/crypt_lmhash.c b/dlls/advapi32/crypt_lmhash.c index 7070154..4760e97 100644 --- a/dlls/advapi32/crypt_lmhash.c +++ b/dlls/advapi32/crypt_lmhash.c @@ -219,3 +219,64 @@ NTSTATUS WINAPI SystemFunction004(const
return STATUS_SUCCESS; } + +/****************************************************************************** + * SystemFunction005 [ADVAPI32.@] + * + * Decrypts a block of data with DES in ECB mode + * + * PARAMS + * data [I] data to decrypt + * key [I] key data (up to 7 bytes) + * output [O] buffer to receive decrypted data + * + * RETURNS + * Success: STATUS_SUCCESS + * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small + * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length + * + */ +NTSTATUS WINAPI SystemFunction005(const struct ustring *in, + const struct ustring *key, + struct ustring *out) +{ + union { + unsigned char uc[8]; + unsigned int ui[2]; + } data; + unsigned char deskey[7]; + int ofs, crypt_len; + + if (key->Length<=0) + return STATUS_INVALID_PARAMETER_2; + + if (key->Length<sizeof deskey) + { + memset(deskey, 0, sizeof deskey); + memcpy(deskey, key->Buffer, key->Length); + } + else + memcpy(deskey, key->Buffer, sizeof deskey); + + CRYPT_DESunhash(data.uc, deskey, in->Buffer); + + if (data.ui[1] != 1) + return STATUS_UNKNOWN_REVISION; + + crypt_len = data.ui[0]; + if (crypt_len > out->MaximumLength) + return STATUS_BUFFER_TOO_SMALL; + + for (ofs=0; (ofs+8)<crypt_len; ofs+=8) + CRYPT_DESunhash(out->Buffer+ofs, deskey, in->Buffer+ofs+8); + + if (ofs<crypt_len) + { + CRYPT_DESunhash(data.uc, deskey, in->Buffer+ofs+8); + memcpy(out->Buffer+ofs, data.uc, crypt_len-ofs); + } + + out->Length = crypt_len; + + return STATUS_SUCCESS; +} diff --git a/dlls/advapi32/tests/crypt_lmhash.c b/dlls/advapi32/tests/crypt_lmhash.c index 2edb843..866bbde 100644 --- a/dlls/advapi32/tests/crypt_lmhash.c +++ b/dlls/advapi32/tests/crypt_lmhash.c @@ -38,6 +38,7 @@ typedef NTSTATUS (WINAPI *fnSystemFuncti typedef NTSTATUS (WINAPI *fnSystemFunction002)(const LPBYTE, const LPBYTE, LPBYTE); typedef NTSTATUS (WINAPI *fnSystemFunction003)(const LPBYTE, LPBYTE); typedef NTSTATUS (WINAPI *fnSystemFunction004)(const struct ustring *, const struct ustring *, struct ustring *); +typedef NTSTATUS (WINAPI *fnSystemFunction005)(const struct ustring *, const struct ustring *, struct ustring *); typedef VOID (WINAPI *fnSystemFunction006)( PCSTR passwd, PSTR lmhash ); typedef NTSTATUS (WINAPI *fnSystemFunction008)(const LPBYTE, const LPBYTE, LPBYTE); typedef NTSTATUS (WINAPI *fnSystemFunction032)(struct ustring *, struct ustring *); @@ -46,6 +47,7 @@ fnSystemFunction001 pSystemFunction001; fnSystemFunction002 pSystemFunction002; fnSystemFunction003 pSystemFunction003; fnSystemFunction004 pSystemFunction004; +fnSystemFunction004 pSystemFunction005; fnSystemFunction006 pSystemFunction006; fnSystemFunction008 pSystemFunction008; fnSystemFunction032 pSystemFunction032; @@ -274,6 +276,63 @@ static void test_SystemFunction004(void) ok(!memcmp(output, inbuf, sizeof output), "crypted data wrong\n"); }
+static void test_SystemFunction005(void) +{ + char output[0x40], result[0x40]; + int r; + struct ustring in, key, out, res; + char *datastr = "twinkle twinkle little star"; + char *keystr = "byolnim"; + + in.Buffer = (unsigned char *) datastr; + in.Length = strlen(datastr); + in.MaximumLength = 0; + + key.Buffer = (unsigned char *)keystr; + key.Length = strlen(keystr); + key.MaximumLength = 0; + + out.Buffer = (unsigned char *)output; + out.Length = out.MaximumLength = sizeof output; + + r = pSystemFunction004(&in, &key, &out); + ok(r == STATUS_SUCCESS, "function failed\n"); + + memset(result, 0, sizeof result); + res.Buffer = (unsigned char *)result; + res.Length = 0; + res.MaximumLength = sizeof result; + + r = pSystemFunction005(&out, &key, &res); + ok(r == STATUS_SUCCESS, "function failed\n"); + + r = pSystemFunction005(&out, &key, &res); + ok(r == STATUS_SUCCESS, "function failed\n"); + + ok(res.Length == in.Length, "Length wrong\n"); + ok(!memcmp(res.Buffer, in.Buffer, in.Length), "data wrong\n"); + + out.Length = 0; + out.MaximumLength = 0; + r = pSystemFunction005(&out, &key, &res); + ok(r == STATUS_SUCCESS, "function failed\n"); + + ok(res.Length == in.Length, "Length wrong\n"); + ok(!memcmp(res.Buffer, in.Buffer, in.Length), "data wrong\n"); + + res.MaximumLength = 0; + r = pSystemFunction005(&out, &key, &res); + ok(r == STATUS_BUFFER_TOO_SMALL, "function failed\n"); + + key.Length = 1; + r = pSystemFunction005(&out, &key, &res); + ok(r == STATUS_UNKNOWN_REVISION, "function failed\n"); + + key.Length = 0; + r = pSystemFunction005(&out, &key, &res); + ok(r == STATUS_INVALID_PARAMETER_2, "function failed\n"); +} + START_TEST(crypt_lmhash) { HMODULE module; @@ -296,6 +355,10 @@ START_TEST(crypt_lmhash) if (pSystemFunction004) test_SystemFunction004();
+ pSystemFunction005 = (fnSystemFunction005)GetProcAddress( module, "SystemFunction005" ); + if (pSystemFunction005) + test_SystemFunction005(); + pSystemFunction006 = (fnSystemFunction006)GetProcAddress( module, "SystemFunction006" ); if (pSystemFunction006) test_SystemFunction006();