Пример #1
0
/* parses the destination directory parameters from pszSection
 * the parameters are of the form: root,key,value,unknown,fallback
 * we first read the reg value root\\key\\value and if that fails,
 * use fallback as the destination directory
 */
static void get_dest_dir(HINF hInf, PCWSTR pszSection, PWSTR pszBuffer, DWORD dwSize)
{
    INFCONTEXT context;
    WCHAR key[MAX_PATH], value[MAX_PATH];
    WCHAR prefix[PREFIX_LEN];
    HKEY root, subkey;
    DWORD size;

    static const WCHAR hklm[] = {'H','K','L','M',0};
    static const WCHAR hkcu[] = {'H','K','C','U',0};

    /* load the destination parameters */
    SetupFindFirstLineW(hInf, pszSection, NULL, &context);
    SetupGetStringFieldW(&context, 1, prefix, PREFIX_LEN, &size);
    SetupGetStringFieldW(&context, 2, key, MAX_PATH, &size);
    SetupGetStringFieldW(&context, 3, value, MAX_PATH, &size);

    if (!lstrcmpW(prefix, hklm))
        root = HKEY_LOCAL_MACHINE;
    else if (!lstrcmpW(prefix, hkcu))
        root = HKEY_CURRENT_USER;
    else
        root = NULL;

    size = dwSize * sizeof(WCHAR);

    /* fallback to the default destination dir if reg fails */
    if (RegOpenKeyW(root, key, &subkey) ||
        RegQueryValueExW(subkey, value, NULL, NULL, (LPBYTE)pszBuffer, &size))
    {
        SetupGetStringFieldW(&context, 5, pszBuffer, dwSize, NULL);
    }

    RegCloseKey(subkey);
}
Пример #2
0
BOOLEAN
INF_GetData(
	IN PINFCONTEXT Context,
	OUT PWCHAR *Key,
	OUT PWCHAR *Data)
{
#ifdef __REACTOS__
	return InfGetData(Context, Key, Data);
#else
	static PWCHAR pLastCallData[4] = { NULL, NULL, NULL, NULL };
	static DWORD currentIndex = 0;
	DWORD dwSize, i;
	BOOL ret;

	currentIndex ^= 2;

	if (Key) *Key = NULL;
	if (Data) *Data = NULL;

	if (SetupGetFieldCount(Context) != 1)
		return FALSE;

	for (i = 0; i <= 1; i++)
	{
		ret = SetupGetStringFieldW(
			Context,
			i,
			NULL,
			0,
			&dwSize);
		if (!ret)
			return FALSE;
		HeapFree(GetProcessHeap(), 0, pLastCallData[i + currentIndex]);
		pLastCallData[i + currentIndex] = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
		ret = SetupGetStringFieldW(
			Context,
			i,
			pLastCallData[i + currentIndex],
			dwSize,
			NULL);
		if (!ret)
			return FALSE;
	}

	if (Key)
		*Key = pLastCallData[0 + currentIndex];
	if (Data)
		*Data = pLastCallData[1 + currentIndex];
	return TRUE;
#endif /* !__REACTOS__ */
}
Пример #3
0
static BOOL
InstallSysSetupInfDevices(VOID)
{
    INFCONTEXT InfContext;
    WCHAR szLineBuffer[256];
    DWORD dwLineLength;

    if (!SetupFindFirstLineW(hSysSetupInf,
                            L"DeviceInfsToInstall",
                            NULL,
                            &InfContext))
    {
        return FALSE;
    }

    do
    {
        if (!SetupGetStringFieldW(&InfContext,
                                 0,
                                 szLineBuffer,
                                 sizeof(szLineBuffer)/sizeof(szLineBuffer[0]),
                                 &dwLineLength))
        {
            return FALSE;
        }

        if (!SetupDiInstallClassW(NULL, szLineBuffer, DI_QUIETINSTALL, NULL))
        {
            return FALSE;
        }
    }
    while (SetupFindNextLine(&InfContext, &InfContext));

    return TRUE;
}
Пример #4
0
VOID
ParseSetupInf(VOID)
{
    INFCONTEXT InfContext;
    WCHAR szBuffer[30];

    if (!SetupFindFirstLineW(hSetupInf,
                             L"Unattend",
                             L"LocaleID",
                             &InfContext))
    {
        SetupCloseInfFile(hSetupInf);
        DPRINT1("SetupFindFirstLine failed\n");
        return;
    }

    if (!SetupGetStringFieldW(&InfContext, 1, szBuffer,
                              sizeof(szBuffer) / sizeof(WCHAR), NULL))
    {
        SetupCloseInfFile(hSetupInf);
        DPRINT1("SetupGetStringField failed\n");
        return;
    }

    UnattendLCID = wcstoul(szBuffer, NULL, 16);
    IsUnattendedSetupEnabled = 1;
    SetupCloseInfFile(hSetupInf);
}
Пример #5
0
/* retrieves the contents of a field, dynamically growing the buffer if necessary */
static WCHAR *get_field_string(INFCONTEXT *context, DWORD index, WCHAR *buffer,
                               const WCHAR *static_buffer, DWORD *size)
{
    DWORD required;

    if (SetupGetStringFieldW(context, index, buffer, *size, &required)) return buffer;

    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        /* now grow the buffer */
        if (buffer != static_buffer) HeapFree(GetProcessHeap(), 0, buffer);
        if (!(buffer = HeapAlloc(GetProcessHeap(), 0, required*sizeof(WCHAR)))) return NULL;
        *size = required;
        if (SetupGetStringFieldW(context, index, buffer, *size, &required)) return buffer;
    }

    if (buffer != static_buffer) HeapFree(GetProcessHeap(), 0, buffer);
    return NULL;
}
Пример #6
0
BOOLEAN
INF_GetDataField(
	IN PINFCONTEXT Context,
	IN ULONG FieldIndex,
	OUT PWCHAR *Data)
{
#ifdef __REACTOS__
	return InfGetDataField(Context, FieldIndex, Data);
#else
	static PWCHAR pLastCallsData[] = { NULL, NULL, NULL };
	static DWORD NextIndex = 0;
	DWORD dwSize;
	BOOL ret;

	*Data = NULL;

	ret = SetupGetStringFieldW(
		Context,
		FieldIndex,
		NULL,
		0,
		&dwSize);
	if (!ret)
		return FALSE;
	HeapFree(GetProcessHeap(), 0, pLastCallsData[NextIndex]);
	pLastCallsData[NextIndex] = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
	ret = SetupGetStringFieldW(
		Context,
		FieldIndex,
		pLastCallsData[NextIndex],
		dwSize,
		NULL);
	if (!ret)
		return FALSE;

	*Data = pLastCallsData[NextIndex];
	NextIndex = (NextIndex + 1) % (sizeof(pLastCallsData) / sizeof(pLastCallsData[0]));
	return TRUE;
#endif /* !__REACTOS__ */
}
Пример #7
0
static LPWSTR get_source_id( HINF hinf, PINFCONTEXT context, PCWSTR filename )
{
    WCHAR Section[MAX_PATH];
    DWORD size;
    LPWSTR source_id;

    if (!SetupDiGetActualSectionToInstallW(hinf, source_disks_files, Section, MAX_PATH, NULL, NULL))
        return NULL;

    if (!SetupFindFirstLineW( hinf, Section, filename, context ) &&
        !SetupFindFirstLineW( hinf, source_disks_files, filename, context ))
        return NULL;

    if (!SetupGetStringFieldW( context, 1, NULL, 0, &size ))
        return NULL;

    if (!(source_id = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) )))
        return NULL;

    if (!SetupGetStringFieldW( context, 1, source_id, size, NULL ))
    {
        HeapFree( GetProcessHeap(), 0, source_id );
        return NULL;
    }

    if (!SetupDiGetActualSectionToInstallW(hinf, source_disks_names, Section, MAX_PATH, NULL, NULL))
    {
        HeapFree( GetProcessHeap(), 0, source_id );
        return NULL;
    }

    if (!SetupFindFirstLineW( hinf, Section, source_id, context ) &&
        !SetupFindFirstLineW( hinf, source_disks_names, source_id, context ))
    {
        HeapFree( GetProcessHeap(), 0, source_id );
        return NULL;
    }
    return source_id;
}
Пример #8
0
BOOL
RegisterTypeLibraries (HINF hinf, LPCWSTR szSection)
{
    INFCONTEXT InfContext;
    BOOL res;
    WCHAR szName[MAX_PATH];
    WCHAR szPath[MAX_PATH];
    INT csidl;
    LPWSTR p;
    HMODULE hmod;
    HRESULT hret;

    /* Begin iterating the entries in the inf section */
    res = SetupFindFirstLine(hinf, szSection, NULL, &InfContext);
    if (!res) return FALSE;

    do
    {
        /* Get the name of the current type library */
        if (!SetupGetStringFieldW(&InfContext, 1, szName, MAX_PATH, NULL))
        {
            FatalError("SetupGetStringFieldW failed\n");
            continue;
        }

        if (!SetupGetIntField(&InfContext, 2, &csidl))
            csidl = CSIDL_SYSTEM;

        hret = SHGetFolderPathW(NULL, csidl, NULL, 0, szPath);
        if (FAILED(hret))
        {
            FatalError("SHGetFolderPathW failed hret=0x%d\n", hret);
            continue;
        }

        p = PathAddBackslash(szPath);
        _tcscpy(p, szName);

        hmod = LoadLibraryW(szName);
        if (hmod == NULL)
        {
            FatalError("LoadLibraryW failed\n");
            continue;
        }

        __wine_register_resources(hmod);

    }while (SetupFindNextLine(&InfContext, &InfContext));

    return TRUE;
}
Пример #9
0
static BOOL CreateShortcuts(HINF hinf, LPCWSTR szSection)
{
    INFCONTEXT Context;
    WCHAR szPath[MAX_PATH];
    WCHAR szFolder[MAX_PATH];
    WCHAR szFolderSection[MAX_PATH];
    INT csidl;

    CoInitialize(NULL);

    if (!SetupFindFirstLine(hinf, szSection, NULL, &Context))
        return FALSE;

    do
    {
        if (SetupGetFieldCount(&Context) < 2)
            continue;

        if (!SetupGetStringFieldW(&Context, 0, szFolderSection, MAX_PATH, NULL))
            continue;

        if (!SetupGetIntField(&Context, 1, &csidl))
            continue;

        if (!SetupGetStringFieldW(&Context, 2, szFolder, MAX_PATH, NULL))
            continue;

        if (FAILED(SHGetFolderPathAndSubDirW(NULL, csidl|CSIDL_FLAG_CREATE, (HANDLE)-1, SHGFP_TYPE_DEFAULT, szFolder, szPath)))
            continue;

        CreateShortcutsFromSection(hinf, szFolderSection, szPath);

    }while (SetupFindNextLine(&Context, &Context));

    CoUninitialize();

    return TRUE;
}
Пример #10
0
static HRESULT vboxDrvCfgInfQueryKeyValue(PINFCONTEXT pCtx, DWORD iValue, LPWSTR *lppszValue, PDWORD pcValue)
{
    DWORD dwErr;
    DWORD cValue;

    if (!SetupGetStringFieldW(pCtx, iValue, NULL, 0, &cValue))
    {
        dwErr = GetLastError();
//        NonStandardAssert(dwErr == ERROR_INSUFFICIENT_BUFFER);
        if (dwErr != ERROR_INSUFFICIENT_BUFFER)
        {
            NonStandardLogFlowCrap((__FUNCTION__ ": SetupGetStringField failed WinEr (%d) for iValue(%d)\n", dwErr, iValue));
            return HRESULT_FROM_WIN32(dwErr);
        }
    }

    LPWSTR lpszValue = (LPWSTR)malloc(cValue * sizeof (lpszValue[0]));
    NonStandardAssert(lpszValue);
    if (!lpszValue)
    {
        NonStandardLogRelCrap((__FUNCTION__ ": SetCoTaskMemAlloc failed to alloc mem of size (%d), for iValue(%d)\n", cValue * sizeof (lpszValue[0]), dwErr, iValue));
        return E_FAIL;
    }

    if (!SetupGetStringFieldW(pCtx, iValue, lpszValue, cValue, &cValue))
    {
        dwErr = GetLastError();
        NonStandardLogRelCrap((__FUNCTION__ ": SetupGetStringField failed WinEr (%d) for iValue(%d)\n", dwErr, iValue));
        NonStandardAssert(0);
        free(lpszValue);
        return HRESULT_FROM_WIN32(dwErr);
    }

    *lppszValue = lpszValue;
    if (pcValue)
        *pcValue = cValue;
    return S_OK;
}
Пример #11
0
static BOOL CreateShortcutsFromSection(HINF hinf, LPWSTR  pszSection, LPCWSTR pszFolder)
{
    INFCONTEXT Context;
    WCHAR szCommand[MAX_PATH];
    WCHAR szName[MAX_PATH];
    WCHAR szDescription[MAX_PATH];
    INT iIconNr;

    if (!SetupFindFirstLine(hinf, pszSection, NULL, &Context))
        return FALSE;

    do
    {
        if (SetupGetFieldCount(&Context) < 4)
            continue;

        if (!SetupGetStringFieldW(&Context, 1, szCommand, MAX_PATH, NULL))
            continue;

        if (!SetupGetStringFieldW(&Context, 2, szName, MAX_PATH, NULL))
            continue;

        if (!SetupGetStringFieldW(&Context, 3, szDescription, MAX_PATH, NULL))
            continue;

        if (!SetupGetIntField(&Context, 4, &iIconNr))
            continue;

        _tcscat(szName, L".lnk");

        CreateShortcut(pszFolder, szName, szCommand, szDescription, iIconNr);

    }while (SetupFindNextLine(&Context, &Context));

    return TRUE;
}
Пример #12
0
BOOL WINAPI SetupGetSourceInfoW( HINF hinf, UINT source_id, UINT info,
                                 PWSTR buffer, DWORD buffer_size, LPDWORD required_size )
{
    WCHAR Section[MAX_PATH];
    INFCONTEXT ctx;
    WCHAR source_id_str[11];
    static const WCHAR fmt[] = {'%','d',0};
    DWORD index;

    TRACE("%p, %d, %d, %p, %d, %p\n", hinf, source_id, info, buffer, buffer_size,
          required_size);

    sprintfW( source_id_str, fmt, source_id );

    if (!SetupDiGetActualSectionToInstallW(hinf, source_disks_names, Section, MAX_PATH, NULL, NULL))
        return FALSE;

    if (!SetupFindFirstLineW( hinf, Section, source_id_str, &ctx ) &&
        !SetupFindFirstLineW( hinf, source_disks_names, source_id_str, &ctx ))
        return FALSE;

    switch (info)
    {
    case SRCINFO_PATH:          index = 4; break;
    case SRCINFO_TAGFILE:       index = 2; break;
    case SRCINFO_DESCRIPTION:   index = 1; break;
    default:
        WARN("unknown info level: %d\n", info);
        return FALSE;
    }

    if (SetupGetStringFieldW( &ctx, index, buffer, buffer_size, required_size ))
        return TRUE;

    if (required_size) *required_size = 1;
    if (buffer)
    {
        if (buffer_size >= 1) buffer[0] = 0;
        else
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            return FALSE;
        }
    }
    return TRUE;
}
Пример #13
0
static BOOL
GetSupportedCP(VOID)
{
    UINT uiCPage, Number;
    LONG Count;
    INFCONTEXT infCont;
    LPCPAGE lpCPage;
    HANDLE hCPage;
    CPINFOEX cpInfEx;
    //TCHAR Section[MAX_PATH];

    Count = SetupGetLineCountW(hIntlInf, L"CodePages");
    if (Count <= 0) return FALSE;

    for (Number = 0; Number < (UINT)Count; Number++)
    {
        if (SetupGetLineByIndexW(hIntlInf, L"CodePages", Number, &infCont) &&
            SetupGetIntField(&infCont, 0, (PINT)&uiCPage))
        {
            if (!(hCPage = GlobalAlloc(GHND, sizeof(CPAGE)))) return FALSE;

            lpCPage            = GlobalLock(hCPage);
            lpCPage->CPage     = uiCPage;
            lpCPage->hCPage    = hCPage;
            lpCPage->Status    = 0;
            (lpCPage->Name)[0] = 0;

            if (GetCPInfoEx(uiCPage, 0, &cpInfEx))
            {
                wcscpy(lpCPage->Name, cpInfEx.CodePageName);
            }
            else if (!SetupGetStringFieldW(&infCont, 1, lpCPage->Name, MAX_PATH, NULL))
            {
                GlobalUnlock(hCPage);
                GlobalFree(hCPage);
                continue;
            }

            lpCPage->NextItem = PCPage;
            PCPage = lpCPage;
        }
    }

    return TRUE;
}
Пример #14
0
BOOL WINAPI SetupGetSourceFileLocationW( HINF hinf, PINFCONTEXT context, PCWSTR filename,
                                         PUINT source_id, PWSTR buffer, DWORD buffer_size,
                                         PDWORD required_size )
{
    INFCONTEXT ctx;
    WCHAR *end, *source_id_str;

    TRACE("%p, %p, %s, %p, %p, 0x%08x, %p\n", hinf, context, debugstr_w(filename), source_id,
          buffer, buffer_size, required_size);

    if (!context) context = &ctx;

    if (!(source_id_str = get_source_id( hinf, context, filename )))
        return FALSE;

    *source_id = strtolW( source_id_str, &end, 10 );
    if (end == source_id_str || *end)
    {
        HeapFree( GetProcessHeap(), 0, source_id_str );
        return FALSE;
    }
    HeapFree( GetProcessHeap(), 0, source_id_str );

    if (SetupGetStringFieldW( context, 4, buffer, buffer_size, required_size ))
        return TRUE;

    if (required_size) *required_size = 1;
    if (buffer)
    {
        if (buffer_size >= 1) buffer[0] = 0;
        else
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            return FALSE;
        }
    }
    return TRUE;
}
Пример #15
0
static HRESULT register_ocxs_callback(HINF hinf, PCWSTR field, const void *arg)
{
    HMODULE hm;
    INFCONTEXT context;
    HRESULT hr = S_OK;

    BOOL ok = SetupFindFirstLineW(hinf, field, NULL, &context);
    
    for (; ok; ok = SetupFindNextLine(&context, &context))
    {
        WCHAR buffer[MAX_INF_STRING_LENGTH];

        /* get OCX filename */
        if (!SetupGetStringFieldW(&context, 1, buffer,
                                  sizeof(buffer) / sizeof(WCHAR), NULL))
            continue;

        hm = LoadLibraryExW(buffer, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
        if (hm)
        {
            if (do_ocx_reg(hm, TRUE, NULL, NULL) != S_OK)
                hr = E_FAIL;

            FreeLibrary(hm);
        }
        else
            hr = E_FAIL;

        if (FAILED(hr))
        {
            /* FIXME: display a message box */
            break;
        }
    }

    return hr;
}
Пример #16
0
/***********************************************************************
 *            do_reg_operation
 *
 * Perform an add/delete registry operation depending on the flags.
 */
static BOOLEAN
do_reg_operation(HANDLE KeyHandle,
                 PUNICODE_STRING ValueName,
                 PINFCONTEXT Context,
                 ULONG Flags)
{
  WCHAR EmptyStr = (WCHAR)0;
  ULONG Type;
  ULONG Size;

  if (Flags & FLG_ADDREG_DELVAL)  /* deletion */
    {
#if 0
      if (ValueName)
        {
          RegDeleteValueW( KeyHandle, ValueName );
        }
      else
        {
          RegDeleteKeyW( KeyHandle, NULL );
        }
#endif
      return TRUE;
    }

  if (Flags & FLG_ADDREG_KEYONLY)
    return TRUE;

#if 0
  if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY))
    {
      BOOL exists = !RegQueryValueExW( hkey, value, NULL, NULL, NULL, NULL );
      if (exists && (flags & FLG_ADDREG_NOCLOBBER))
        return TRUE;
      if (!exists & (flags & FLG_ADDREG_OVERWRITEONLY))
        return TRUE;
    }
