2 * Windows and DOS version functions
4 * Copyright 1997 Alexandre Julliard
5 * Copyright 1997 Marcus Meissner
6 * Copyright 1998 Patrik Stridvall
7 * Copyright 1998 Andreas Mohr
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "wine/port.h"
36 #include "wine/winbase16.h"
38 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(ver
);
45 WIN20
, /* Windows 2.0 */
46 WIN30
, /* Windows 3.0 */
47 WIN31
, /* Windows 3.1 */
48 WIN95
, /* Windows 95 */
49 WIN98
, /* Windows 98 */
50 WINME
, /* Windows Me */
51 NT351
, /* Windows NT 3.51 */
52 NT40
, /* Windows NT 4.0 */
53 NT2K
, /* Windows 2000 */
54 WINXP
, /* Windows XP */
62 OSVERSIONINFOEXA getVersionEx
;
65 /* FIXME: compare values below with original and fix.
66 * An *excellent* win9x version page (ALL versions !)
67 * can be found at members.aol.com/axcel216/ver.htm */
68 static VERSION_DATA VersionData
[NB_WINDOWS_VERSIONS
] =
70 /* WIN20 FIXME: verify values */
72 MAKELONG( 0x0002, 0x0303 ), /* assume DOS 3.3 */
73 MAKELONG( 0x0002, 0x8000 ),
75 sizeof(OSVERSIONINFOA
), 2, 0, 0,
76 VER_PLATFORM_WIN32s
, "Win32s 1.3",
80 /* WIN30 FIXME: verify values */
82 MAKELONG( 0x0003, 0x0500 ), /* assume DOS 5.00 */
83 MAKELONG( 0x0003, 0x8000 ),
85 sizeof(OSVERSIONINFOA
), 3, 0, 0,
86 VER_PLATFORM_WIN32s
, "Win32s 1.3",
92 MAKELONG( 0x0a03, 0x0616 ), /* DOS 6.22 */
93 MAKELONG( 0x0a03, 0x8000 ),
95 sizeof(OSVERSIONINFOA
), 3, 10, 0,
96 VER_PLATFORM_WIN32s
, "Win32s 1.3",
105 /* Win95: 4, 0, 0x40003B6, ""
106 * Win95sp1: 4, 0, 0x40003B6, " A " (according to doc)
107 * Win95osr2: 4, 0, 0x4000457, " B " (according to doc)
108 * Win95osr2.1: 4, 3, 0x40304BC, " B " (according to doc)
109 * Win95osr2.5: 4, 3, 0x40304BE, " C " (according to doc)
110 * Win95a/b can be discerned via regkey SubVersionNumber
112 * http://support.microsoft.com/support/kb/articles/q158/2/38.asp
114 sizeof(OSVERSIONINFOA
), 4, 0, 0x40003B6,
115 VER_PLATFORM_WIN32_WINDOWS
, "",
119 /* WIN98 (second edition) */
124 /* Win98: 4, 10, 0x40A07CE, " " 4.10.1998
125 * Win98SE: 4, 10, 0x40A08AE, " A " 4.10.2222
127 sizeof(OSVERSIONINFOA
), 4, 10, 0x40A08AE,
128 VER_PLATFORM_WIN32_WINDOWS
, " A ",
137 sizeof(OSVERSIONINFOA
), 4, 90, 0x45A0BB8,
138 VER_PLATFORM_WIN32_WINDOWS
, " ",
147 sizeof(OSVERSIONINFOA
), 3, 51, 0x421,
148 VER_PLATFORM_WIN32_NT
, "Service Pack 2",
157 sizeof(OSVERSIONINFOA
), 4, 0, 0x565,
158 VER_PLATFORM_WIN32_NT
, "Service Pack 6",
159 6, 0, 0, VER_NT_WORKSTATION
, 0
167 sizeof(OSVERSIONINFOA
), 5, 0, 0x893,
168 VER_PLATFORM_WIN32_NT
, "Service Pack 2",
169 2, 0, 0, VER_NT_WORKSTATION
, 30 /* FIXME: Great, a reserved field with a value! */
174 0x05005F03, /* Assuming DOS 5 like the other NT */
177 sizeof(OSVERSIONINFOA
), 5, 1, 0xA28,
178 VER_PLATFORM_WIN32_NT
, "",
179 0, 0, 0, VER_NT_WORKSTATION
, 0 /* FIXME: Verify last 5 values */
184 static const char *WinVersionNames
[NB_WINDOWS_VERSIONS
] =
185 { /* no spaces in here ! */
194 "win2000,win2k,nt2k,nt2000",
198 /* if one of the following dlls is importing ntdll the windows
199 version autodetection switches wine to unicode (nt 3.51 or 4.0) */
200 static char * special_dlls
[] =
210 /* the current version has not been autodetected but forced via cmdline */
211 static BOOL versionForced
= FALSE
;
212 static WINDOWS_VERSION forcedWinVersion
= WIN31
; /* init value irrelevant */
214 /**********************************************************************
215 * VERSION_ParseWinVersion
217 static void VERSION_ParseWinVersion( const char *arg
)
220 const char *pCurr
, *p
;
221 for (i
= 0; i
< NB_WINDOWS_VERSIONS
; i
++)
223 pCurr
= WinVersionNames
[i
];
224 /* iterate through all winver aliases separated by comma */
226 p
= strchr(pCurr
, ',');
227 len
= p
? (int)p
- (int)pCurr
: strlen(pCurr
);
228 if ( (!strncmp( pCurr
, arg
, len
)) && (arg
[len
] == '\0') )
230 forcedWinVersion
= (WINDOWS_VERSION
)i
;
231 versionForced
= TRUE
;
237 MESSAGE("Invalid Windows version value '%s' specified in config file.\n", arg
);
238 MESSAGE("Valid versions are:" );
239 for (i
= 0; i
< NB_WINDOWS_VERSIONS
; i
++)
241 /* only list the first, "official" alias in case of aliases */
242 pCurr
= WinVersionNames
[i
];
243 p
= strchr(pCurr
, ',');
244 len
= (p
) ? (int)p
- (int)pCurr
: strlen(pCurr
);
246 MESSAGE(" '%.*s'%c", len
, pCurr
,
247 (i
== NB_WINDOWS_VERSIONS
- 1) ? '\n' : ',' );
253 /**********************************************************************
254 * VERSION_ParseDosVersion
256 static void VERSION_ParseDosVersion( const char *arg
)
259 if (sscanf( arg
, "%d.%d", &hi
, &lo
) == 2)
261 VersionData
[WIN31
].getVersion16
=
262 MAKELONG(LOWORD(VersionData
[WIN31
].getVersion16
),
267 MESSAGE("Wrong format for DOS version in config file. Use \"x.xx\"\n");
273 /**********************************************************************
276 static void VERSION_Init(void)
280 BOOL got_win_ver
= FALSE
, got_dos_ver
= FALSE
;
281 char buffer
[MAX_PATH
+16], *appname
, *p
;
282 static BOOL init_done
;
284 if (init_done
) return;
285 if (!GetModuleFileNameA( 0, buffer
, MAX_PATH
))
287 WARN( "could not get module file name\n" );
292 if ((p
= strrchr( appname
, '/' ))) appname
= p
+ 1;
293 if ((p
= strrchr( appname
, '\\' ))) appname
= p
+ 1;
295 if (!RegOpenKeyA( HKEY_LOCAL_MACHINE
, "Software\\Wine\\Wine\\Config\\AppDefaults", &hkey
))
297 /* open AppDefaults\\appname\\Version key */
298 strcat( appname
, "\\Version" );
299 if (!RegOpenKeyA( hkey
, appname
, &appkey
))
301 count
= sizeof(buffer
);
302 if (!RegQueryValueExA( appkey
, "Windows", NULL
, &type
, buffer
, &count
))
304 VERSION_ParseWinVersion( buffer
);
305 TRACE( "got app win version %s\n", WinVersionNames
[forcedWinVersion
] );
308 count
= sizeof(buffer
);
309 if (!RegQueryValueExA( appkey
, "DOS", NULL
, &type
, buffer
, &count
))
311 VERSION_ParseDosVersion( buffer
);
312 TRACE( "got app dos version %lx\n", VersionData
[WIN31
].getVersion16
);
315 RegCloseKey( appkey
);
320 if (got_win_ver
&& got_dos_ver
) return;
322 if (!RegOpenKeyA( HKEY_LOCAL_MACHINE
, "Software\\Wine\\Wine\\Config\\Version", &hkey
))
326 count
= sizeof(buffer
);
327 if (!RegQueryValueExA( hkey
, "Windows", NULL
, &type
, buffer
, &count
))
329 VERSION_ParseWinVersion( buffer
);
330 TRACE( "got default win version %s\n", WinVersionNames
[forcedWinVersion
] );
335 count
= sizeof(buffer
);
336 if (!RegQueryValueExA( hkey
, "DOS", NULL
, &type
, buffer
, &count
))
338 VERSION_ParseDosVersion( buffer
);
339 TRACE( "got default dos version %lx\n", VersionData
[WIN31
].getVersion16
);
347 /**********************************************************************
348 * VERSION_GetSystemDLLVersion
350 * This function tries to figure out if a given (native) dll comes from
351 * win95/98 or winnt. Since all values in the OptionalHeader are not a
352 * usable hint, we test if a dll imports the ntdll.
353 * This is at least working for all system dlls like comctl32, comdlg32 and
355 * If you have a better idea to figure this out...
357 static DWORD
VERSION_GetSystemDLLVersion( HMODULE hmod
)
360 IMAGE_IMPORT_DESCRIPTOR
*pe_imp
;
362 if ((pe_imp
= RtlImageDirectoryEntryToData( hmod
, TRUE
, IMAGE_DIRECTORY_ENTRY_IMPORT
, &size
)))
364 for ( ; pe_imp
->Name
; pe_imp
++)
366 char * name
= (char *)hmod
+ (unsigned int)pe_imp
->Name
;
369 if (!strncasecmp(name
, "ntdll", 5))
371 switch(RtlImageNtHeader(hmod
)->OptionalHeader
.MajorOperatingSystemVersion
) {
373 MESSAGE("WARNING: very old native DLL (NT 3.x) used, might cause instability.\n");
377 case 6: return WINXP
;
379 FIXME("Unknown DLL OS version, please report !!\n");
387 /**********************************************************************
388 * VERSION_GetLinkedDllVersion
390 * Some version data (not reliable!):
391 * linker/OS/image/subsys
393 * x.xx/1.00/0.00/3.10 Win32s (any version ?)
394 * 2.39/1.00/0.00/3.10 Win32s freecell.exe (any version)
395 * 2.50/1.00/4.00/4.00 Win32s 1.30 winhlp32.exe
396 * 2.60/3.51/3.51/3.51 NT351SP5 system dlls
397 * 2.60/3.51/3.51/4.00 NT351SP5 comctl32 dll
398 * 2.xx/1.00/0.00/4.00 Win95 system files
399 * x.xx/4.00/0.00/4.00 Win95 most applications
400 * 3.10/4.00/0.00/4.00 Win98 notepad
401 * x.xx/5.00/5.00/4.00 Win98 system dlls (e.g. comctl32.dll)
402 * x.xx/4.00/4.00/4.00 NT 4 most apps
403 * 5.12/5.00/5.00/4.00 NT4+IE5 comctl32.dll
404 * 5.12/5.00/5.00/4.00 Win98 calc
405 * x.xx/5.00/5.00/4.00 win95/win98/NT4 IE5 files
407 static DWORD
VERSION_GetLinkedDllVersion(void)
410 DWORD WinVersion
= NB_WINDOWS_VERSIONS
;
411 PIMAGE_OPTIONAL_HEADER ophd
;
412 IMAGE_NT_HEADERS
*nt
;
414 /* First check the native dlls provided. These have to be
415 from one windows version */
416 for ( wm
= MODULE_modref_list
; wm
; wm
=wm
->next
)
418 nt
= RtlImageNtHeader(wm
->module
);
419 ophd
= &nt
->OptionalHeader
;
421 TRACE("%s: %02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n",
423 ophd
->MajorLinkerVersion
, ophd
->MinorLinkerVersion
,
424 ophd
->MajorOperatingSystemVersion
, ophd
->MinorOperatingSystemVersion
,
425 ophd
->MajorImageVersion
, ophd
->MinorImageVersion
,
426 ophd
->MajorSubsystemVersion
, ophd
->MinorSubsystemVersion
);
428 /* test if it is an external (native) dll */
429 if (!(wm
->flags
& WINE_MODREF_INTERNAL
))
432 for (i
= 0; special_dlls
[i
]; i
++)
434 /* test if it is a special dll */
435 if (!strcasecmp(wm
->modname
, special_dlls
[i
]))
437 DWORD DllVersion
= VERSION_GetSystemDLLVersion(wm
->module
);
438 if (WinVersion
== NB_WINDOWS_VERSIONS
)
439 WinVersion
= DllVersion
;
441 if (WinVersion
!= DllVersion
) {
442 ERR("You mixed system DLLs from different windows versions! Expect a crash! (%s: expected version '%s', but is '%s')\n",
444 VersionData
[WinVersion
].getVersionEx
.szCSDVersion
,
445 VersionData
[DllVersion
].getVersionEx
.szCSDVersion
);
446 return WIN20
; /* this may let the exe exiting */
455 if(WinVersion
!= NB_WINDOWS_VERSIONS
) return WinVersion
;
457 /* we are using no external system dlls, look at the exe */
458 nt
= RtlImageNtHeader(GetModuleHandleA(NULL
));
459 ophd
= &nt
->OptionalHeader
;
461 TRACE("%02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n",
462 ophd
->MajorLinkerVersion
, ophd
->MinorLinkerVersion
,
463 ophd
->MajorOperatingSystemVersion
, ophd
->MinorOperatingSystemVersion
,
464 ophd
->MajorImageVersion
, ophd
->MinorImageVersion
,
465 ophd
->MajorSubsystemVersion
, ophd
->MinorSubsystemVersion
);
467 /* special nt 3.51 */
468 if (3 == ophd
->MajorOperatingSystemVersion
&& 51 == ophd
->MinorOperatingSystemVersion
)
473 /* the MajorSubsystemVersion is the only usable sign */
474 if (ophd
->MajorSubsystemVersion
< 4)
476 if ( ophd
->MajorOperatingSystemVersion
== 1
477 && ophd
->MinorOperatingSystemVersion
== 0)
479 return WIN31
; /* win32s */
482 if (ophd
->Subsystem
== IMAGE_SUBSYSTEM_WINDOWS_CUI
)
483 return NT351
; /* FIXME: NT 3.1, not tested */
491 /**********************************************************************
495 * Don't call this function too early during the Wine init,
496 * as pdb->exe_modref (required by VERSION_GetImageVersion()) might still
497 * be NULL in such cases, which causes the winver to ALWAYS be detected
499 * And as we cache the winver once it has been determined, this is bad.
500 * This can happen much easier than you might think, as this function
501 * is called by EVERY GetVersion*() API !
504 static WINDOWS_VERSION
VERSION_GetVersion(void)
506 static WORD winver
= 0xffff;
508 if (winver
== 0xffff) /* to be determined */
510 WINDOWS_VERSION retver
;
513 if (versionForced
) /* user has overridden any sensible checks */
514 winver
= forcedWinVersion
;
517 retver
= VERSION_GetLinkedDllVersion();
519 /* cache determined value, but do not store in case of WIN31 */
520 if (retver
!= WIN31
) winver
= retver
;
530 /***********************************************************************
531 * GetVersion (KERNEL.3)
533 LONG WINAPI
GetVersion16(void)
535 WINDOWS_VERSION ver
= VERSION_GetVersion();
536 return VersionData
[ver
].getVersion16
;
540 /***********************************************************************
541 * GetVersion (KERNEL32.@)
543 LONG WINAPI
GetVersion(void)
545 WINDOWS_VERSION ver
= VERSION_GetVersion();
546 return VersionData
[ver
].getVersion32
;
550 /***********************************************************************
551 * GetVersionEx (KERNEL.149)
553 BOOL16 WINAPI
GetVersionEx16(OSVERSIONINFO16
*v
)
555 WINDOWS_VERSION ver
= VERSION_GetVersion();
556 if (v
->dwOSVersionInfoSize
< sizeof(OSVERSIONINFO16
))
558 WARN("wrong OSVERSIONINFO size from app\n");
559 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
562 v
->dwMajorVersion
= VersionData
[ver
].getVersionEx
.dwMajorVersion
;
563 v
->dwMinorVersion
= VersionData
[ver
].getVersionEx
.dwMinorVersion
;
564 v
->dwBuildNumber
= VersionData
[ver
].getVersionEx
.dwBuildNumber
;
565 v
->dwPlatformId
= VersionData
[ver
].getVersionEx
.dwPlatformId
;
566 strcpy( v
->szCSDVersion
, VersionData
[ver
].getVersionEx
.szCSDVersion
);
571 /***********************************************************************
572 * GetVersionExA (KERNEL32.@)
574 BOOL WINAPI
GetVersionExA(OSVERSIONINFOA
*v
)
576 WINDOWS_VERSION ver
= VERSION_GetVersion();
577 LPOSVERSIONINFOEXA vex
;
579 if (v
->dwOSVersionInfoSize
!= sizeof(OSVERSIONINFOA
) &&
580 v
->dwOSVersionInfoSize
!= sizeof(OSVERSIONINFOEXA
))
582 WARN("wrong OSVERSIONINFO size from app (got: %ld, expected: %d or %d)\n",
583 v
->dwOSVersionInfoSize
, sizeof(OSVERSIONINFOA
),
584 sizeof(OSVERSIONINFOEXA
));
585 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
588 v
->dwMajorVersion
= VersionData
[ver
].getVersionEx
.dwMajorVersion
;
589 v
->dwMinorVersion
= VersionData
[ver
].getVersionEx
.dwMinorVersion
;
590 v
->dwBuildNumber
= VersionData
[ver
].getVersionEx
.dwBuildNumber
;
591 v
->dwPlatformId
= VersionData
[ver
].getVersionEx
.dwPlatformId
;
592 strcpy( v
->szCSDVersion
, VersionData
[ver
].getVersionEx
.szCSDVersion
);
593 if(v
->dwOSVersionInfoSize
== sizeof(OSVERSIONINFOEXA
)) {
594 vex
= (LPOSVERSIONINFOEXA
) v
;
595 vex
->wServicePackMajor
= VersionData
[ver
].getVersionEx
.wServicePackMajor
;
596 vex
->wServicePackMinor
= VersionData
[ver
].getVersionEx
.wServicePackMinor
;
597 vex
->wSuiteMask
= VersionData
[ver
].getVersionEx
.wSuiteMask
;
598 vex
->wProductType
= VersionData
[ver
].getVersionEx
.wProductType
;
604 /***********************************************************************
605 * GetVersionExW (KERNEL32.@)
607 BOOL WINAPI
GetVersionExW(OSVERSIONINFOW
*v
)
609 WINDOWS_VERSION ver
= VERSION_GetVersion();
610 LPOSVERSIONINFOEXW vex
;
612 if (v
->dwOSVersionInfoSize
!= sizeof(OSVERSIONINFOW
) &&
613 v
->dwOSVersionInfoSize
!= sizeof(OSVERSIONINFOEXW
))
615 WARN("wrong OSVERSIONINFO size from app (got: %ld, expected: %d or %d)\n",
616 v
->dwOSVersionInfoSize
, sizeof(OSVERSIONINFOW
),
617 sizeof(OSVERSIONINFOEXW
));
618 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
621 v
->dwMajorVersion
= VersionData
[ver
].getVersionEx
.dwMajorVersion
;
622 v
->dwMinorVersion
= VersionData
[ver
].getVersionEx
.dwMinorVersion
;
623 v
->dwBuildNumber
= VersionData
[ver
].getVersionEx
.dwBuildNumber
;
624 v
->dwPlatformId
= VersionData
[ver
].getVersionEx
.dwPlatformId
;
625 MultiByteToWideChar( CP_ACP
, 0, VersionData
[ver
].getVersionEx
.szCSDVersion
, -1,
626 v
->szCSDVersion
, sizeof(v
->szCSDVersion
)/sizeof(WCHAR
) );
627 if(v
->dwOSVersionInfoSize
== sizeof(OSVERSIONINFOEXW
)) {
628 vex
= (LPOSVERSIONINFOEXW
) v
;
629 vex
->wServicePackMajor
= VersionData
[ver
].getVersionEx
.wServicePackMajor
;
630 vex
->wServicePackMinor
= VersionData
[ver
].getVersionEx
.wServicePackMinor
;
631 vex
->wSuiteMask
= VersionData
[ver
].getVersionEx
.wSuiteMask
;
632 vex
->wProductType
= VersionData
[ver
].getVersionEx
.wProductType
;
638 /******************************************************************************
639 * VerifyVersionInfoA (KERNEL32.@)
641 BOOL WINAPI
VerifyVersionInfoA( LPOSVERSIONINFOEXA lpVersionInfo
, DWORD dwTypeMask
,
642 DWORDLONG dwlConditionMask
)
644 OSVERSIONINFOEXW verW
;
646 verW
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOEXW
);
647 verW
.dwMajorVersion
= lpVersionInfo
->dwMajorVersion
;
648 verW
.dwMinorVersion
= lpVersionInfo
->dwMinorVersion
;
649 verW
.dwBuildNumber
= lpVersionInfo
->dwBuildNumber
;
650 verW
.dwPlatformId
= lpVersionInfo
->dwPlatformId
;
651 verW
.wServicePackMajor
= lpVersionInfo
->wServicePackMajor
;
652 verW
.wServicePackMinor
= lpVersionInfo
->wServicePackMinor
;
653 verW
.wSuiteMask
= lpVersionInfo
->wSuiteMask
;
654 verW
.wProductType
= lpVersionInfo
->wProductType
;
655 verW
.wReserved
= lpVersionInfo
->wReserved
;
657 return VerifyVersionInfoW(&verW
, dwTypeMask
, dwlConditionMask
);
661 /******************************************************************************
662 * VerifyVersionInfoW (KERNEL32.@)
664 BOOL WINAPI
VerifyVersionInfoW( LPOSVERSIONINFOEXW lpVersionInfo
, DWORD dwTypeMask
,
665 DWORDLONG dwlConditionMask
)
667 OSVERSIONINFOEXW ver
;
670 FIXME("(%p,%lu,%llx): Not all cases correctly implemented yet\n", lpVersionInfo
, dwTypeMask
, dwlConditionMask
);
672 - Check the following special case on Windows (various versions):
673 o lp->wSuiteMask == 0 and ver.wSuiteMask != 0 and VER_AND/VER_OR
674 o lp->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXW)
675 - MSDN talks about some tests being impossible. Check what really happens.
678 ver
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOEXW
);
679 if(!GetVersionExW((LPOSVERSIONINFOW
) &ver
))
684 if(!(dwTypeMask
&& dwlConditionMask
)) {
686 SetLastError(ERROR_BAD_ARGUMENTS
);
689 if(dwTypeMask
& VER_PRODUCT_TYPE
)
690 switch(dwlConditionMask
>> 7*3 & 0x07) {
692 if(ver
.wProductType
!= lpVersionInfo
->wProductType
)
696 if(ver
.wProductType
<= lpVersionInfo
->wProductType
)
699 case VER_GREATER_EQUAL
:
700 if(ver
.wProductType
< lpVersionInfo
->wProductType
)
704 if(ver
.wProductType
>= lpVersionInfo
->wProductType
)
708 if(ver
.wProductType
> lpVersionInfo
->wProductType
)
713 SetLastError(ERROR_BAD_ARGUMENTS
);
716 if(dwTypeMask
& VER_SUITENAME
&& res
)
717 switch(dwlConditionMask
>> 6*3 & 0x07) {
719 if((lpVersionInfo
->wSuiteMask
& ver
.wSuiteMask
) != lpVersionInfo
->wSuiteMask
)
723 if(!(lpVersionInfo
->wSuiteMask
& ver
.wSuiteMask
) && lpVersionInfo
->wSuiteMask
)
728 SetLastError(ERROR_BAD_ARGUMENTS
);
731 if(dwTypeMask
& VER_PLATFORMID
&& res
)
732 switch(dwlConditionMask
>> 3*3 & 0x07) {
734 if(ver
.dwPlatformId
!= lpVersionInfo
->dwPlatformId
)
738 if(ver
.dwPlatformId
<= lpVersionInfo
->dwPlatformId
)
741 case VER_GREATER_EQUAL
:
742 if(ver
.dwPlatformId
< lpVersionInfo
->dwPlatformId
)
746 if(ver
.dwPlatformId
>= lpVersionInfo
->dwPlatformId
)
750 if(ver
.dwPlatformId
> lpVersionInfo
->dwPlatformId
)
755 SetLastError(ERROR_BAD_ARGUMENTS
);
758 if(dwTypeMask
& VER_BUILDNUMBER
&& res
)
759 switch(dwlConditionMask
>> 2*3 & 0x07) {
761 if(ver
.dwBuildNumber
!= lpVersionInfo
->dwBuildNumber
)
765 if(ver
.dwBuildNumber
<= lpVersionInfo
->dwBuildNumber
)
768 case VER_GREATER_EQUAL
:
769 if(ver
.dwBuildNumber
< lpVersionInfo
->dwBuildNumber
)
773 if(ver
.dwBuildNumber
>= lpVersionInfo
->dwBuildNumber
)
777 if(ver
.dwBuildNumber
> lpVersionInfo
->dwBuildNumber
)
782 SetLastError(ERROR_BAD_ARGUMENTS
);
785 if(dwTypeMask
& VER_MAJORVERSION
&& res
)
786 switch(dwlConditionMask
>> 1*3 & 0x07) {
788 if(ver
.dwMajorVersion
!= lpVersionInfo
->dwMajorVersion
)
792 if(ver
.dwMajorVersion
<= lpVersionInfo
->dwMajorVersion
)
795 case VER_GREATER_EQUAL
:
796 if(ver
.dwMajorVersion
< lpVersionInfo
->dwMajorVersion
)
800 if(ver
.dwMajorVersion
>= lpVersionInfo
->dwMajorVersion
)
804 if(ver
.dwMajorVersion
> lpVersionInfo
->dwMajorVersion
)
809 SetLastError(ERROR_BAD_ARGUMENTS
);
812 if(dwTypeMask
& VER_MINORVERSION
&& res
)
813 switch(dwlConditionMask
>> 0*3 & 0x07) {
815 if(ver
.dwMinorVersion
!= lpVersionInfo
->dwMinorVersion
)
819 if(ver
.dwMinorVersion
<= lpVersionInfo
->dwMinorVersion
)
822 case VER_GREATER_EQUAL
:
823 if(ver
.dwMinorVersion
< lpVersionInfo
->dwMinorVersion
)
827 if(ver
.dwMinorVersion
>= lpVersionInfo
->dwMinorVersion
)
831 if(ver
.dwMinorVersion
> lpVersionInfo
->dwMinorVersion
)
836 SetLastError(ERROR_BAD_ARGUMENTS
);
839 if(dwTypeMask
& VER_SERVICEPACKMAJOR
&& res
)
840 switch(dwlConditionMask
>> 5*3 & 0x07) {
842 if(ver
.wServicePackMajor
!= lpVersionInfo
->wServicePackMajor
)
846 if(ver
.wServicePackMajor
<= lpVersionInfo
->wServicePackMajor
)
849 case VER_GREATER_EQUAL
:
850 if(ver
.wServicePackMajor
< lpVersionInfo
->wServicePackMajor
)
854 if(ver
.wServicePackMajor
>= lpVersionInfo
->wServicePackMajor
)
858 if(ver
.wServicePackMajor
> lpVersionInfo
->wServicePackMajor
)
863 SetLastError(ERROR_BAD_ARGUMENTS
);
866 if(dwTypeMask
& VER_SERVICEPACKMINOR
&& res
)
867 switch(dwlConditionMask
>> 4*3 & 0x07) {
869 if(ver
.wServicePackMinor
!= lpVersionInfo
->wServicePackMinor
)
873 if(ver
.wServicePackMinor
<= lpVersionInfo
->wServicePackMinor
)
876 case VER_GREATER_EQUAL
:
877 if(ver
.wServicePackMinor
< lpVersionInfo
->wServicePackMinor
)
881 if(ver
.wServicePackMinor
>= lpVersionInfo
->wServicePackMinor
)
885 if(ver
.wServicePackMinor
> lpVersionInfo
->wServicePackMinor
)
890 SetLastError(ERROR_BAD_ARGUMENTS
);
894 if(!(res
|| error_set
))
895 SetLastError(ERROR_OLD_WIN_VERSION
);
900 /***********************************************************************
901 * GetWinFlags (KERNEL.132)
903 DWORD WINAPI
GetWinFlags16(void)
905 static const long cpuflags
[5] =
906 { WF_CPU086
, WF_CPU186
, WF_CPU286
, WF_CPU386
, WF_CPU486
};
913 /* There doesn't seem to be any Pentium flag. */
914 result
= cpuflags
[min(si
.wProcessorLevel
, 4)] | WF_ENHANCED
| WF_PMODE
| WF_80x87
| WF_PAGING
;
915 if (si
.wProcessorLevel
>= 4) result
|= WF_HASCPUID
;
916 ovi
.dwOSVersionInfoSize
= sizeof(ovi
);
918 if (ovi
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
919 result
|= WF_WIN32WOW
; /* undocumented WF_WINNT */
925 /* Not used at this time. This is here for documentation only */
927 /* WINDEBUGINFO flags values */
928 #define WDI_OPTIONS 0x0001
929 #define WDI_FILTER 0x0002
930 #define WDI_ALLOCBREAK 0x0004
932 /* dwOptions values */
933 #define DBO_CHECKHEAP 0x0001
934 #define DBO_BUFFERFILL 0x0004
935 #define DBO_DISABLEGPTRAPPING 0x0010
936 #define DBO_CHECKFREE 0x0020
938 #define DBO_SILENT 0x8000
940 #define DBO_TRACEBREAK 0x2000
941 #define DBO_WARNINGBREAK 0x1000
942 #define DBO_NOERRORBREAK 0x0800
943 #define DBO_NOFATALBREAK 0x0400
944 #define DBO_INT3BREAK 0x0100
946 /* DebugOutput flags values */
947 #define DBF_TRACE 0x0000
948 #define DBF_WARNING 0x4000
949 #define DBF_ERROR 0x8000
950 #define DBF_FATAL 0xc000
952 /* dwFilter values */
953 #define DBF_KERNEL 0x1000
954 #define DBF_KRN_MEMMAN 0x0001
955 #define DBF_KRN_LOADMODULE 0x0002
956 #define DBF_KRN_SEGMENTLOAD 0x0004
957 #define DBF_USER 0x0800
958 #define DBF_GDI 0x0400
959 #define DBF_MMSYSTEM 0x0040
960 #define DBF_PENWIN 0x0020
961 #define DBF_APPLICATION 0x0008
962 #define DBF_DRIVER 0x0010
964 #endif /* NOLOGERROR */
967 /***********************************************************************
968 * GetWinDebugInfo (KERNEL.355)
970 BOOL16 WINAPI
GetWinDebugInfo16(WINDEBUGINFO16
*lpwdi
, UINT16 flags
)
972 FIXME("(%8lx,%d): stub returning 0\n",
973 (unsigned long)lpwdi
, flags
);
974 /* 0 means not in debugging mode/version */
975 /* Can this type of debugging be used in wine ? */
976 /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
981 /***********************************************************************
982 * SetWinDebugInfo (KERNEL.356)
984 BOOL16 WINAPI
SetWinDebugInfo16(WINDEBUGINFO16
*lpwdi
)
986 FIXME("(%8lx): stub returning 0\n", (unsigned long)lpwdi
);
987 /* 0 means not in debugging mode/version */
988 /* Can this type of debugging be used in wine ? */
989 /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
994 /***********************************************************************
998 * Should fill lpBuffer only if DBO_BUFFERFILL has been set by SetWinDebugInfo()
1000 void WINAPI
DebugFillBuffer(LPSTR lpBuffer
, WORD wBytes
)
1002 memset(lpBuffer
, DBGFILL_BUFFER
, wBytes
);
1005 /***********************************************************************
1006 * DiagQuery (KERNEL.339)
1008 * returns TRUE if Win called with "/b" (bootlog.txt)
1010 BOOL16 WINAPI
DiagQuery16(void)
1012 /* perhaps implement a Wine "/b" command line flag sometime ? */
1016 /***********************************************************************
1017 * DiagOutput (KERNEL.340)
1019 * writes a debug string into <windir>\bootlog.txt
1021 void WINAPI
DiagOutput16(LPCSTR str
)
1024 DPRINTF("DIAGOUTPUT:%s\n", debugstr_a(str
));