Chapter 1. Windows Fundamentals

Summary of Windows Fundamental Requirements

Rationale

Passing these requirements will help ensure that your application runs in a stable, reliable manner on Windows operating systems.

Customer benefits

Customers can be confident that a compliant product will not adversely affect the reliability of the operating system.

Requirements

  1. Perform primary functionality and maintain stability

  2. Provide 32-bit components and document any 16-bit code

  3. Support Long File Names LFNs) and UNC paths

  4. Support printers with long names and UNC paths

  5. Do not read from or write to Win.ini, System.ini, Autoexec.bat or Config.sys

  6. Ensure non-hidden files outside of your application directory have associated file types, and all file types have associated icons, descriptions and actions.

  7. Perform Windows version-checking correctly

  8. Kernel mode drivers must pass verification testing

  9. Hardware drivers must pass WHQL testing

  10. Client components must comply with the Desktop Application Specification for Windows 2000

References

Using Driver Verifier tool:
https://www.microsoft.com/whdc/hwdev/driver/default.mspx

General Functionality and Stability Test Procedure for the Certified for Microsoft® Windows® Logo:
https://msdn.microsoft.com/certification/download.asp

VeriTest-Rational Install Analyzer for Windows 2000
https://www.veritest.com/mslogos/windows2000/

Link Utility-Microsoft Platform SDK

How to Comply with Windows Fundamental Requirements

1. Perform Primary Functionality, and Maintain Stability

Your application must perform its primary functionality without compromising the stability of the operating system or your application.

Primary functions are: functions so important that, in the estimation of a normal user, their inoperability or impairment would render the product unfit for its purpose. For example:

  • Users should be able to enter new records, edit existing records, and delete existing records in a database application. They should be able to save the documents, open them later, and print the documents on supported printers.

  • Users should be able to view all supported resources within the expected scope of a resource management application. They should be able to create, save, open, and print supported reports.

  • Users should be able to view expected data in an online analytical processing (OLAP) application and perform supported analyses.

  • Users should be able back up supported files, folders, or drives on the local or supported remote machines from a server-based backup application.

While users perform the primary functions of your application, it must not hang, crash, or lose users' data. Primary functions should not become inoperable or obstructed, and the application must not disrupt Windows or other applications running on the computer.

Users must be able to use system features supported by Windows 2000 with your application. For example:

  • Your application should not crash, hang, or lose data when supported users connect to or disconnect from the server hosting your application.

  • A local user should be able to copy to and paste from the Windows clipboard in other applications while your application is running.

For more information on primary functions and stability, see the General Functionality and Stability Test Procedure for the Certified for Microsoft Windows Logo, located at https://msdn.microsoft.com/certification/download.asp.

2. Provide 32-Bit Components, and Document 16-Bit Code

An application must be a 32-bit executable file of the Portable Executable (PE) format. This means that all executable files, including dynamic-link libraries (DLLs) and executable (EXE) program files, must be 32-bit files. You can test for the correct executable format by using the Link utility on the Microsoft Platform Software Developer's Kit (SDK) or the VeriTest-Rational Install Analyzer tool available for free download from https://www.veritest.com/mslogos/windows2000/.

If your application is not represented in PE format, for example, interpreted code, then the "run-time engine" must be a Win32-based executable file in PE format. For example, if you develop an application in Microsoft Access, your application is an .mdb file, not an .exe file. However, msaccess.exe is a Win32-based executable file in the PE format.

Important When you submit your product for compliance testing, you must list the file name and fully explain the use of any 16-bit file your application could install. This must be done in the electronic Vendor Questionnaire you submit with your application.

Note Each 16-bit file must be tested as part of the Certification process to ensure that system stability is not compromised. This may require additional testing time and consequent additional charges by the testing agency. The time and charges will be determined on a case-by-case basis by the testing agency.

Whenever possible, you should avoid using 16-bit code, even for backward compatibility, because 64-bit versions of Windows will not support 16-bit code.

