/*********************************************************************** * GlobalGetAtomNameA (KERNEL32.@) * * Get a copy of the string associated with an atom. * * RETURNS * Success: The length of the returned string in characters. * Failure: 0. */ UINT WINAPI GlobalGetAtomNameA( ATOM atom, /* [in] Atom identifier */ LPSTR buffer, /* [out] Pointer to buffer for atom string */ INT count ) /* [in] Size of buffer */ { WCHAR tmpW[MAX_ATOM_LEN + 1]; UINT wlen, len = 0, c; if (count <= 0) SetLastError( ERROR_MORE_DATA ); else if ((wlen = GlobalGetAtomNameW( atom, tmpW, MAX_ATOM_LEN + 1 ))) { char tmp[MAX_ATOM_LEN + 1]; len = WideCharToMultiByte( CP_ACP, 0, tmpW, wlen, tmp, MAX_ATOM_LEN + 1, NULL, NULL ); c = min(len, count - 1); memcpy(buffer, tmp, c); buffer[c] = '\0'; if (len >= count) { len = 0; SetLastError( ERROR_MORE_DATA ); } } return len; }
ESTATUS main_WasAtomWrittenSuccessfully( ATOM tAtom, PWSTR pswzExpectedBuffer, PBOOL pbWasAtomWrittenSuccessfully ) { LPWSTR pswzCheckBuffer = NULL; DWORD cbCheckBuffer = 0; ESTATUS eReturn = ESTATUS_INVALID; UINT uiRet = 0; HMODULE hUser32 = NULL; BOOL bWasAtomWrittenSuccessfully = FALSE; // If user32.dll is not loaded, the ATOM functions return access denied.For more details see : // http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.kernel/2004-03/0851.html hUser32 = LoadLibrary(L"user32.dll"); if (NULL == hUser32) { goto lblCleanup; } cbCheckBuffer = (wcslen(pswzExpectedBuffer) + 1) * sizeof(WCHAR); pswzCheckBuffer = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbCheckBuffer); if (NULL == pswzCheckBuffer) { printf("HeapAlloc failed. GLE: 0x%X (%d)\n\n", GetLastError(), GetLastError()); eReturn = ESTATUS_MAIN_WASATOMWRITTENSUCCESSFULLY_HEAPALLOC_FAILED; goto lblCleanup; } uiRet = GlobalGetAtomNameW(tAtom, pswzCheckBuffer, cbCheckBuffer); if (0 == uiRet) { printf("GlobalGetAtomNameA failed. GLE: 0x%X (%d)\n\n", GetLastError(), GetLastError()); eReturn = ESTATUS_MAIN_WASATOMWRITTENSUCCESSFULLY_GLOBALGETATOMNAMEW_FAILED; goto lblCleanup; } bWasAtomWrittenSuccessfully = (0 == memcmp(pswzCheckBuffer, pswzExpectedBuffer, cbCheckBuffer)); eReturn = ESTATUS_SUCCESS; *pbWasAtomWrittenSuccessfully = bWasAtomWrittenSuccessfully; lblCleanup: if (NULL != pswzCheckBuffer) { HeapFree(GetProcessHeap(), 0, pswzCheckBuffer); pswzCheckBuffer = NULL; } return eReturn; }
static HMODULE load_desktop_driver( HWND hwnd ) { static const WCHAR display_device_guid_propW[] = { '_','_','w','i','n','e','_','d','i','s','p','l','a','y','_', 'd','e','v','i','c','e','_','g','u','i','d',0 }; static const WCHAR key_pathW[] = { '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','\\', 'V','i','d','e','o','\\','{',0}; static const WCHAR displayW[] = {'}','\\','0','0','0','0',0}; static const WCHAR driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0}; HMODULE ret = 0; HKEY hkey; DWORD size; WCHAR path[MAX_PATH]; WCHAR key[(sizeof(key_pathW) + sizeof(displayW)) / sizeof(WCHAR) + 40]; UINT guid_atom = HandleToULong( GetPropW( hwnd, display_device_guid_propW )); USER_CheckNotLock(); strcpy( driver_load_error, "The explorer process failed to start." ); /* default error */ if (!guid_atom) { SendMessageW( hwnd, WM_NULL, 0, 0 ); /* wait for the desktop process to be ready */ guid_atom = HandleToULong( GetPropW( hwnd, display_device_guid_propW )); } memcpy( key, key_pathW, sizeof(key_pathW) ); if (!GlobalGetAtomNameW( guid_atom, key + strlenW(key), 40 )) return 0; strcatW( key, displayW ); if (RegOpenKeyW( HKEY_LOCAL_MACHINE, key, &hkey )) return 0; size = sizeof(path); if (!RegQueryValueExW( hkey, driverW, NULL, NULL, (BYTE *)path, &size )) { if (!(ret = LoadLibraryW( path ))) ERR( "failed to load %s\n", debugstr_w(path) ); TRACE( "%s %p\n", debugstr_w(path), ret ); } else { size = sizeof(driver_load_error); RegQueryValueExA( hkey, "DriverError", NULL, NULL, (BYTE *)driver_load_error, &size ); } RegCloseKey( hkey ); return ret; }
static void test_get_atom_name(void) { char buf[10]; WCHAR bufW[10]; int i; UINT len; static const WCHAR resultW[] = {'f','o','o','b','a','r',0,'.','.','.'}; char in[257], out[257]; WCHAR inW[257], outW[257]; ATOM atom = GlobalAddAtomA( "foobar" ); /* Get the name of the atom we added above */ memset( buf, '.', sizeof(buf) ); len = GlobalGetAtomNameA( atom, buf, 10 ); ok( len == strlen("foobar"), "bad length %d\n", len ); ok( !memcmp( buf, "foobar\0...", 10 ), "bad buffer contents\n" ); /* Repeat, unicode-style */ if (unicode_OS) { for (i = 0; i < 10; i++) bufW[i] = '.'; SetLastError( 0xdeadbeef ); len = GlobalGetAtomNameW( atom, bufW, 10 ); ok( len && GetLastError() == 0xdeadbeef, "GlobalGetAtomNameW failed\n" ); ok( len == lstrlenW(foobarW), "bad length %d\n", len ); ok( !memcmp( bufW, resultW, 10*sizeof(WCHAR) ), "bad buffer contents\n" ); } /* Check error code returns */ memset(buf, '.', 10); ok( !GlobalGetAtomNameA( atom, buf, 0 ), "succeeded\n" ); ok( !memcmp( buf, "..........", 10 ), "should not touch buffer\n" ); if (unicode_OS) { static const WCHAR sampleW[] = {'.','.','.','.','.','.','.','.','.','.'}; for (i = 0; i < 10; i++) bufW[i] = '.'; ok( !GlobalGetAtomNameW( atom, bufW, 0 ), "succeeded\n" ); ok( !memcmp( bufW, sampleW, sizeof(sampleW) ), "should not touch buffer\n" ); } /* Test integer atoms */ for (i = 0; i <= 0xbfff; i++) { memset( buf, 'a', 10 ); len = GlobalGetAtomNameA( (ATOM)i, buf, 10 ); if (i) { char res[20]; ok( (len > 1) && (len < 7), "bad length %d\n", len ); sprintf( res, "#%d", i ); memset( res + strlen(res) + 1, 'a', 10 ); ok( !memcmp( res, buf, 10 ), "bad buffer contents %s\n", buf ); if (len <= 1 || len >= 7) break; /* don't bother testing all of them */ } else ok( !len, "bad length %d\n", len ); SetLastError(0xdeadbeef); len = GlobalGetAtomNameA( (ATOM)i, buf, 2); ok(!len, "bad length %d\n", len); ok(GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INVALID_PARAMETER, "wrong error conditions %u for %u\n", GetLastError(), i); } memset( buf, '.', sizeof(buf) ); len = GlobalGetAtomNameA( atom, buf, 6 ); ok( len == 0, "bad length %d\n", len ); ok( !memcmp( buf, "fooba\0....", 10 ), "bad buffer contents\n"); if (unicode_OS) { static const WCHAR resW[] = {'f','o','o','b','a','r','.','.','.','.'}; for (len = 0; len < 10; len++) bufW[len] = '.'; SetLastError(0xdeadbeef); len = GlobalGetAtomNameW( atom, bufW, 6 ); ok( len && GetLastError() == 0xdeadbeef, "GlobalGetAtomNameW failed\n" ); ok( len == lstrlenW(foobarW), "bad length %d\n", len ); ok( !memcmp( bufW, resW, 10*sizeof(WCHAR) ), "bad buffer contents\n" ); } /* test string limits & overflow */ do_initA(in, "abcdefghij", 255); atom = GlobalAddAtomA(in); ok(atom, "couldn't add atom for %s\n", in); len = GlobalGetAtomNameA(atom, out, sizeof(out)); ok(len == 255, "length mismatch (%u instead of 255)\n", len); for (i = 0; i < 255; i++) { ok(out[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, out[i], "abcdefghij"[i % 10]); } ok(out[255] == '\0', "wrong end of string\n"); memset(out, '.', sizeof(out)); SetLastError(0xdeadbeef); len = GlobalGetAtomNameA(atom, out, 10); ok(!len, "bad length %d\n", len); ok(GetLastError() == ERROR_MORE_DATA, "wrong error code (%u instead of %u)\n", GetLastError(), ERROR_MORE_DATA); for (i = 0; i < 9; i++) { ok(out[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, out[i], "abcdefghij"[i % 10]); } ok(out[9] == '\0', "wrong end of string\n"); ok(out[10] == '.', "wrote after end of buf\n"); do_initA(in, "abcdefghij", 256); atom = GlobalAddAtomA(in); ok(!atom, "succeeded\n"); if (unicode_OS) { /* test integral atoms */ for (i = 0; i <= 0xbfff; i++) { memset(outW, 'a', sizeof(outW)); len = GlobalGetAtomNameW( (ATOM)i, outW, 10 ); if (i) { WCHAR res[20]; ok( (len > 1) && (len < 7), "bad length %d\n", len ); wsprintfW( res, integfmt, i ); memset( res + lstrlenW(res) + 1, 'a', 10 * sizeof(WCHAR)); ok( !memcmp( res, outW, 10 * sizeof(WCHAR) ), "bad buffer contents for %d\n", i ); if (len <= 1 || len >= 7) break; /* don't bother testing all of them */ } else ok( !len, "bad length %d\n", len ); memset(outW, '.', sizeof(outW)); SetLastError(0xdeadbeef); len = GlobalGetAtomNameW( (ATOM)i, outW, 1); if (i) { /* len == 0 with ERROR_MORE_DATA is on NT3.51 */ ok(len == 1 || (len == 0 && GetLastError() == ERROR_MORE_DATA), "0x%04x: got %u with %d (expected '1' or '0' with " "ERROR_MORE_DATA)\n", i, len, GetLastError()); ok(outW[1] == DOUBLE('.'), "buffer overwrite\n"); } else ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "0 badly handled\n"); } do_initW(inW, "abcdefghij", 255); atom = GlobalAddAtomW(inW); ok(atom, "couldn't add atom for %s\n", in); len = GlobalGetAtomNameW(atom, outW, sizeof(outW)/sizeof(outW[0])); ok(len == 255, "length mismatch (%u instead of 255)\n", len); for (i = 0; i < 255; i++) { ok(outW[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, outW[i], "abcdefghij"[i % 10]); } ok(outW[255] == '\0', "wrong end of string\n"); memset(outW, '.', sizeof(outW)); len = GlobalGetAtomNameW(atom, outW, 10); ok(len == 10, "succeeded\n"); for (i = 0; i < 10; i++) { ok(outW[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, outW[i], "abcdefghij"[i % 10]); } ok(outW[10] == DOUBLE('.'), "wrote after end of buf\n"); do_initW(inW, "abcdefghij", 256); atom = GlobalAddAtomW(inW); ok(!atom, "succeeded\n"); ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error code\n"); } }
HRESULT WINAPI ObjectFromLresult( LRESULT result, REFIID riid, WPARAM wParam, void **ppObject ) { WCHAR atom_str[sizeof(lresult_atom_prefix)/sizeof(WCHAR)+3*8+3]; HANDLE server_proc, server_mapping, mapping; DWORD proc_id, size; IStream *stream; HGLOBAL data; void *view; HRESULT hr; WCHAR *p; TRACE("%ld %s %ld %p\n", result, debugstr_guid(riid), wParam, ppObject ); if(wParam) FIXME("unsupported wParam = %lx\n", wParam); if(!ppObject) return E_INVALIDARG; *ppObject = NULL; if(result != (ATOM)result) return E_FAIL; if(!GlobalGetAtomNameW(result, atom_str, sizeof(atom_str)/sizeof(WCHAR))) return E_FAIL; if(memcmp(atom_str, lresult_atom_prefix, sizeof(lresult_atom_prefix))) return E_FAIL; p = atom_str + sizeof(lresult_atom_prefix)/sizeof(WCHAR); proc_id = strtoulW(p, &p, 16); if(*p != ':') return E_FAIL; server_mapping = ULongToHandle( strtoulW(p+1, &p, 16) ); if(*p != ':') return E_FAIL; size = strtoulW(p+1, &p, 16); if(*p != 0) return E_FAIL; server_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, proc_id); if(!server_proc) return E_FAIL; if(!DuplicateHandle(server_proc, server_mapping, GetCurrentProcess(), &mapping, 0, FALSE, DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS)) return E_FAIL; CloseHandle(server_proc); GlobalDeleteAtom(result); view = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); CloseHandle(mapping); if(!view) return E_FAIL; data = GlobalAlloc(GMEM_FIXED, size); if(!data) { UnmapViewOfFile(view); return E_OUTOFMEMORY; } memcpy(data, view, size); UnmapViewOfFile(view); hr = CreateStreamOnHGlobal(data, TRUE, &stream); if(FAILED(hr)) { GlobalFree(data); return hr; } hr = CoUnmarshalInterface(stream, riid, ppObject); IStream_Release(stream); return hr; }
/* * @implemented */ int WINAPI EnumPropsW(HWND hWnd, PROPENUMPROCW lpEnumFunc) { PPROPLISTITEM pli, i; NTSTATUS Status; DWORD Count; int ret = -1; if(!lpEnumFunc) { SetLastError(ERROR_INVALID_PARAMETER); return ret; } Status = NtUserBuildPropList(hWnd, NULL, 0, &Count); if(!NT_SUCCESS(Status)) { if(Status == STATUS_INVALID_HANDLE) SetLastError(ERROR_INVALID_WINDOW_HANDLE); else SetLastError(RtlNtStatusToDosError(Status)); return ret; } if(Count > 0) { pli = RtlAllocateHeap(GetProcessHeap(), 0, Count); if (pli == NULL) { SetLastError(ERROR_OUTOFMEMORY); return -1; } Status = NtUserBuildPropList(hWnd, (LPVOID)pli, Count, &Count); if(!NT_SUCCESS(Status)) { RtlFreeHeap(GetProcessHeap(), 0, pli); if(Status == STATUS_INVALID_HANDLE) SetLastError(ERROR_INVALID_WINDOW_HANDLE); else SetLastError(RtlNtStatusToDosError(Status)); return ret; } i = pli; for(; Count > 0; Count--, i++) { WCHAR str[ATOM_BUFFER_SIZE]; if(!GlobalGetAtomNameW(i->Atom, str, ATOM_BUFFER_SIZE)) continue; ret = lpEnumFunc(hWnd, str, i->Data); if(!ret) break; } RtlFreeHeap(GetProcessHeap(), 0, pli); } return ret; }