/*
 * Windows and DOS version functions
 *
 * Copyright 1997 Alexandre Julliard
 * Copyright 1997 Marcus Meissner
 * Copyright 1998 Patrik Stridvall
 * Copyright 1998 Andreas Mohr
 */

#include <string.h>
#include <stdlib.h>
#include "winbase.h"
#include "winuser.h"
#include "wine/winbase16.h"
#include "process.h"
#include "options.h"
#include "debugtools.h"
#include "neexe.h"
#include "winversion.h"
#include "winerror.h"

DEFAULT_DEBUG_CHANNEL(ver)

typedef struct
{
    LONG             getVersion16; 
    LONG             getVersion32;
    OSVERSIONINFOA getVersionEx;
} VERSION_DATA;


/* FIXME: compare values below with original and fix */
static VERSION_DATA VersionData[NB_WINDOWS_VERSIONS] =
{
    /* WIN31 */
    {
	MAKELONG( 0x0a03, 0x0616 ), /* DOS 6.22 */
	MAKELONG( 0x0a03, 0x8000 ),
	{
            sizeof(OSVERSIONINFOA), 3, 10, 0,
            VER_PLATFORM_WIN32s, "Win32s 1.3" 
	}
    },
    /* WIN95 */
    {
        0x07005F03,
        0xC0000004,
	{
            sizeof(OSVERSIONINFOA), 4, 0, 0x40003B6,
            VER_PLATFORM_WIN32_WINDOWS, "Win95"
	}
    },
    /* WIN98 */
    {
	0x07005F03,	/* FIXME: need DOS value from real Win98 */
	0xC0000A04,
	{
	    sizeof(OSVERSIONINFOA), 4, 10, 0x40A07CE,
	    VER_PLATFORM_WIN32_WINDOWS, "Win98"
	}
    },
    /* NT351 */
    {
        0x05000A03,
        0x04213303,
        {
            sizeof(OSVERSIONINFOA), 3, 51, 0x421,
            VER_PLATFORM_WIN32_NT, "Service Pack 2"
	}
    },
    /* NT40 */
    {
        0x05000A03,
        0x05650004,
        {
            sizeof(OSVERSIONINFOA), 4, 0, 0x565,
            VER_PLATFORM_WIN32_NT, "Service Pack 3"
        }
    }
};

static const char *WinVersionNames[NB_WINDOWS_VERSIONS] =
{
    "win31",
    "win95",
    "win98",
    "nt351",
    "nt40"
};

/* the current version has not been autodetected but forced via cmdline */
static BOOL versionForced = FALSE;
static WINDOWS_VERSION defaultWinVersion = WIN31;


/**********************************************************************
 *         VERSION_ParseWinVersion
 */
void VERSION_ParseWinVersion( const char *arg )
{
    int i;
    for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
    {
        if (!strcmp( WinVersionNames[i], arg ))
        {
            defaultWinVersion = (WINDOWS_VERSION)i;
            versionForced = TRUE;
            return;
        }
    }
    MESSAGE("Invalid winver value '%s' specified.\n", arg );
    MESSAGE("Valid versions are:" );
    for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
        MESSAGE(" '%s'%c", WinVersionNames[i],
	    (i == NB_WINDOWS_VERSIONS - 1) ? '\n' : ',' );
}


/**********************************************************************
 *         VERSION_ParseDosVersion
 */
void VERSION_ParseDosVersion( const char *arg )
{
    int hi, lo;
    if (sscanf( arg, "%d.%d", &hi, &lo ) == 2)
    {
        VersionData[WIN31].getVersion16 =
            MAKELONG(LOWORD(VersionData[WIN31].getVersion16),
                     (hi<<8) + lo);
    }
    else
        fprintf( stderr, "-dosver: Wrong version format. Use \"-dosver x.xx\"\n");
}