3. Support Long File Names and UNC Paths

If your application exposes file names to users and/or allows users to enter file names, then your application must support all valid Win32 file names, including Long File Names (LFNs) and Universal Naming Convention (UNC) names. LFNs and UNC names may be longer than the names allowed by 16-bit Windows and legacy DOS applications, and they may contain characters that were not allowed in 16-bit Windows or DOS.

For example, your application must properly recognize and display the following paths:

C:\documents and settings\joe user\my documents\my letter.txt

C:\documents and settings\Joe [joeuser]\my documents\Ca$h;flow\my letter to André.txt

D:\Our folder\project 10\project 11\project 12\project 13\project 14\project 15\ project 16\project 17\project 18\project 19\project 20\project 21\ project 22\project 23\project 24\project 25\project 26\project 27\ project 28\project 29\project 30\filename.ext

\\server\sharename\joe user\my letter.txt

All Win32 functions that create, open, locate, and save files and folders use the constant MAX_PATH as the maximum buffer size for path information. Your application must allow users to create files with a total path length up to MAX_PATH, and your application must open any supported files the user creates, with your application and any other application, on paths up to MAX_PATH long. The MAX_PATH constant is defined in the platform SDK support file windef.h. In the current platform SDK, the value of MAX_PATH is "260." You should use the MAX_PATH constant name instead of coding the value in your application. Using the name instead of the value will help you quickly adapt your application to future versions of Windows, which may support longer paths, but use the same constant name.

4. Support Printers with Long Names and UNC Paths

Windows allows long file names for Printers. If your application supports printing, it must accept names up to 220 characters long for printers, and print to devices with names such as these:

\\PrintServer44.domain.com\Duplex printer: number 0047 (accounting group)

Color laser-Research and Design Dept IP 123.456.78.9 see Fred or Wilma

Note Commas and exclamation points are illegal printer name characters.

5. Do Not Read from or Write to Win.ini, System.ini, Autoexec.bat, or Config.sys

Your application must not read from or write to Win.ini, System.ini, Autoexec.bat, or Config.sys. These file are not used by Windows 2000 systems, and some users remove them.

6. Ensure Non-Hidden Files Outside Your Application Directory Have Associated File Types, and All File Types Have Associated Icons, Descriptions, and Actions

Every non-hidden file that your application creates outside its directory in "Program Files" (see Requirement 3) must have an associated registered file type. This includes:

  • Files created during installation

  • Implementation and data files

  • User created files that are native to your application

If the file type is already registered, no action is required, though you may take over the file type if you wish.

If the file type is not already registered, you must do the following for each new file type:

  • Provide an icon so that none of the files your application creates is identified by the default Windows icon.

  • Provide a friendly type description, for example, "Outlook Offline Mail File."

  • Ensure that each file type has an associated action when double-clicked (e.g., launch your application and load the file), or is designated as "NoOpen."

The NoOpen designation is for files that you don't want users to open. When the user double-clicks a file marked as NoOpen, the operating system will automatically provide a message informing the user that the file should not be opened. Note that if an action is later associated with a NoOpen file type, the NoOpen designation will be ignored.

Exception   If your application allows the user to save or export file types that are not native to your application, the user may choose to save a file as a type that has no association on the user's computer. Your application may save the file as requested by the user, even though the file will have a default Windows icon.

Implementation details

To check if a file extension is already registered:

  • Under HKCR, look for the key that is named with the three (or more) character file extension, such as ".txt." If the key with that file extension doesn't exist, you must register it (see below).

To register new file types:

  • Create a file type under HKCR. The file type is the unique identifier for all files with a given file extension. For example, "txtfile" is the file type for files with the .txt extension. Note that multiple extensions can point to the same file type. For example, ".txt" and ".log" both point to the same file type, "txtfile." The default value for the file type key is the "friendly name" that is displayed in explorer. For example, extensions that point to the "txtfile" key have the friendly name, "Text Document."

  • Under HKCR, create a three-character or longer extension for your file type. We recommend four or five characters, because this will help avoid file type collisions and will make the file type easier to identify. Then set the default value for the file extension to point to the file type you've just created. For example, the default value for ".txt" is the file type "txtfile."