#endif

  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 && SetupGetFieldCount (Context) == 5))
    {
      PWCHAR Str = NULL;

      if (Type == REG_MULTI_SZ)
        {
          if (!SetupGetMultiSzFieldW (Context, 5, NULL, 0, &Size))
            Size = 0;

          if (Size)
            {
              Str = (WCHAR*) RtlAllocateHeap (ProcessHeap, 0, Size * sizeof(WCHAR));
              if (Str == NULL)
                return FALSE;

              SetupGetMultiSzFieldW (Context, 5, Str, Size, NULL);
            }

          if (Flags & FLG_ADDREG_APPEND)
            {
              if (Str == NULL)
                return TRUE;

//            append_multi_sz_value( hkey, value, str, size );

              RtlFreeHeap (ProcessHeap, 0, Str);
              return TRUE;
            }
          /* else fall through to normal string handling */
        }
      else
        {
          if (!SetupGetStringFieldW (Context, 5, NULL, 0, &Size))
            Size = 0;

          if (Size)
            {
              Str = (WCHAR*) RtlAllocateHeap (ProcessHeap, 0, Size * sizeof(WCHAR));
              if (Str == NULL)
                return FALSE;

              SetupGetStringFieldW (Context, 5, Str, Size, NULL);
            }
        }

      if (Type == REG_DWORD)
        {
          ULONG dw = Str ? wcstol (Str, NULL, 0) : 0;

          DPRINT("setting dword %wZ to %lx\n", ValueName, dw);

#ifdef __ODYSSEY__
          NtSetValueKey (KeyHandle,
                         ValueName,
                         0,
                         Type,
                         (PVOID)&dw,
                         sizeof(ULONG));
#else
          RegSetValueExW(KeyHandle, ValueName, 0, Type, (const UCHAR*)&dw, sizeof(ULONG));
#endif
        }
      else
        {
          DPRINT("setting value %wZ to %S\n", ValueName, Str);

          if (Str)
            {
#ifdef __ODYSSEY__
              NtSetValueKey (KeyHandle,
                             ValueName,
                             0,
                             Type,
                             (PVOID)Str,
                             Size * sizeof(WCHAR));
#else
              RegSetValueExW(KeyHandle, ValueName, 0, Type, (const UCHAR*)Str, Size * sizeof(WCHAR));
#endif
            }
          else
            {
#ifdef __ODYSSEY__
              NtSetValueKey (KeyHandle,
                             ValueName,
                             0,
                             Type,
                             (PVOID)&EmptyStr,
                             sizeof(WCHAR));
#else
              RegSetValueExW(KeyHandle, ValueName, 0, Type, (const UCHAR*)&EmptyStr, sizeof(WCHAR));
#endif
            }
        }
      RtlFreeHeap (ProcessHeap, 0, Str);
    }
  else  /* get the binary data */
    {
      PUCHAR Data = NULL;

      if (!SetupGetBinaryField (Context, 5, NULL, 0, &Size))
        Size = 0;

      if (Size)
        {
          Data = (unsigned char*) RtlAllocateHeap (ProcessHeap, 0, Size);
          if (Data == NULL)
            return FALSE;

          DPRINT("setting binary data %wZ len %lu\n", ValueName, Size);
          SetupGetBinaryField (Context, 5, Data, Size, NULL);
        }

#ifdef __ODYSSEY__
      NtSetValueKey (KeyHandle,
                     ValueName,
                     0,
                     Type,
                     (PVOID)Data,
                     Size);
#else
      RegSetValueExW(KeyHandle, ValueName, 0, Type, (const UCHAR*)Data, Size);
#endif

      RtlFreeHeap (ProcessHeap, 0, Data);
    }

  return TRUE;
}
Пример #17
0
static PBOOTRECORD
ReadFreeldrSection(HINF hInf, WCHAR *szSectionName)
{
    PBOOTRECORD pRecord;
    INFCONTEXT InfContext;
    WCHAR szName[MAX_PATH];
    WCHAR szValue[MAX_PATH];
    DWORD LineLength;

    if (!SetupFindFirstLineW(hInf,
                             szSectionName,
                             NULL,
                             &InfContext))
    {
        /* Failed to find section */
        return NULL;
    }

    pRecord = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOTRECORD));
    if (pRecord == NULL)
    {
        return NULL;
    }

    wcscpy(pRecord->szSectionName, szSectionName);

    do
    {
        if (!SetupGetStringFieldW(&InfContext,
                                  0,
                                  szName,
                                  sizeof(szName) / sizeof(WCHAR),
                                  &LineLength))
        {
            break;
        }

        if (!SetupGetStringFieldW(&InfContext,
                                  1,
                                  szValue,
                                  sizeof(szValue) / sizeof(WCHAR),
                                  &LineLength))
        {
            break;
        }

        if (!_wcsnicmp(szName, L"BootType", 8))
        {
            if (!_wcsnicmp(szValue, L"ReactOS", 7))
            {
                // FIXME: Store as enum
                pRecord->BootType = 1;
            }
            else
            {
                pRecord->BootType = 0;
            }
        }
        else if (!_wcsnicmp(szName, L"SystemPath", 10))
        {
            wcscpy(pRecord->szBootPath, szValue);
        }
        else if (!_wcsnicmp(szName, L"Options", 7))
        {
            // FIXME: Store flags as values
            wcscpy(pRecord->szOptions, szValue);
        }

    }
    while (SetupFindNextLine(&InfContext, &InfContext));

    return pRecord;
}
Пример #18
0
static
VOID
InstallPrivileges(VOID)
{
    HINF hSecurityInf = INVALID_HANDLE_VALUE;
    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
    WCHAR szPrivilegeString[256];
    WCHAR szSidString[256];
    INFCONTEXT InfContext;
    DWORD i;
    PRIVILEGE_SET PrivilegeSet;
    PSID AccountSid;
    NTSTATUS Status;
    LSA_HANDLE PolicyHandle = NULL;
    LSA_HANDLE AccountHandle;

    DPRINT("InstallPrivileges()\n");

    hSecurityInf = SetupOpenInfFileW(L"defltws.inf", //szNameBuffer,
                                     NULL,
                                     INF_STYLE_WIN4,
                                     NULL);
    if (hSecurityInf == INVALID_HANDLE_VALUE)
    {
        DPRINT1("SetupOpenInfFileW failed\n");
        return;
    }

    memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));

    Status = LsaOpenPolicy(NULL,
                           &ObjectAttributes,
                           POLICY_CREATE_ACCOUNT,
                           &PolicyHandle);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
        goto done;
    }

    if (!SetupFindFirstLineW(hSecurityInf,
                             L"Privilege Rights",
                             NULL,
                             &InfContext))
    {
        DPRINT1("SetupFindfirstLineW failed\n");
        goto done;
    }

    PrivilegeSet.PrivilegeCount = 1;
    PrivilegeSet.Control = 0;

    do
    {
        /* Retrieve the privilege name */
        if (!SetupGetStringFieldW(&InfContext,
                                  0,
                                  szPrivilegeString,
                                  256,
                                  NULL))
        {
            DPRINT1("SetupGetStringFieldW() failed\n");
            goto done;
        }
        DPRINT("Privilege: %S\n", szPrivilegeString);

        if (!LookupPrivilegeValueW(NULL,
                                   szPrivilegeString,
                                   &(PrivilegeSet.Privilege[0].Luid)))
        {
            DPRINT1("LookupPrivilegeNameW() failed\n");
            goto done;
        }

        PrivilegeSet.Privilege[0].Attributes = 0;

        for (i = 0; i < SetupGetFieldCount(&InfContext); i++)
        {
            if (!SetupGetStringFieldW(&InfContext,
                                      i + 1,
                                      szSidString,
                                      256,
                                      NULL))
            {
                DPRINT1("SetupGetStringFieldW() failed\n");
                goto done;
            }
            DPRINT("SID: %S\n", szSidString);

            ConvertStringSidToSid(szSidString, &AccountSid);

            Status = LsaOpenAccount(PolicyHandle,
                                    AccountSid,
                                    ACCOUNT_VIEW | ACCOUNT_ADJUST_PRIVILEGES,
                                    &AccountHandle);
            if (NT_SUCCESS(Status))
            {
                Status = LsaAddPrivilegesToAccount(AccountHandle,
                                                   &PrivilegeSet);
                if (!NT_SUCCESS(Status))
                {
                    DPRINT1("LsaAddPrivilegesToAccount() failed (Status %08lx)\n", Status);
                }

                LsaClose(AccountHandle);
            }

            LocalFree(AccountSid);
        }

    }
    while (SetupFindNextLine(&InfContext, &InfContext));

