/***************************************************** * localmon_XcvDataPort [exported through MONITOREX] * * Execute command through a Communication-Channel * * PARAMS * hXcv [i] The Handle to work with * pszDataName [i] Name of the command to execute * pInputData [i] Buffer for extra Input Data (needed only for some commands) * cbInputData [i] Size in Bytes of Buffer at pInputData * pOutputData [o] Buffer to receive additional Data (needed only for some commands) * cbOutputData [i] Size in Bytes of Buffer at pOutputData * pcbOutputNeeded [o] PTR to receive the minimal Size in Bytes of the Buffer at pOutputData * * RETURNS * Success: ERROR_SUCCESS * Failure: win32 error code * * NOTES * * Minimal List of commands, that every Printmonitor DLL should support: * *| "MonitorUI" : Return the Name of the Userinterface-DLL as WSTR in pOutputData *| "AddPort" : Add a Port (Name as WSTR in pInputData) *| "DeletePort": Delete a Port (Name as WSTR in pInputData) * * */ static DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded) { WCHAR buffer[16]; /* buffer for a decimal number */ LPWSTR ptr; DWORD res; DWORD needed; HKEY hroot; TRACE("(%p, %s, %p, %d, %p, %d, %p)\n", hXcv, debugstr_w(pszDataName), pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded); if (!lstrcmpW(pszDataName, cmd_AddPortW)) { TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData)); res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_PortsW, &hroot); if (res == ERROR_SUCCESS) { if (does_port_exist((LPWSTR) pInputData)) { RegCloseKey(hroot); TRACE("=> %u\n", ERROR_ALREADY_EXISTS); return ERROR_ALREADY_EXISTS; } res = RegSetValueExW(hroot, (LPWSTR) pInputData, 0, REG_SZ, (const BYTE *) emptyW, sizeof(emptyW)); RegCloseKey(hroot); } TRACE("=> %u\n", res); return res; } if (!lstrcmpW(pszDataName, cmd_ConfigureLPTPortCommandOKW)) { TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData)); res = RegCreateKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_WindowsW, &hroot); if (res == ERROR_SUCCESS) { res = RegSetValueExW(hroot, TransmissionRetryTimeoutW, 0, REG_SZ, pInputData, cbInputData); RegCloseKey(hroot); } return res; } if (!lstrcmpW(pszDataName, cmd_DeletePortW)) { TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData)); res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_PortsW, &hroot); if (res == ERROR_SUCCESS) { res = RegDeleteValueW(hroot, (LPWSTR) pInputData); RegCloseKey(hroot); TRACE("=> %u with %u\n", res, GetLastError() ); return res; } return ERROR_FILE_NOT_FOUND; } if (!lstrcmpW(pszDataName, cmd_GetDefaultCommConfigW)) { TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData)); *pcbOutputNeeded = cbOutputData; res = GetDefaultCommConfigW((LPWSTR) pInputData, (LPCOMMCONFIG) pOutputData, pcbOutputNeeded); TRACE("got %u with %u\n", res, GetLastError() ); return res ? ERROR_SUCCESS : GetLastError(); } if (!lstrcmpW(pszDataName, cmd_GetTransmissionRetryTimeoutW)) { * pcbOutputNeeded = sizeof(DWORD); if (cbOutputData >= sizeof(DWORD)) { /* the w2k resource kit documented a default of 90, but that's wrong */ *((LPDWORD) pOutputData) = 45; res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_WindowsW, &hroot); if (res == ERROR_SUCCESS) { needed = sizeof(buffer) - sizeof(WCHAR); res = RegQueryValueExW(hroot, TransmissionRetryTimeoutW, NULL, NULL, (LPBYTE) buffer, &needed); if ((res == ERROR_SUCCESS) && (buffer[0])) { *((LPDWORD) pOutputData) = strtoulW(buffer, NULL, 0); } RegCloseKey(hroot); } return ERROR_SUCCESS; } return ERROR_INSUFFICIENT_BUFFER; } if (!lstrcmpW(pszDataName, cmd_MonitorUIW)) { * pcbOutputNeeded = sizeof(dllnameuiW); if (cbOutputData >= sizeof(dllnameuiW)) { memcpy(pOutputData, dllnameuiW, sizeof(dllnameuiW)); return ERROR_SUCCESS; } return ERROR_INSUFFICIENT_BUFFER; } if (!lstrcmpW(pszDataName, cmd_PortIsValidW)) { TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData)); res = get_type_from_name((LPCWSTR) pInputData); TRACE("detected as %u\n", res); /* names, that we have recognized, are valid */ if (res) return ERROR_SUCCESS; /* ERROR_ACCESS_DENIED, ERROR_PATH_NOT_FOUND or something else */ TRACE("=> %u\n", GetLastError()); return GetLastError(); } if (!lstrcmpW(pszDataName, cmd_SetDefaultCommConfigW)) { /* get the portname from the Handle */ ptr = strchrW(((xcv_t *)hXcv)->nameW, ' '); if (ptr) { ptr++; /* skip the space */ } else { ptr = ((xcv_t *)hXcv)->nameW; } lstrcpynW(buffer, ptr, sizeof(buffer)/sizeof(WCHAR)); if (buffer[0]) buffer[lstrlenW(buffer)-1] = '\0'; /* remove the ':' */ res = SetDefaultCommConfigW(buffer, (LPCOMMCONFIG) pInputData, cbInputData); TRACE("got %u with %u\n", res, GetLastError() ); return res ? ERROR_SUCCESS : GetLastError(); } FIXME("command not supported: %s\n", debugstr_w(pszDataName)); return ERROR_INVALID_PARAMETER; }
static HRESULT HTMLFormElement_get_dispid(HTMLDOMNode *iface, BSTR name, DWORD grfdex, DISPID *pid) { HTMLFormElement *This = impl_from_HTMLDOMNode(iface); nsIDOMHTMLCollection *elements; nsAString nsstr, name_str; UINT32 len, i; nsresult nsres; HRESULT hres = DISP_E_UNKNOWNNAME; static const PRUnichar nameW[] = {'n','a','m','e',0}; TRACE("(%p)->(%s %x %p)\n", This, wine_dbgstr_w(name), grfdex, pid); nsres = nsIDOMHTMLFormElement_GetElements(This->nsform, &elements); if(NS_FAILED(nsres)) { FIXME("GetElements failed: 0x%08x\n", nsres); return E_FAIL; } nsres = nsIDOMHTMLCollection_GetLength(elements, &len); if(NS_FAILED(nsres)) { FIXME("GetLength failed: 0x%08x\n", nsres); nsIDOMHTMLCollection_Release(elements); return E_FAIL; } if(len > MSHTML_CUSTOM_DISPID_CNT) len = MSHTML_CUSTOM_DISPID_CNT; /* FIXME: Implement in more generic way */ if('0' <= *name && *name <= '9') { WCHAR *end_ptr; i = strtoulW(name, &end_ptr, 10); if(!*end_ptr && i < len) { *pid = MSHTML_DISPID_CUSTOM_MIN + i; return S_OK; } } nsAString_Init(&nsstr, NULL); for(i = 0; i < len; ++i) { nsIDOMNode *nsitem; nsIDOMHTMLElement *nshtml_elem; const PRUnichar *str; nsres = nsIDOMHTMLCollection_Item(elements, i, &nsitem); if(NS_FAILED(nsres)) { FIXME("Item failed: 0x%08x\n", nsres); hres = E_FAIL; break; } nsres = nsIDOMNode_QueryInterface(nsitem, &IID_nsIDOMHTMLElement, (void**)&nshtml_elem); nsIDOMNode_Release(nsitem); if(NS_FAILED(nsres)) { FIXME("Failed to get nsIDOMHTMLNode interface: 0x%08x\n", nsres); hres = E_FAIL; break; } /* compare by id attr */ nsres = nsIDOMHTMLElement_GetId(nshtml_elem, &nsstr); if(NS_FAILED(nsres)) { FIXME("GetId failed: 0x%08x\n", nsres); nsIDOMHTMLElement_Release(nshtml_elem); hres = E_FAIL; break; } nsAString_GetData(&nsstr, &str); if(!strcmpiW(str, name)) { nsIDOMHTMLElement_Release(nshtml_elem); /* FIXME: using index for dispid */ *pid = MSHTML_DISPID_CUSTOM_MIN + i; hres = S_OK; break; } /* compare by name attr */ nsres = get_elem_attr_value(nshtml_elem, nameW, &name_str, &str); nsIDOMHTMLElement_Release(nshtml_elem); if(NS_SUCCEEDED(nsres)) { if(!strcmpiW(str, name)) { nsAString_Finish(&name_str); /* FIXME: using index for dispid */ *pid = MSHTML_DISPID_CUSTOM_MIN + i; hres = S_OK; break; } nsAString_Finish(&name_str); } } nsAString_Finish(&nsstr); nsIDOMHTMLCollection_Release(elements); return hres; }
static LPBYTE get_regdata(LPWSTR data, DWORD reg_type, WCHAR separator, DWORD *reg_count) { LPBYTE out_data = NULL; *reg_count = 0; switch (reg_type) { case REG_NONE: case REG_SZ: case REG_EXPAND_SZ: { *reg_count = (lstrlenW(data) + 1) * sizeof(WCHAR); out_data = HeapAlloc(GetProcessHeap(),0,*reg_count); lstrcpyW((LPWSTR)out_data,data); break; } case REG_DWORD: /* case REG_DWORD_LITTLE_ENDIAN: */ case REG_DWORD_BIG_ENDIAN: /* Yes, this is correct! */ { LPWSTR rest; DWORD val; val = strtoulW(data, &rest, (data[1] == 'x') ? 16 : 10); if (*rest || data[0] == '-') { output_message(STRING_MISSING_INTEGER); break; } *reg_count = sizeof(DWORD); out_data = HeapAlloc(GetProcessHeap(),0,*reg_count); ((LPDWORD)out_data)[0] = val; break; } case REG_BINARY: { BYTE hex0, hex1; int i = 0, destByteIndex = 0, datalen = lstrlenW(data); *reg_count = ((datalen + datalen % 2) / 2) * sizeof(BYTE); out_data = HeapAlloc(GetProcessHeap(), 0, *reg_count); if(datalen % 2) { hex1 = hexchar_to_byte(data[i++]); if(hex1 == 0xFF) goto no_hex_data; out_data[destByteIndex++] = hex1; } for(;i + 1 < datalen;i += 2) { hex0 = hexchar_to_byte(data[i]); hex1 = hexchar_to_byte(data[i + 1]); if(hex0 == 0xFF || hex1 == 0xFF) goto no_hex_data; out_data[destByteIndex++] = (hex0 << 4) | hex1; } break; no_hex_data: /* cleanup, print error */ HeapFree(GetProcessHeap(), 0, out_data); output_message(STRING_MISSING_HEXDATA); out_data = NULL; break; } case REG_MULTI_SZ: /* FIXME: Needs handling */ default: output_message(STRING_UNHANDLED_TYPE, reg_type, data); } return out_data; }
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) 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; }
static HRESULT do_process_key(LPCOLESTR *pstr, HKEY parent_key, strbuf *buf, BOOL do_register) { LPCOLESTR iter; HRESULT hres; LONG lres; HKEY hkey = 0; strbuf name; enum { NORMAL, NO_REMOVE, IS_VAL, FORCE_REMOVE, DO_DELETE } key_type = NORMAL; static const WCHAR wstrNoRemove[] = {'N','o','R','e','m','o','v','e',0}; static const WCHAR wstrForceRemove[] = {'F','o','r','c','e','R','e','m','o','v','e',0}; static const WCHAR wstrDelete[] = {'D','e','l','e','t','e',0}; static const WCHAR wstrval[] = {'v','a','l',0}; iter = *pstr; hres = get_word(&iter, buf); if(FAILED(hres)) return hres; strbuf_init(&name); while(buf->str[1] || buf->str[0] != '}') { key_type = NORMAL; if(!lstrcmpiW(buf->str, wstrNoRemove)) key_type = NO_REMOVE; else if(!lstrcmpiW(buf->str, wstrForceRemove)) key_type = FORCE_REMOVE; else if(!lstrcmpiW(buf->str, wstrval)) key_type = IS_VAL; else if(!lstrcmpiW(buf->str, wstrDelete)) key_type = DO_DELETE; if(key_type != NORMAL) { hres = get_word(&iter, buf); if(FAILED(hres)) break; } TRACE("name = %s\n", debugstr_w(buf->str)); if(do_register) { if(key_type == IS_VAL) { hkey = parent_key; strbuf_write(buf->str, &name, -1); }else if(key_type == DO_DELETE) { TRACE("Deleting %s\n", debugstr_w(buf->str)); RegDeleteTreeW(parent_key, buf->str); }else { if(key_type == FORCE_REMOVE) RegDeleteTreeW(parent_key, buf->str); lres = RegCreateKeyW(parent_key, buf->str, &hkey); if(lres != ERROR_SUCCESS) { WARN("Could not create(open) key: %08x\n", lres); hres = HRESULT_FROM_WIN32(lres); break; } } }else if(key_type != IS_VAL && key_type != DO_DELETE) { strbuf_write(buf->str, &name, -1); lres = RegOpenKeyW(parent_key, buf->str, &hkey); if(lres != ERROR_SUCCESS) WARN("Could not open key %s: %08x\n", debugstr_w(name.str), lres); } if(key_type != DO_DELETE && *iter == '=') { iter++; hres = get_word(&iter, buf); if(FAILED(hres)) break; if(buf->len != 1) { WARN("Wrong registry type: %s\n", debugstr_w(buf->str)); hres = DISP_E_EXCEPTION; break; } if(do_register) { switch(buf->str[0]) { case 's': hres = get_word(&iter, buf); if(FAILED(hres)) break; lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_SZ, (PBYTE)buf->str, (lstrlenW(buf->str)+1)*sizeof(WCHAR)); if(lres != ERROR_SUCCESS) { WARN("Could set value of key: %08x\n", lres); hres = HRESULT_FROM_WIN32(lres); break; } break; case 'd': { DWORD dw; hres = get_word(&iter, buf); if(FAILED(hres)) break; dw = atoiW(buf->str); lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_DWORD, (PBYTE)&dw, sizeof(dw)); if(lres != ERROR_SUCCESS) { WARN("Could set value of key: %08x\n", lres); hres = HRESULT_FROM_WIN32(lres); break; } break; } case 'b': { BYTE *bytes; DWORD count; DWORD i; hres = get_word(&iter, buf); if(FAILED(hres)) break; count = (lstrlenW(buf->str) + 1) / 2; bytes = HeapAlloc(GetProcessHeap(), 0, count); if(bytes == NULL) { hres = E_OUTOFMEMORY; break; } for(i = 0; i < count && buf->str[2*i]; i++) { WCHAR digits[3]; if(!isxdigitW(buf->str[2*i]) || !isxdigitW(buf->str[2*i + 1])) { hres = E_FAIL; break; } digits[0] = buf->str[2*i]; digits[1] = buf->str[2*i + 1]; digits[2] = 0; bytes[i] = (BYTE) strtoulW(digits, NULL, 16); } if(SUCCEEDED(hres)) { lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_BINARY, bytes, count); if(lres != ERROR_SUCCESS) { WARN("Could not set value of key: 0x%08x\n", lres); hres = HRESULT_FROM_WIN32(lres); } } HeapFree(GetProcessHeap(), 0, bytes); break; } default: WARN("Wrong resource type: %s\n", debugstr_w(buf->str)); hres = DISP_E_EXCEPTION; }; if(FAILED(hres)) break; }else { if(*iter == '-') iter++; hres = get_word(&iter, buf); if(FAILED(hres)) break; } }else if(key_type == IS_VAL) { WARN("value not set!\n"); hres = DISP_E_EXCEPTION; break; } if(key_type != IS_VAL && key_type != DO_DELETE && *iter == '{' && isspaceW(iter[1])) { hres = get_word(&iter, buf); if(FAILED(hres)) break; hres = do_process_key(&iter, hkey, buf, do_register); if(FAILED(hres)) break; } TRACE("%x %x\n", do_register, key_type); if(!do_register && (key_type == NORMAL || key_type == FORCE_REMOVE)) { TRACE("Deleting %s\n", debugstr_w(name.str)); RegDeleteKeyW(parent_key, name.str); } if(hkey && key_type != IS_VAL) RegCloseKey(hkey); hkey = 0; name.len = 0; hres = get_word(&iter, buf); if(FAILED(hres)) break; } HeapFree(GetProcessHeap(), 0, name.str); if(hkey && key_type != IS_VAL) RegCloseKey(hkey); *pstr = iter; return hres; }
/*********************************************************************** * do_reg_operation * * Perform an add/delete registry operation depending on the flags. */ static BOOL do_reg_operation( IN HKEY KeyHandle, IN PWCHAR ValueName, IN PINFCONTEXT Context, IN ULONG Flags) { WCHAR EmptyStr = (CHAR)0; ULONG Type; ULONG Size; LONG Error; if (Flags & FLG_ADDREG_DELVAL) /* deletion */ { if (ValueName) { RegDeleteValueW (KeyHandle, ValueName); } else { RegDeleteKeyW (KeyHandle, NULL); } return TRUE; } if (Flags & FLG_ADDREG_KEYONLY) return TRUE; if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY)) { Error = RegQueryValueExW ( KeyHandle, ValueName, NULL, NULL, NULL, NULL); if ((Error == ERROR_SUCCESS) && (Flags & FLG_ADDREG_NOCLOBBER)) return TRUE; if ((Error != ERROR_SUCCESS) && (Flags & FLG_ADDREG_OVERWRITEONLY)) return TRUE; } switch (Flags & FLG_ADDREG_TYPE_MASK) { case FLG_ADDREG_TYPE_SZ: Type = REG_SZ; break; case FLG_ADDREG_TYPE_MULTI_SZ: Type = REG_MULTI_SZ; break; case FLG_ADDREG_TYPE_EXPAND_SZ: Type = REG_EXPAND_SZ; break; case FLG_ADDREG_TYPE_BINARY: Type = REG_BINARY; break; case FLG_ADDREG_TYPE_DWORD: Type = REG_DWORD; break; case FLG_ADDREG_TYPE_NONE: Type = REG_NONE; break; default: Type = Flags >> 16; break; } if (!(Flags & FLG_ADDREG_BINVALUETYPE) || (Type == REG_DWORD && InfHostGetFieldCount (Context) == 5)) { PWCHAR Str = NULL; if (Type == REG_MULTI_SZ) { if (InfHostGetMultiSzField (Context, 5, NULL, 0, &Size) != 0) Size = 0; if (Size) { Str = malloc (Size * sizeof(WCHAR)); if (Str == NULL) return FALSE; InfHostGetMultiSzField (Context, 5, Str, (ULONG)Size, NULL); } if (Flags & FLG_ADDREG_APPEND) { if (Str == NULL) return TRUE; AppendMultiSzValue ( KeyHandle, ValueName, Str, Size); free (Str); return TRUE; } /* else fall through to normal string handling */ } else { if (InfHostGetStringField (Context, 5, NULL, 0, &Size) != 0) Size = 0; if (Size) { Str = malloc (Size * sizeof(WCHAR)); if (Str == NULL) return FALSE; InfHostGetStringField (Context, 5, Str, (ULONG)Size, NULL); } } if (Type == REG_DWORD) { ULONG dw = Str ? strtoulW (Str, NULL, 0) : 0; DPRINT("setting dword %S to %x\n", ValueName, dw); RegSetValueExW ( KeyHandle, ValueName, 0, Type, (const PUCHAR)&dw, sizeof(ULONG)); } else { DPRINT("setting value %S to %S\n", ValueName, Str); if (Str) { RegSetValueExW ( KeyHandle, ValueName, 0, Type, (PVOID)Str, (ULONG)Size * sizeof(WCHAR)); } else { RegSetValueExW ( KeyHandle, ValueName, 0, Type, (PVOID)&EmptyStr, (ULONG)sizeof(WCHAR)); } } free (Str); } else /* get the binary data */ { PUCHAR Data = NULL; if (InfHostGetBinaryField (Context, 5, NULL, 0, &Size) != 0) Size = 0; if (Size) { Data = malloc (Size); if (Data == NULL) return FALSE; DPRINT("setting binary data %S len %d\n", ValueName, Size); InfHostGetBinaryField (Context, 5, Data, Size, NULL); } RegSetValueExW ( KeyHandle, ValueName, 0, Type, (PVOID)Data, (ULONG)Size); free (Data); } return TRUE; }
static LPBYTE get_regdata(const WCHAR *data, DWORD reg_type, WCHAR separator, DWORD *reg_count) { static const WCHAR empty; LPBYTE out_data = NULL; *reg_count = 0; if (!data) data = ∅ switch (reg_type) { case REG_NONE: case REG_SZ: case REG_EXPAND_SZ: { *reg_count = (lstrlenW(data) + 1) * sizeof(WCHAR); out_data = HeapAlloc(GetProcessHeap(),0,*reg_count); lstrcpyW((LPWSTR)out_data,data); break; } case REG_DWORD: /* case REG_DWORD_LITTLE_ENDIAN: */ case REG_DWORD_BIG_ENDIAN: /* Yes, this is correct! */ { LPWSTR rest; DWORD val; val = strtoulW(data, &rest, (tolowerW(data[1]) == 'x') ? 16 : 10); if (*rest || data[0] == '-' || (val == ~0u && errno == ERANGE)) { output_message(STRING_MISSING_INTEGER); break; } *reg_count = sizeof(DWORD); out_data = HeapAlloc(GetProcessHeap(),0,*reg_count); ((LPDWORD)out_data)[0] = val; break; } case REG_BINARY: { BYTE hex0, hex1; int i = 0, destByteIndex = 0, datalen = lstrlenW(data); *reg_count = ((datalen + datalen % 2) / 2) * sizeof(BYTE); out_data = HeapAlloc(GetProcessHeap(), 0, *reg_count); if(datalen % 2) { hex1 = hexchar_to_byte(data[i++]); if(hex1 == 0xFF) goto no_hex_data; out_data[destByteIndex++] = hex1; } for(;i + 1 < datalen;i += 2) { hex0 = hexchar_to_byte(data[i]); hex1 = hexchar_to_byte(data[i + 1]); if(hex0 == 0xFF || hex1 == 0xFF) goto no_hex_data; out_data[destByteIndex++] = (hex0 << 4) | hex1; } break; no_hex_data: /* cleanup, print error */ HeapFree(GetProcessHeap(), 0, out_data); output_message(STRING_MISSING_HEXDATA); out_data = NULL; break; } case REG_MULTI_SZ: { int i, destindex, len = strlenW(data); WCHAR *buffer = HeapAlloc(GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR)); for (i = 0, destindex = 0; i < len; i++, destindex++) { if (!separator && data[i] == '\\' && data[i + 1] == '0') { buffer[destindex] = 0; i++; } else if (data[i] == separator) buffer[destindex] = 0; else buffer[destindex] = data[i]; if (destindex && !buffer[destindex - 1] && (!buffer[destindex] || destindex == 1)) { HeapFree(GetProcessHeap(), 0, buffer); output_message(STRING_INVALID_STRING); return NULL; } } buffer[destindex] = 0; if (destindex && buffer[destindex - 1]) buffer[++destindex] = 0; *reg_count = (destindex + 1) * sizeof(WCHAR); return (BYTE *)buffer; } default: output_message(STRING_UNHANDLED_TYPE, reg_type, data); } return out_data; }