To register an icon for a file type:

  • Under the file type key, create the 'DefaultIcon' key as a REG_SZ or REG_EXPAND_SZ, and point it to an icon you provide. For example, for "txtfile" the value is "%SystemRoot%\system32\shell32.dll,-152," meaning "use the 152nd icon in shell32.dll."

To identify a file as "No Open":

  • Under the file type key, add the "NoOpen" Reg_SZ value. Custom text can be added to the value if you would like to customize the message. See the "ocxfile" key in HKCR for an example.

Example Registry structure to associate ".txt" file extension with "Txtfile" file type:

```    
	HKEY_CLASSES_ROOT\.txt
		  (default) = "txtfile"

	HKEY_CLASSES_ROOT\txtfile
			 \DefaultIcon
				(default) = %SystemRoot%\system32\shell32.dll,-152
			 \shell\open\command
				(default) = %SystemRoot%\system32\NOTEPAD.EXE %1
```

7. Perform Windows Version-Checking Correctly

Your application must verify that the operating system meets the minimum version requirements for your application. The application must also install and run on all later versions of that operating system.

For example, if the application requires Windows 2000 with Service Pack 1 (SP1), your version-checking should allow installation on Major Version 5, Minor Version 0, SP1, and it must also install on all operating system version numbers that are greater than this number (such as Windows 2000 Service Pack 2 (SP2) and so on).

Exception In certain cases, it is acceptable to block install on later versions of Windows. If you choose to do this, you must:

  1. Document this in the Vendor Questionnaire, and explain the rationale.

  2. Display a message to the user when blocking installation or execution that your application is not designed for the later Windows version.

    Examples where this is appropriate would be for low-level disk utilities. In this case, running such an application on a Windows version for which the product was not tested could potentially result in lost user data. For example, the application might not be aware that there could be changes in the file system.

For applications that will run only on Windows 2000 and later versions, we recommend that you use the VerifyVersionInfo API to determine the version of the operating system. Note, however, that this API is not available on down-level platforms. For applications that also run on Windows NT® 4.0, you should use the GetVersionEx() API to determine the OS version. See the code samples below for examples of each implementation.

Code sample using VerifyVersionInfo (for Windows 2000 and later)

Using VerifyVersionInfo helps applications more reliably determine if the application can be installed on a particular OS. In the past, the application would request the version info from the OS and then write code to decide it the current version met its needs. In contrast, with VerifyVersionInfo, the application tells the OS what version it needs, and then asks the OS if the current version meets this. Fewer lines of code are needed.

  #ifdef Windows2000
//
//This sample is for Windows2000 and later versions
//
BOOL bIsWindowsVersionOK(DWORD dwMajor, DWORD dwMinor, DWORD wSPMajor )
    {

    OSVERSIONINFOEX osvi;
    DWORDLONG dwlConditionMask;
   ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));

   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
   osvi.dwMajorVersion = dwMajor;
   osvi.dwMinorVersion = dwMinor;
   osvi.wServicePackMajor = wSPMajor;

   // Set up the condition mask.

   VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL );
   VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL );
   VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL );

   // Perform the test.
   return VerifyVersionInfo(&osvi, 
                             VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR,
                          dwlConditionMask);
     }
#endif

Code sample to verify the Windows version on down-level platforms

This code runs on all 32-bit Windows platforms. Note that, if you need to verify the version of an NT4 Service Pack prior to Service Pack 4, you should also query the following registry key to determine the SP level, as in this sample.

  HKLM\system\CurrentControlSet\control\windows\CSDVersion