done:
    if (PolicyHandle != NULL)
        LsaClose(PolicyHandle);

    if (hSecurityInf != INVALID_HANDLE_VALUE)
        SetupCloseInfFile(hSecurityInf);
}
Пример #19
0
static INT
LoadFreeldrSettings(HINF hInf, HWND hwndDlg)
{
    INFCONTEXT InfContext;
    PBOOTRECORD pRecord;
    WCHAR szDefaultOs[MAX_PATH];
    WCHAR szName[MAX_PATH];
    WCHAR szValue[MAX_PATH];
    DWORD LineLength;
    DWORD TimeOut;
    LRESULT lResult;

    if (!SetupFindFirstLineW(hInf,
                             L"FREELOADER",
                             L"DefaultOS",
                             &InfContext))
    {
        /* Failed to find default os */
        return FALSE;
    }

    if (!SetupGetStringFieldW(&InfContext,
                              1,
                              szDefaultOs,
                              sizeof(szDefaultOs) / sizeof(WCHAR),
                              &LineLength))
    {
        /* No key */
        return FALSE;
    }

    if (!SetupFindFirstLineW(hInf,
                             L"FREELOADER",
                             L"TimeOut",
                             &InfContext))
    {
        /* Expected to find timeout value */
        return FALSE;
    }


    if (!SetupGetIntField(&InfContext,
                          1,
                          (PINT)&TimeOut))
    {
        /* Failed to retrieve timeout */
        return FALSE;
    }

    if (!SetupFindFirstLineW(hInf,
                             L"Operating Systems",
                             NULL,
                             &InfContext))
    {
        /* Expected list of operating systems */
        return FALSE;
    }

    do
    {
        if (!SetupGetStringFieldW(&InfContext,
                                  0,
                                  szName,
                                  sizeof(szName) / sizeof(WCHAR),
                                  &LineLength))
        {
            /* The ini file is messed up */
            return FALSE;
        }

        if (!SetupGetStringFieldW(&InfContext,
                                  1,
                                  szValue,
                                  sizeof(szValue) / sizeof(WCHAR),
                                  &LineLength))
        {
            /* The ini file is messed up */
            return FALSE;
        }

        pRecord = ReadFreeldrSection(hInf, szName);
        if (pRecord)
        {
            lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValue);
            if (lResult != CB_ERR)
            {
                SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)pRecord);
                if (!wcscmp(szDefaultOs, szName))
                {
                    /* We store the friendly name as key */
                    wcscpy(szDefaultOs, szValue);
                }
            }
            else
            {
                HeapFree(GetProcessHeap(), 0, pRecord);
            }
        }
    }
    while (SetupFindNextLine(&InfContext, &InfContext));

    /* Find default os in list */
    lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_FINDSTRING, (WPARAM)-1, (LPARAM)szDefaultOs);
    if (lResult != CB_ERR)
    {
        /* Set cur sel */
        SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)lResult, (LPARAM)0);
    }

    if(TimeOut)
    {
        SendDlgItemMessageW(hwndDlg, IDC_STRECLIST, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
    }

    SetTimeout(hwndDlg, TimeOut);

    return TRUE;
}
Пример #20
0
static INT
LoadBootSettings(HINF hInf, HWND hwndDlg)
{
    INFCONTEXT InfContext;
    WCHAR szName[MAX_PATH];
    WCHAR szValue[MAX_PATH];
    DWORD LineLength;
    DWORD TimeOut = 0;
    WCHAR szDefaultOS[MAX_PATH];
    WCHAR szOptions[MAX_PATH];
    PBOOTRECORD pRecord;
    LRESULT lResult;

    if(!SetupFindFirstLineW(hInf,
                            L"boot loader",
                            NULL,
                            &InfContext))
    {
        return FALSE;
    }

    do
    {
        if (!SetupGetStringFieldW(&InfContext,
                                  0,
                                  szName,
                                  sizeof(szName) / sizeof(WCHAR),
                                  &LineLength))
        {
            return FALSE;
        }

        if (!SetupGetStringFieldW(&InfContext,
                                  1,
                                  szValue,
                                  sizeof(szValue) / sizeof(WCHAR),
                                  &LineLength))
        {
            return FALSE;
        }

        if (!_wcsnicmp(szName, L"timeout", 7))
        {
            TimeOut = _wtoi(szValue);
        }

        if (!_wcsnicmp(szName, L"default", 7))
        {
            wcscpy(szDefaultOS, szValue);
        }

    }
    while (SetupFindNextLine(&InfContext, &InfContext));

    if (!SetupFindFirstLineW(hInf,
                             L"operating systems",
                             NULL,
                             &InfContext))
    {
        /* Failed to find operating systems section */
        return FALSE;
    }

    do
    {
        if (!SetupGetStringFieldW(&InfContext,
                                  0,
                                  szName,
                                  sizeof(szName) / sizeof(WCHAR),
                                  &LineLength))
        {
            return FALSE;
        }

        if (!SetupGetStringFieldW(&InfContext,
                                  1,
                                  szValue,
                                  sizeof(szValue) / sizeof(WCHAR),
                                  &LineLength))
        {
            return FALSE;
        }

        SetupGetStringFieldW(&InfContext,
                             2,
                             szOptions,
                             sizeof(szOptions) / sizeof(WCHAR),
                             &LineLength);

        pRecord = (PBOOTRECORD) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOTRECORD));
        if (pRecord)
        {
            pRecord->BootType = 0;
            wcscpy(pRecord->szBootPath, szName);
            wcscpy(pRecord->szSectionName, szValue);
            wcscpy(pRecord->szOptions, szOptions);

            if (!wcscmp(szName, szDefaultOS))
            {
                /* ms boot ini stores the path not the friendly name */
                wcscpy(szDefaultOS, szValue);
            }

            lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValue);
            if (lResult != CB_ERR)
            {
                SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)pRecord);
            }
            else
            {
                HeapFree(GetProcessHeap(), 0, pRecord);
            }
        }

    }
    while (SetupFindNextLine(&InfContext, &InfContext));

    /* Find default os in list */
    lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_FINDSTRING, (WPARAM)0, (LPARAM)szDefaultOS);
    if (lResult != CB_ERR)
    {
        /* Set cur sel */
        SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)lResult, (LPARAM)0);
    }

    if(TimeOut)
    {
        SendDlgItemMessageW(hwndDlg, IDC_STRECLIST, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
    }

    SetTimeout(hwndDlg, TimeOut);

    return TRUE;
}
Пример #21
0
static BOOL
InstallSysSetupInfComponents(VOID)
{
    INFCONTEXT InfContext;
    WCHAR szNameBuffer[256];
    WCHAR szSectionBuffer[256];
    HINF hComponentInf = INVALID_HANDLE_VALUE;

    if (!SetupFindFirstLineW(hSysSetupInf,
                            L"Infs.Always",
                            NULL,
                            &InfContext))
    {
        DPRINT("No Inf.Always section found\n");
    }
    else
    {
        do
        {
            if (!SetupGetStringFieldW(&InfContext,
                                     1, // Get the component name
                                     szNameBuffer,
                                     sizeof(szNameBuffer)/sizeof(szNameBuffer[0]),
                                     NULL))
            {
                FatalError("Error while trying to get component name \n");
                return FALSE;
            }

            if (!SetupGetStringFieldW(&InfContext,
                                     2, // Get the component install section
                                     szSectionBuffer,
                                     sizeof(szSectionBuffer)/sizeof(szSectionBuffer[0]),
                                     NULL))
            {
                FatalError("Error while trying to get component install section \n");
                return FALSE;
            }

            DPRINT("Trying to execute install section '%S' from '%S' \n", szSectionBuffer, szNameBuffer);

            hComponentInf = SetupOpenInfFileW(szNameBuffer,
                                              NULL,
                                              INF_STYLE_WIN4,
                                              NULL);

            if (hComponentInf == INVALID_HANDLE_VALUE)
            {
                FatalError("SetupOpenInfFileW() failed to open '%S' (Error: %lu)\n", szNameBuffer, GetLastError());
                return FALSE;
            }

            if (!SetupInstallFromInfSectionW(NULL,
                                            hComponentInf,
                                            szSectionBuffer,
                                            SPINST_ALL,
                                            NULL,
                                            NULL,
                                            SP_COPY_NEWER,
                                            SetupDefaultQueueCallbackW,
                                            NULL,
                                            NULL,
                                            NULL))
           {
                FatalError("Error while trying to install : %S (Error: %lu)\n", szNameBuffer, GetLastError());
                SetupCloseInfFile(hComponentInf);
                return FALSE;
           }

           SetupCloseInfFile(hComponentInf);
        }
        while (SetupFindNextLine(&InfContext, &InfContext));
    }

    return TRUE;
}
Пример #22
0
/* loads the LDIDs specified in the install section of an INF */
void set_ldids(HINF hInf, LPCWSTR pszInstallSection, LPCWSTR pszWorkingDir)
{
    WCHAR field[MAX_FIELD_LENGTH];
    WCHAR line[MAX_FIELD_LENGTH];
    WCHAR dest[MAX_PATH];
    INFCONTEXT context;
    DWORD size;
    int ldid;

    static const WCHAR source_dir[] = {'S','o','u','r','c','e','D','i','r',0};

    static const WCHAR custDestW[] = {
        'C','u','s','t','o','m','D','e','s','t','i','n','a','t','i','o','n',0
    };

    if (!SetupGetLineTextW(NULL, hInf, pszInstallSection, custDestW,
                           field, MAX_FIELD_LENGTH, &size))
        return;

    if (!SetupFindFirstLineW(hInf, field, NULL, &context))
        return;

    do
    {
        LPWSTR value, ptr, key, key_copy = NULL;
        DWORD flags = 0;

        SetupGetLineTextW(&context, NULL, NULL, NULL,
                          line, MAX_FIELD_LENGTH, &size);

        /* SetupGetLineTextW returns the value if there is only one key, but
         * returns the whole line if there is more than one key
         */
        if (!(value = strchrW(line, '=')))
        {
            SetupGetStringFieldW(&context, 0, NULL, 0, &size);
            key = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
            key_copy = key;
            SetupGetStringFieldW(&context, 0, key, size, &size);
            value = line;
        }
        else
        {
            key = line;
            *(value++) = '\0';
        }

        /* remove leading whitespace from the value */
        while (*value == ' ')
            value++;

        /* Extract the flags */
        ptr = strchrW(value, ',');
        if (ptr) {
            *ptr = '\0';
            flags = atolW(ptr+1);
        }

        /* set dest to pszWorkingDir if key is SourceDir */
        if (pszWorkingDir && !lstrcmpiW(value, source_dir))
            lstrcpynW(dest, pszWorkingDir, MAX_PATH);
        else
            get_dest_dir(hInf, value, dest, MAX_PATH);

        /* If prompting required, provide dialog to request path */
        if (flags & 0x04)
            FIXME("Need to support changing paths - default will be used\n");

        /* set all ldids to dest */
        while ((ptr = get_parameter(&key, ',', FALSE)))
        {
            ldid = atolW(ptr);
            SetupSetDirectoryIdW(hInf, ldid, dest);
        }
        HeapFree(GetProcessHeap(), 0, key_copy);
    } while (SetupFindNextLine(&context, &context));
}
Пример #23
0
DWORD WINAPI
NetClassInstaller(
	IN DI_FUNCTION InstallFunction,
	IN HDEVINFO DeviceInfoSet,
	IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
{
	SP_DRVINFO_DATA_W DriverInfoData;
	SP_DRVINFO_DETAIL_DATA_W DriverInfoDetail;
	WCHAR SectionName[LINE_LEN];
	HINF hInf = INVALID_HANDLE_VALUE;
	INFCONTEXT InfContext;
	UINT ErrorLine;
	INT CharacteristicsInt;
	DWORD Characteristics;
	LPWSTR BusType = NULL;
	RPC_STATUS RpcStatus;
	UUID Uuid;
	LPWSTR UuidRpcString = NULL;
	LPWSTR UuidString = NULL;
	LONG rc;
	DWORD dwLength;

	if (InstallFunction != DIF_INSTALLDEVICE)
		return ERROR_DI_DO_DEFAULT;

	DPRINT("%lu %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);

	/* Get driver info details */
	DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA_W);
	if (!SetupDiGetSelectedDriverW(DeviceInfoSet, DeviceInfoData, &DriverInfoData))
	{
		rc = GetLastError();
		DPRINT("SetupDiGetSelectedDriverW() failed with error 0x%lx\n", rc);
		goto cleanup;
	}
	DriverInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W);
	if (!SetupDiGetDriverInfoDetailW(DeviceInfoSet, DeviceInfoData, &DriverInfoData, &DriverInfoDetail, sizeof(DriverInfoDetail), NULL)
	 && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
	{
		rc = GetLastError();
		DPRINT("SetupDiGetDriverInfoDetailW() failed with error 0x%lx\n", rc);
		goto cleanup;
	}
	hInf = SetupOpenInfFileW(DriverInfoDetail.InfFileName, NULL, INF_STYLE_WIN4, &ErrorLine);
	if (hInf == INVALID_HANDLE_VALUE)
	{
		rc = GetLastError();
		DPRINT("SetupOpenInfFileW() failed with error 0x%lx\n", rc);
		goto cleanup;
	}
	if (!SetupDiGetActualSectionToInstallW(hInf, DriverInfoDetail.SectionName, SectionName, LINE_LEN, NULL, NULL))
	{
		rc = GetLastError();
		DPRINT("SetupDiGetActualSectionToInstallW() failed with error 0x%lx\n", rc);
		goto cleanup;
	}

	/* Get Characteristics and BusType (optional) from .inf file */
	if (!SetupFindFirstLineW(hInf, SectionName, L"Characteristics", &InfContext))
	{
		rc = GetLastError();
		DPRINT("Unable to find key %S in section %S of file %S (error 0x%lx)\n",
			L"Characteristics", SectionName, DriverInfoDetail.InfFileName, rc);
		goto cleanup;
	}
	if (!SetupGetIntField(&InfContext, 1, &CharacteristicsInt))
	{
		rc = GetLastError();
		DPRINT("SetupGetIntField() failed with error 0x%lx\n", rc);
		goto cleanup;
	}
	Characteristics = (DWORD)CharacteristicsInt;
	if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NET))
	{
		if (SetupFindFirstLineW(hInf, SectionName, L"BusType", &InfContext))
		{
			if (!SetupGetStringFieldW(&InfContext, 1, NULL, 0, &dwLength))
			{
				rc = GetLastError();
				DPRINT("SetupGetStringFieldW() failed with error 0x%lx\n", rc);
				goto cleanup;
			}
			BusType = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR));
			if (!BusType)
			{
				DPRINT("HeapAlloc() failed\n");
				rc = ERROR_NOT_ENOUGH_MEMORY;
				goto cleanup;
			}
			if (!SetupGetStringFieldW(&InfContext, 1, BusType, dwLength, NULL))
			{
				rc = GetLastError();
				DPRINT("SetupGetStringFieldW() failed with error 0x%lx\n", rc);
				goto cleanup;
			}
		}
	}

	/* Create a new UUID */
	RpcStatus = UuidCreate(&Uuid);
	if (RpcStatus != RPC_S_OK && RpcStatus != RPC_S_UUID_LOCAL_ONLY)
	{
		DPRINT("UuidCreate() failed with RPC status 0x%lx\n", RpcStatus);
		rc = ERROR_GEN_FAILURE;
		goto cleanup;
	}
	RpcStatus = UuidToStringW(&Uuid, &UuidRpcString);
	if (RpcStatus != RPC_S_OK)
	{
		DPRINT("UuidToStringW() failed with RPC status 0x%lx\n", RpcStatus);
		rc = ERROR_GEN_FAILURE;
		goto cleanup;
	}

	/* Add curly braces around Uuid */
	UuidString = HeapAlloc(GetProcessHeap(), 0, (2 + wcslen(UuidRpcString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
	if (!UuidString)
	{
		DPRINT("HeapAlloc() failed\n");
		rc = ERROR_NOT_ENOUGH_MEMORY;
		goto cleanup;
	}
	wcscpy(UuidString, L"{");
	wcscat(UuidString, UuidRpcString);
	wcscat(UuidString, L"}");

	if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NET))
		rc = InstallNetDevice(DeviceInfoSet, DeviceInfoData, UuidString, Characteristics, BusType);
	else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETCLIENT))
		rc = InstallNetClient();
	else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETSERVICE))
		rc = InstallNetService();
	else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETTRANS))
		rc = InstallNetTransport();
	else
	{
		DPRINT("Invalid class guid\n");
		rc = ERROR_GEN_FAILURE;
	}