WINDOWS_VERSION VERSION_GetImageVersion(PDB *pdb)
{
    PIMAGE_NT_HEADERS peheader;

	if (!pdb->exe_modref)
	{
		/* HACK: if we have loaded a PE image into this address space,
		 * we are probably using thunks, so Win95 is our best bet
		 */
		if (pdb->modref_list)
			return WIN95;
		/* FIXME: hmm, do anything else ?
		   TDB.version doesn't help here
		   as it always holds version 3.10 */
			return WIN31;
	}
	else
	{
		peheader = PE_HEADER(pdb->exe_modref->module);
#define OPTHD peheader->OptionalHeader

		TRACE("%02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n",
			  OPTHD.MajorLinkerVersion,
			  OPTHD.MinorLinkerVersion,
			  OPTHD.MajorOperatingSystemVersion,
			  OPTHD.MinorOperatingSystemVersion,
			  OPTHD.MajorImageVersion,
			  OPTHD.MinorImageVersion,
			  OPTHD.MajorSubsystemVersion,
			  OPTHD.MinorSubsystemVersion);

        switch (OPTHD.MajorSubsystemVersion)
		{
			case 4:
				switch (OPTHD.MajorOperatingSystemVersion)
				{
					case 5:
						return NT40; /* FIXME: this is NT 5, isn't it ? */
					case 4:
						if ((OPTHD.MajorImageVersion == 0) &&
							(OPTHD.SectionAlignment == 4096))
							return WIN95;
						else
							return NT40;
					case 1:
						return WIN95;
					default:
						return WIN95; /* FIXME ? */
				}
			case 3:
				/* 3.1x versions */
				if (OPTHD.MinorSubsystemVersion <= 11)
				{
					if (OPTHD.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
						return NT351; /* FIXME: NT 3.1 */
					else
						return WIN31;
				}
				else
				{
					/* NT 3.51 */
					if (OPTHD.MinorSubsystemVersion == 50)
						return NT351;
					else
					if (OPTHD.MinorSubsystemVersion == 51)
						return NT351;
				}
			default:
				if (OPTHD.MajorSubsystemVersion)
				ERR("unknown subsystem version: %04x.%04x, please report.\n",
					OPTHD.MajorSubsystemVersion,
					OPTHD.MinorSubsystemVersion );
				return defaultWinVersion;
		}
#undef OPTHD
	}
}


/**********************************************************************
 *
 * Check the version of COMDLG32, SHELL32, COMCTL32 and CTL3D32.
 * Not functional yet.
 */
DWORD VERSION_GetLinkedDllVersion(PDB *pdb)
{
	WINE_MODREF *wm;
    WORD VersionCounter[NB_WINDOWS_VERSIONS];

    memset(VersionCounter, 0, sizeof(VersionCounter));

	VersionCounter[WIN95] = 1;
	for ( wm = PROCESS_Current()->modref_list; wm; wm=wm->next ) {
	    if (!(lstrncmpiA(wm->modname, "CTL3D32", 7)))
			VersionCounter[WIN95]++;
	}

	return MAKELONG(WIN95, VersionCounter[WIN95]);
}


/**********************************************************************
 *         VERSION_GetVersion
 *
 * WARNING !!!
 * Don't call this function too early during the Wine init,
 * as pdb->exe_modref (required by VERSION_GetImageVersion()) might still
 * be NULL in such cases, which causes the winver to ALWAYS be detected
 * as WIN31.
 * And as we cache the winver once it has been determined, this is bad.
 * This can happen much easier than you might think, as this function
 * is called by EVERY GetVersion*() API !
 *
 * Some version data:
 * linker/OS/image/subsys	Name			Intended for
 *
 * 2.39/1.00/0.00/3.10		freecell.exe	Win32s (any version)
 * 2.55/1.00/0.00/4.00		acrord32.exe	Win32s, Win95 supported (?)
 * 
 * 2.50/1.00/4.00/4.00		winhlp32.exe	Win32s 1.30
 * 4.20/4.00/1.00/4.00		Asuslm.exe		Win95 (Aaargh !)
 * 5.12/4.00/1.07/4.00      clikfixi.exe    NT 4 (service pack files)
 * 3.10/4.00/4.00/4.00		PLUMBING.EXE	NT
 * ?.??/4.00/97.01/4.00		sse.exe			huh ?? (damn crackerz ;)
 * 5.12/5.00/5.00/4.00		comctl32.dll	NT4 / IE 5.0
 * 6.00/5.00/5.00/4.00						NT 4 driver update (strange numbers)
 * 
 * Common versions:
 * x.xx/1.00/0.00/3.10						Win32s (any version ?)
 * 2.xx/1.00/0.00/4.00						Win95 (Microsoft/system files) 
 * x.xx/4.00/0.00/4.00						Win95 (most applications !)
 * x.xx/4.00/4.00/4.00						NT 4 (most apps)
 * x.xx/5.00/5.00/4.00						NT 4 newer files / NT 5 ??
 */
WINDOWS_VERSION VERSION_GetVersion(void)
{
    PDB *pdb = PROCESS_Current();
    DWORD DllVer;

    if (versionForced) /* user has overridden any sensible checks */
        return defaultWinVersion;

    if (pdb->winver == 0xffff) /* to be determined */
        {
		DllVer = 0/*VERSION_GetLinkedDllVersion(pdb)*/;
		if (HIWORD(DllVer) > 1)
			pdb->winver = LOWORD(DllVer);
            else
			pdb->winver = VERSION_GetImageVersion(pdb);
        }

	return pdb->winver;
}


/**********************************************************************
 *         VERSION_GetVersionName
 */
char *VERSION_GetVersionName()
{
  WINDOWS_VERSION ver = VERSION_GetVersion();
  switch(ver)
    {
    case WIN31:
      return "Windows 3.1";
    case WIN95:  
      return "Windows 95";
    case WIN98:
      return "Windows 98";
    case NT351:
      return "Windows NT 3.51";
    case NT40:
      return "Windows NT 4.0";
    default:
      FIXME("Windows version %d not named",ver);
      return "Windows <Unknown>";
    }
}

/***********************************************************************
 *         GetVersion16   (KERNEL.3)
 */
LONG WINAPI GetVersion16(void)
{
    WINDOWS_VERSION ver = VERSION_GetVersion();
    return VersionData[ver].getVersion16;
}


/***********************************************************************
 *         GetVersion32   (KERNEL32.427)
 */
LONG WINAPI GetVersion(void)
{
    WINDOWS_VERSION ver = VERSION_GetVersion();
    return VersionData[ver].getVersion32;
}


/***********************************************************************
 *         GetVersionEx16   (KERNEL.149)
 */
BOOL16 WINAPI GetVersionEx16(OSVERSIONINFO16 *v)
{
    WINDOWS_VERSION ver = VERSION_GetVersion();
    if (v->dwOSVersionInfoSize != sizeof(OSVERSIONINFO16))
    {
        WARN("wrong OSVERSIONINFO size from app (got: %ld, expected: %d)",
                        v->dwOSVersionInfoSize, sizeof(OSVERSIONINFO16));
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }
    v->dwMajorVersion = VersionData[ver].getVersionEx.dwMajorVersion;
    v->dwMinorVersion = VersionData[ver].getVersionEx.dwMinorVersion;
    v->dwBuildNumber  = VersionData[ver].getVersionEx.dwBuildNumber;
    v->dwPlatformId   = VersionData[ver].getVersionEx.dwPlatformId;
    strcpy( v->szCSDVersion, VersionData[ver].getVersionEx.szCSDVersion );
    return TRUE;
}


/***********************************************************************
 *         GetVersionEx32A   (KERNEL32.428)
 */
BOOL WINAPI GetVersionExA(OSVERSIONINFOA *v)
{
    WINDOWS_VERSION ver = VERSION_GetVersion();
    if (v->dwOSVersionInfoSize != sizeof(OSVERSIONINFOA))
    {
        WARN("wrong OSVERSIONINFO size from app (got: %ld, expected: %d)",
                        v->dwOSVersionInfoSize, sizeof(OSVERSIONINFOA));
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }
    v->dwMajorVersion = VersionData[ver].getVersionEx.dwMajorVersion;
    v->dwMinorVersion = VersionData[ver].getVersionEx.dwMinorVersion;
    v->dwBuildNumber  = VersionData[ver].getVersionEx.dwBuildNumber;
    v->dwPlatformId   = VersionData[ver].getVersionEx.dwPlatformId;
    strcpy( v->szCSDVersion, VersionData[ver].getVersionEx.szCSDVersion );
    return TRUE;
}


/***********************************************************************
 *         GetVersionEx32W   (KERNEL32.429)
 */
BOOL WINAPI GetVersionExW(OSVERSIONINFOW *v)
{
    WINDOWS_VERSION ver = VERSION_GetVersion();

    if (v->dwOSVersionInfoSize!=sizeof(OSVERSIONINFOW))
    {
        WARN("wrong OSVERSIONINFO size from app (got: %ld, expected: %d)",
			v->dwOSVersionInfoSize, sizeof(OSVERSIONINFOW));
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }
    v->dwMajorVersion = VersionData[ver].getVersionEx.dwMajorVersion;
    v->dwMinorVersion = VersionData[ver].getVersionEx.dwMinorVersion;
    v->dwBuildNumber  = VersionData[ver].getVersionEx.dwBuildNumber;
    v->dwPlatformId   = VersionData[ver].getVersionEx.dwPlatformId;
    lstrcpyAtoW( v->szCSDVersion, VersionData[ver].getVersionEx.szCSDVersion );
    return TRUE;
}


/***********************************************************************
 *	    GetWinFlags   (KERNEL.132)
 */
DWORD WINAPI GetWinFlags16(void)
{
  static const long cpuflags[5] =
    { WF_CPU086, WF_CPU186, WF_CPU286, WF_CPU386, WF_CPU486 };
  SYSTEM_INFO si;
  OSVERSIONINFOA ovi;
  DWORD result;

  GetSystemInfo(&si);

  /* There doesn't seem to be any Pentium flag.  */
  result = cpuflags[MIN (si.wProcessorLevel, 4)];

  switch(Options.mode)
  {
  case MODE_STANDARD:
      result |= WF_STANDARD | WF_PMODE | WF_80x87;
      break;

  case MODE_ENHANCED:
      result |= WF_ENHANCED | WF_PMODE | WF_80x87 | WF_PAGING;
      break;

  default:
      ERR("Unknown mode set? This shouldn't happen. Check GetWinFlags()!\n");
      break;
  }
  if (si.wProcessorLevel >= 4) result |= WF_HASCPUID;
  ovi.dwOSVersionInfoSize = sizeof(ovi);
  GetVersionExA(&ovi);
  if (ovi.dwPlatformId == VER_PLATFORM_WIN32_NT)
      result |= WF_WIN32WOW; /* undocumented WF_WINNT */
  return result;
}


/***********************************************************************
 *	    GetWinDebugInfo   (KERNEL.355)
 */
BOOL16 WINAPI GetWinDebugInfo16(WINDEBUGINFO *lpwdi, UINT16 flags)
{
    FIXME("(%8lx,%d): stub returning 0\n",
	  (unsigned long)lpwdi, flags);
    /* 0 means not in debugging mode/version */
    /* Can this type of debugging be used in wine ? */
    /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
    return 0;
}


/***********************************************************************
 *	    SetWinDebugInfo   (KERNEL.356)
 */
BOOL16 WINAPI SetWinDebugInfo16(WINDEBUGINFO *lpwdi)
{
    FIXME("(%8lx): stub returning 0\n", (unsigned long)lpwdi);
    /* 0 means not in debugging mode/version */
    /* Can this type of debugging be used in wine ? */
    /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
    return 0;
}


/***********************************************************************
 *           DebugFillBuffer                    (KERNEL.329)
 *
 * TODO:
 * Should fill lpBuffer only if DBO_BUFFERFILL has been set by SetWinDebugInfo()
 */
void WINAPI DebugFillBuffer(LPSTR lpBuffer, WORD wBytes)
{
	memset(lpBuffer, DBGFILL_BUFFER, wBytes);
}

/***********************************************************************
 *           DiagQuery                          (KERNEL.339)
 *
 * returns TRUE if Win called with "/b" (bootlog.txt)
 */
BOOL16 WINAPI DiagQuery16()
{
	/* perhaps implement a Wine "/b" command line flag sometime ? */
	return FALSE;
}

/***********************************************************************
 *           DiagOutput                         (KERNEL.340)
 *
 * writes a debug string into <windir>\bootlog.txt
 */
void WINAPI DiagOutput16(LPCSTR str)
{
        /* FIXME */
	DPRINTF("DIAGOUTPUT:%s\n", debugstr_a(str));
}

/***********************************************************************
 *           OaBuildVersion           [OLEAUT32.170]
 */
UINT WINAPI OaBuildVersion()
{
    WINDOWS_VERSION ver = VERSION_GetVersion();

    FIXME("Please report to a.mohr@mailto.de if you get version error messages !\n");
    switch(VersionData[ver].getVersion32)
    {
        case 0x80000a03: /* Win 3.1 */
		return 0x140fd1; /* from Win32s 1.1e */
        case 0xc0000004: /* Win 95 */
	 case 0xc0000a04: /* Win 98: verified same as Win95 */
		return 0x1e10a9; /* some older version: 0x0a0bd3 */
        case 0x04213303: /* NT 3.51 */
		FIXME("NT 3.51 version value unknown !\n");
		return 0x1e10a9; /* value borrowed from Win95 */
        case 0x05650004: /* NT 4.0 */
		return 0x141016;
	default:
		return 0x0;
    }
}
/***********************************************************************
 *        VERSION_OsIsUnicode	[internal]
 *
 * NOTES
 *   some functions getting sometimes LPSTR sometimes LPWSTR...
 *
 */
BOOL VERSION_OsIsUnicode(void)
{
    switch(VERSION_GetVersion())
    {
    case NT351:
    case NT40:
        return TRUE;
    default:
        return FALSE;
    }
}