The values of CSDVersion will be 0x100 for Service Pack 1, 0x200 for Service Pack 2, and so forth. See below for code sample to determine the Service Pack level.

  BOOL bIsWindowsVersionOK(DWORD dwMajor, DWORD dwMinor, DWORD dwSPMajor )
{
OSVERSIONINFO osvi;
 
// Initialize the OSVERSIONINFO structure.
//
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx((OSVERSIONINFO*)&osvi);
 
// First the major version
if ( osvi.dwMajorVersion > dwMajor )
   return TRUE;
else if ( osvi.dwMajorVersion == dwMajor )
   {
   // Then the minor
   if (osvi.dwMinorVersion > dwMinor )
      return TRUE;
   else if (osvi.dwMinorVersion == dwMinor )
      {
      // OK, better check the Service Pack
      if ( dwSPMajor && 
        osvi.dwPlatformId == VER_PLATFORM_WIN32_NT )
         {
         HKEY   hKey;
         DWORD dwCSDVersion;
          DWORD dwSize;
         BOOL   fMeetsSPRequirement = FALSE;
 
         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
            System\\CurrentControlSet\\Control\\Windows",
0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
            {
            dwSize = sizeof(dwCSDVersion);
            if (RegQueryValueEx(hKey, "CSDVersion",
               NULL, NULL,
(unsigned char*)&dwCSDVersion, 
&dwSize) == ERROR_SUCCESS)
               {
               fMeetsSPRequirement = 
(LOWORD(dwCSDVersion) >= dwSPMajor);
               }
           RegCloseKey(hKey);
           }
         return fMeetsSPRequirement;
         }
      return TRUE;
      }
   }
return FALSE;
}

8. Kernel Mode Drivers Must Pass Verification Testing

Poorly written kernel mode drivers have the potential to crash the system. Therefore, it is critical that any application that includes kernel mode drivers, such as anti-virus products, be thoroughly tested to minimize this risk.

If your application includes any kernel mode drivers, each of these drivers must pass validation triggered by the Windows 2000 Driver Verifier Manager tool (Verifier.exe). Driver Verifier is located in the \system32 folder on Windows 2000 systems. See https://www.microsoft.com/whdc/hwdev/driver/default.mspx for more information on using the Driver Verifier Manager and diagnosing driver problems.

9. Hardware Drivers Must Pass WHQL Testing

If your product includes drivers for hardware devices, these drivers must be tested by Windows Hardware Quality Labs (WHQL). Note that turnaround times at WHQL can be up to 30 days. For more information, see www.microsoft.com/hwdev/winlogo/default.htm.

10. Client Components Must Comply with the Desktop Application Specification for Windows 2000