cleanup:
	if (hInf != INVALID_HANDLE_VALUE)
		SetupCloseInfFile(hInf);
	if (UuidRpcString != NULL)
		RpcStringFreeW(&UuidRpcString);
	HeapFree(GetProcessHeap(), 0, BusType);
	HeapFree(GetProcessHeap(), 0, UuidString);

	if (rc == ERROR_SUCCESS)
		rc = ERROR_DI_DO_DEFAULT;
	DPRINT("Returning 0x%lx\n", rc);
	return rc;
}
Пример #24
0
/***********************************************************************
 *            registry_callback
 *
 * Called once for each AddReg and DelReg entry in a given section.
 */
static BOOLEAN
registry_callback (HINF hInf, PCWSTR Section, BOOLEAN Delete)
{
  OBJECT_ATTRIBUTES ObjectAttributes;
  WCHAR Buffer[MAX_INF_STRING_LENGTH];
  UNICODE_STRING Name;
  UNICODE_STRING Value;
  PUNICODE_STRING ValuePtr;
  NTSTATUS Status;
  UINT Flags;
  ULONG Length;

  INFCONTEXT Context;
  HANDLE KeyHandle;
  BOOLEAN Ok;


  Ok = SetupFindFirstLineW (hInf, Section, NULL, &Context);

  if (Ok)
    {
      for (;Ok; Ok = SetupFindNextLine (&Context, &Context))
        {
          /* get root */
          if (!SetupGetStringFieldW (&Context, 1, Buffer, MAX_INF_STRING_LENGTH, NULL))
              continue;
          if (!GetRootKey (Buffer))
            continue;

          /* get key */
          Length = wcslen (Buffer);
          if (!SetupGetStringFieldW (&Context, 2, Buffer + Length, MAX_INF_STRING_LENGTH - Length, NULL))
            *Buffer = 0;

          DPRINT("KeyName: <%S>\n", Buffer);

          /* get flags */
          if (!SetupGetIntField (&Context, 4, (PINT)&Flags))
            Flags = 0;

          DPRINT("Flags: %lx\n", Flags);

#ifdef __ODYSSEY__
          RtlInitUnicodeString (&Name,
                                Buffer);

          InitializeObjectAttributes (&ObjectAttributes,
                                      &Name,
                                      OBJ_CASE_INSENSITIVE,
                                      NULL,
                                      NULL);

          if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY))
            {
              Status = NtOpenKey (&KeyHandle,
                                  KEY_ALL_ACCESS,
                                  &ObjectAttributes);
              if (!NT_SUCCESS(Status))
                {
                  DPRINT("NtOpenKey(%wZ) failed (Status %lx)\n", &Name, Status);
                  continue;  /* ignore if it doesn't exist */
                }
            }
          else
            {
              Status = CreateNestedKey (&KeyHandle,
                                        KEY_ALL_ACCESS,
                                        &ObjectAttributes);
              if (!NT_SUCCESS(Status))
                {
                  DPRINT("CreateNestedKey(%wZ) failed (Status %lx)\n", &Name, Status);
                  continue;
                }
            }
#else
          if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY))
             {
                LONG rc = RegOpenKeyW(NULL, Buffer, &KeyHandle);
                if (rc != ERROR_SUCCESS)
                  {
                    DPRINT("RegOpenKeyW(%S) failed (error %lu)\n", Buffer, rc);
                    continue; /* ignore if it doesn't exist */
                  }
              }
              else
              {
                  LONG rc = RegCreateKeyW(NULL, Buffer, &KeyHandle);
                  if (rc != ERROR_SUCCESS)
                  {
                    DPRINT("RegCreateKeyW(%S) failed (error %lu)\n", Buffer, rc);
                    continue;
                  }
              }
#endif

          /* get value name */
          if (SetupGetStringFieldW (&Context, 3, Buffer, MAX_INF_STRING_LENGTH, NULL))
            {
              RtlInitUnicodeString (&Value,
                                    Buffer);
              ValuePtr = &Value;
            }
          else
            {
              ValuePtr = NULL;
            }

          /* and now do it */
          if (!do_reg_operation (KeyHandle, ValuePtr, &Context, Flags))
            {
              NtClose (KeyHandle);
              return FALSE;
            }

#ifdef __ODYSSEY__
          NtClose (KeyHandle);
#endif
        }
    }

  return TRUE;
}