Client components that run on Windows 2000 Professional and that ship with your application must comply with the desktop application specification for Windows 2000 (see https://msdn.microsoft.com/library/specs/w2kcli.htm) in order for the whole application to be Certified for Windows. Distributed applications that have client components are eligible to carry both Windows 2000 Server and Windows 2000 Professional designations on their Certified for Windows logo.

The following clients may be exempted from complying with the Desktop Application Specification:

  • Administration tools for your server application are temporarily exempt through March 31, 2001. After that date, they will be required to comply with the Desktop Application Specification.

  • "Agents" that have no UI.

In addition, special considerations apply for browser-hosted client applications. Please see Appendix B for details.

Note Testing for client components will be performed on Windows 2000 Professional, but not on down-level operating systems.

How to Pretest Applications for Windows Fundamental Requirements

How To Pretest That Your Application Is 32-Bit

Use the VeriTest-Rational Install Analyzer for Windows 2000, available from https://www.veritest.com/mslogos/windows2000/-or use the Link utility in the Microsoft Platform SDK.

If you use the Link utility, at the command line, type: "link -dump -headers exename.exe | more." If your application is in the proper PE format, the output of this command will be:

  Microsoft (R) COFF Binary File Dumper Version 5.12.8181
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Dump of file exename.exe

PE signature found

File Type: EXECUTABLE IMAGE
.
.
.

You should not get the following output, which would be produced if the application were 16-bit:

  Microsoft (R) COFF Binary File Dumper Version 5.12.8181
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Dump of file exename.exe
LINK : warning LNK4095: " exename.exe" is an NE format executable; use EXEHDR to dump it
.
.
.

To Pretest for Entries in Win.ini, System.ini, Autoexec.bat, and Config.sys Files

  1. Create and save copies of these files before installing the application on a computer where Windows has been freshly installed.

  2. Install the application.

  3. Launch the application, exercise basic functionality, then close the application.

  4. Compare the installed version of the files to the saved version of the files, verifying that no changes have been made. The Install Analyzer will verify this for you.

To Test Whether Your Product Properly Handles Long File Names

LFNs must do the following:

  • Allow plus signs, periods, commas, semicolons, equal signs, and square brackets anywhere.

  • Not save leading or trailing spaces. You can test for this by typing "###test###" or similar text in the Save As dialog box. (In this section, the number sign (#) indicates a spacebar space. ANSI 0032) The program should strip the spaces and add an extension, returning the file name "test.ext."

Note The ANSI 0160 character, used as a non-breaking space character in many fonts, should always be retained, even if used as the leading or trailing character in folder and file names.

  • Support MAX_PATH characters (including the path and extension).

  • Test the following list of file names (not including the quotes), which should save to the hard disk as indicated:

    If you type… It should be saved as
    "test" "test.ext"
    "  test" "test.ext"
    "test  " "test.ext"
    "test#;#+#,#=#[#]" "test#;#+#,#=#[#].ext"
    "     test     " (non-breaking space characters ANSI 0160) "     test     .ext"
    "…..test….." "…..test……ext"
    "\\server\share one\folder three\file" "\\server\share one\folder three\file.ext"

Note if you are typing a UNC name that contains spaces from a command line, you will need to enclose the name in quotes.

To Run Verification Tests on Kernel Mode Drivers

  1. Connect a kernel mode debugger to your test machine. Several suitable debuggers are available, including character mode and GUI debuggers, on the Windows 2000 SDK and DDK CDs, and on the Windows 2000 Symbols and Support CD.

  2. Install your application with its kernel mode drivers.

  3. Start Verifier.exe and select the Settings tab. Look for each driver's name in the Driver list. Select each of your application's drivers on the list, and click Verify. If you do not find one or more of the drivers' names in the Driver list, enter the names in the "Verify these additional drivers after next reboot" edit box. Separate multiple driver names in the edit box with spaces, and use only the name of the driver and its extension. Do not include path information.

  4. Check only these options in "Verification type":

    • Special pool

    • Force IRQL checking

    • Pool tracking

    • I/O verification

  5. Click Apply, Exit, and reboot.

  6. After reboot, start your application, and run a series of typical user tests. If the kernel detects any errors in your driver during boot or during the user tests, it will halt Windows 2000 and display the appropriate information on the character mode screen (blue screen) and on the kernel debugger. If pool corruption is indicated in the debugger, uncheck "Pool tracking" in "Verification type" and restart. When you've eliminated the errors, re-enable "Pool tracking" and retest.

  7. If you find no errors, restart Verifier.exe. Select each driver name again and click Verify, or enter the drivers' names (filename.extension, without path) again in the "Verify these additional drivers after next reboot" edit box, separated by spaces.

  8. Uncheck all options in "Verification type," then check "Low resources simulation."

  9. Click Apply, then exit and reboot. Start your application, and run a series of typical user tests.

  10. The low resources simulation option causes the Kernel to return invalid data and error codes to your driver periodically. As you run user tests, your driver should handle the invalid codes gracefully, perhaps by declining user requests or posting error dialogs. If your driver tries to use the invalid data or ignores error codes, your application will become unstable and fail. The exact symptoms vary with the application and purpose of the driver. The goal here is to ensure that your driver does not crash or hang the system. It is acceptable for applications using your driver to experience intermittent failures, but the system must NOT crash.