(Reproduced) Microsoft Windows 2000 application compatibility

zhaozj2021-02-16  198

Microsoft Windows 2000 Application Compatibility

Kyle MarshMicrosoft Corporation

November 1999

Summary: Discussion Make the application in Microsoft (R) Windows (R) 2000 is not compatibility. Some of the following parts:

Introduction settings and installation issues Windows 2000 compatibility problem application stability problem Differences between Windows platforms

Introduction

For a few months, I have been working on a task, i.e. I find out the application compatibility issues in the Windows 2000 operating system. What I really want to discuss here is that the application is incompatible with Windows 2000. No one truly cares about the reason why the application is compatible.

I have been working with the Windows 2000 test group, and they have tested hundreds of applications in the past few months. We have discussed the application for normal or abnormal operations on Windows 2000. The issues we found can be classified as four categories:

Applications that cannot be installed on Windows 2000. This is the biggest problem we have found so far. Applications are not particularly installed on Windows 2000; the problem is that these applications do not allow themselves to install them into this new version of the operating system. We do what the operating system is made and affect the application running. Whenever the Microsoft Windows NT (R) development group faces the choice, it is to make the system more stable or more powerful, or to ensure the compatibility of the application, they always sacrificed the latter and taking stability. A main goal of Windows 2000 development work is to make the system more stable as a platform. Unfortunately, some changes that must be performed in order to achieve this, the application has caused the application to be incompatible on Windows 2000. Changes we have made to the operating system do not affect the compatibility of the application, but it will interrupt some applications. Applications that depend on the Windows 9x platform. When we develop Windows 2000, we take into account many Windows 9x users to upgrade, so the Windows 9x applications are tested, and they are ported to Windows 2000. We find that some applications are too dependent on Windows 9x.

Setting and installation problem

The first type of problem we want to discuss is setting and installation issues; the most common problem is undoubtedly unable to install the application on Windows 2000. In fact, a most common reason that cannot be installed in the application is that Windows 2000 is a version 5.0 version of Windows NT.

Test group tests the application in a variety of ways. They install the application in Windows 2000-based systems, or install the application in Windows NT 4.0 or Windows 95, and then upgrade the system to Windows 2000 for testing.

After we take a machine that does not have any operating system, we install Windows 2000, then install the application, compared with the above upgrades, the former has much less compatibility.

Version check

The first reason that the application cannot be installed on Windows 2000 is that they cannot handle the version number correctly. We have found that many applications do the operations made by the following sample code. They call GetversionEx during operation, then write a "if" statement, the statement specifies: "If the system is version 3, because there is no new shell, I can't run normally, so I may not be installed. If the system is version 4, I can install and set up. " The problem is that if the system is version 5, this "if" statement is not below. Because the version number is 5.0, these applications cannot be installed due to their own reasons, so we found a series of such problems.

IF (OSVI.DWMAJORVERSION == 3) {

/ / Please do this

}

Else IF (Osvi.dwmajorversion == 4)

{

// Please do that

}

The test group continues to look for the solution and blinds many of these applications. In early compilation, we can take steps to change the return value of GetVersionex. We can change its return value, deceive the app, tell it that version number is 4.0, and then the program will continue to install and run normally. But some application ideas are not installed on Windows 2000. For viral scanners or other low-level utilities, it is understood to be understood by an operating system. However, these applications displays the message to illustrate this. What we look for is those that cannot be installed or unable to run, and there is no application that does not know the user.

How can I correctly check the version number? In Windows 2000 we will add a new API: VerifyVersionInfo, this API will check the primary version number, secondary version, and service pack in turn. If there is a new version of the operating system, the application can still install and run on it. There are still many options and ways to apply VerifyVersionInfo, but if you just check "If the operating system is upgraded, how do you handle this, you only need to call these three signs, then check the primary version number, Version number and service pack. You can define the following statement: "My program needs to run on Windows NT 4.0, SP2", then ask VerifyVersionInfo "whether I am running this standard?", The API will return true value or false value.

VerifyVersionInfo (& OSVI,

VER_MAJORVERSION |

VER_MINORVERSION |

Ver_ServicePackmajor,

Dwlconditionmask;

In this way, check the version, you can comply with Windows 2000 applications, and its basic idea is "as long as there is a new version of the operating system, you must install it on the new version."

One problem with VerifyVersionInfo is that the API can only be run on the Windows 2000 platform. In order to check the version of the old platforms such as Windows 95, you must apply GetversionEx. You can find that its function is basically the same as VerifyVersionInfo: check the primary version number, secondary version number, and service pack in turn.

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 main version

IF (Osvi.dwmajorversion> dwmajor)

Return True;

Else if (Osvi.dwmajorversion == dwmajor)

{

// Then, the second version

IF (Osvi.dwminorVersion> dwminor)

Return True;

Else if (Osvi.dwminorVersion == dwminor)

{

// Yes, it is best to check the service packif (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;

}

//

// This example applies to Windows 2000 and updated versions

//

Bool BiswindowsVersionok (DWORD DWMAJOR, DWORD DWMINOR, DWORD DWSPMAJOR)

{

OsversionInfoEx Osvi;

ZeromeMory (& OSVI, SIZEOF (OsversionInfoEx);

Osvi.dwosversionInFoSize = SizeOf (OsversionInfoEx);

Osvi.dwmajorversion = dwmajor;

Osvi.dwminorversion = dwminor;

Osvi.WServicePackmajor = dwspmajor;

// Set 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);

// Execute the test.

Return VerifyVersionInfo (& OSVI,

VER_MAJORVERSION | VER_MINORVERSION

| Ver_ServicePackmajor, dwlconditionmask;

}

First, you need to check the primary version number. If the primary version number of the current operating system is higher than the required primary version number, no check is required, run down directly. If the primary version number is equal, check the second version in the same way. Finally check the service package number. When we get a version of the release, you can say "It doesn't matter, we don't care whether service pack 3, 4 or 5". If the primary version number or the secondary version number has increased, the system can also be handled. We find all applications to check the version information, find that they will check each component separately. They will say "Hey, the main version number is 5, I only ask 4, good. The second number is .0, very good, but service pack is 0, I need 3". Obviously, Windows 2000 has not launched SP3, so this method of checking version information is wrong. Check the following details when checking the version number of Windows NT: Checking the version number and service pack information. The first is to get the return value of getVersionex and check the "Szcsdversion" string. The actual service pack number is embedded in a certain location of the string. Analysis This string character is really cumbersome, and you must always keep in mind whether it has been localized, it is difficult to do. This is not the best way. If the system is running Windows NT 4.0, you only need to check the following registration key value, where there is a number of service package numbers. Extract this number and make a "equal" or "greater than" comparison:

HCLM / System / CurrentControlSet / Control / Windows / CSDVersion

If you are running Windows 2000 or higher, you can still use GetversionEx, but you need to pass it to the OsversionInfoEx structure, not the OsVersionInfo structure being used. Considering the size of the operator member, Windows 2000 will treat it as a larger structure and give a new field (service package, main version, subset) as an integer used in comparison. If you still use VerifyVersionInfo, you will find this is the most convenient way.

DLL version check

While checking the Windows version, we also discovered another question related to the version, that is, the user does not check the version of the DLL. Whether the DLL is Microsoft DLL in the system directory, or your own DLL, you must have a version check before copying it to the system. The purpose of the inspection is to prevent the old version of the DLL from being copied to the new version.

Version information must be confirmed in the user's own DLL to check. It is important to do this, it can avoid a variety of trouble. Do not try to change the DLL in the system directory, do not consider upgrading the system DLL, or override the same DLL. The system DLL is a DLL submitted by Windows 2000 in a CD or a service package, located in the system directory.

If you intend to prepare new Windows 2000 applications, you need to use Windows Installer, which can check the version of the DLL. As long as you explain that you need to place a particular DLL in a specific directory, you can find that Windows Installer is checked for you. You don't need to process this small piece of code.

DLL Hell

If the DLL version is not checked correctly, the result is no doubt happening. I definitely not explain what DLL Hell is to explain to you, you must spend a lot of time on this. Because I originally participated in the development of CTL3D.dll, the same thing as familiar with my neighbors.

We spent a few years, trying to break through obstacles that affect the normal work of DLL, and we finally determine that application developers cannot keep backward compatibility. Everyone is working hard in this regard, this goal is great, but it can't be realized. In fact, the DLL cannot keep backward compatibility. The result is: If an application is to end properly, it must depend on a specific version of a DLL, and another application depends on another version of the DLL, because these two applications are in this share of components. (Ie, shared DLL) has a conflict, resulting in the same system that cannot be coemented in the same system. So far, we still think that for Windows applications, DLL sharing features is a very good and important part. We also think that DLL can provide you with the features of you or very valuable. The problem is if you do not test the version of the DLL, and the cross-care program will bring a lot of problems with the DLL global sharing.

Parallel DLL

In Windows 2000, we have begun to implement some content called parallel DLLs. We hope that your application has also begun to close to parallel versions. In Windows 2000, we have taken some preventive measures to reduce DLL Hell. The first thing we have to consider is to ensure that the system is in protected state, and maintain its integrity. Then we will discuss Windows file protection.

Another thing we have to do is in parallel to implement components, and I hope that the application vendor will do this. We are targeting Microsoft components; as for your own components, we also recommend that you do this. We will use a parallel version of the component, and we also hope that you can use a parallel version of the component for your own partial shared components.

System stability

Another job that Windows NT Group is working hard is to ensure that the system remains long and stable. Microsoft allows all functions to Windows NT in the form of division service packages, which is a problem. Customers who have installed Windows NT and companies are very vigilant when selecting a service package, because these things are not just some problems. Usually it will make some corrections, then say "Hey, we add this feature here, add that function there", these things make the system unable to reach the expected stability.

According to routine strategies, the service pack can only contain corrections to errors, and there is no other content. If we think that the operating system needs to add some important features and features, we will launch the .x version of Windows 2000. You will get such content similar to Windows NT 5.1, 5.2, and there are also three different versions of service packages for Windows NT. We will continue to work hard to maintain the integrity of each platform function, which even relate to QFE, error checking, and hot fix. The new version of the operating system will be issued each time with new features or new features.

The last job we conducted in Microsoft is to ensure that what components have been released with the same product, we strongly recommend that you will follow. We are doing the most likely to reduce the number of components released in different products. If a particular component needs to work with another specific component, we will try to publish these two components together. For all these components that can be re-distributed, we will set out the released structure sequence.

Parallel DLL

If you need to change the components by global sharing components or DLLs to new parallel DLLs, you need to change some changes to the DLL. This change to DLL itself is necessary. You must declare: "The components I have designed will allow multiple versions to run at the same time."

In order to make a component become a real parallel component, first need to rename the DLL, and the changes may exist in the OCX control, all GUIDs in the COM object. This renamed job can guarantee a new DLL running in parallel, which will no longer be global sharing.

After the DLL is renamed, the application installs it into the autonomous directory without being installed. In this way, the application developers can say: "I have fully tested a specific version of this DLL, and I also confirm that this DLL will not upgrade before I will test again." Just give your developer enough confidence: Anyone cannot use shared components to disturb your app, causing the system to crash and bring us back to DLL Hell.

If you are using these components as a user, you can register a relative path in your own directory (instead of the system directory). This will load a local version falling somewhere in the system, not a global copy.

We modify the loadLibrary function to ensure that if the application registers a component with a relative path, we always complete the load in a relative path, regardless of this component is in the system directory, or is running else. This makes it possible to ensure that you get the copy of the application to test the application.

Isolated application

We also modified the LoadLibrary code to support DLL redirection. This administrator can redirect the DLL load process to a certain location and load the DLL by the local directory. After this process, your DLL can be in an isolated state. Suppose someone of a large unit is to test whether they can use your app, they have another application, and then test whether the two work together. They found that the result is not, the administrator starts to find where the two applications are conflicted on which component has occurred. After finding this component, the administrator considers the perspective of employees using these two programs, extracts the DLL (or contains OCX to the object) and places it in the directory where the application is located. Then the administrator created a file called foo.exe, and then added .local. If you call LoadLibrary, LoadLibrary finds that there is a foo.exe.local file here, which will first load the file in the application directory without considering the application for the application for the LoadLibrary call itself. This approach helps people distinguish between multiple applications that require the same component, so that all of these applications are running in the same system.

Windows file protection

In order to ensure the stability of the system and the reliability of the platform, the first step is to ensure that the system will not encounter any DLL HELL problem. We hope that no matter what happens, the system is still able to run, can boot, ie, users can have sufficient confidence in the stability of the system.

With Windows File Protection (WFP), if the application tries to change a system file, Windows 2000 will restore it. For some features, the application will be installed and said: "Hey, I need this DLL new version ..." to implement a function, or at all this is a wrong application that does not correctly execute the version check function. Windows 2000 will check this and find that the file has been changed. If Windows 2000 found this is a system file, and declare "I don't allow this file", it will restore the file.

If you want to upgrade files that have been locked by the system, you can only use several file replacement mechanisms issued by the Windows NT team: service pack, QFE or Hot FIX. They enable alternatives to system files, while other applications cannot be.

For example, mfc42.dll is a file we locked. The DLL will not be upgraded through the language group, and only the Windows NT team can change this file in the system. If the C programmer needs to upgrade their DLL (and assume that they want to upgrade before the next version of Windows NT released after Windows 2000), only the parallel component version feature can only be used. Most * .sys, *. Dll, *. Exe and * .ocx files and several font files are in the protection.

There are still several compatibility issues. First, the anti-virus program must recognize and correctly handle the Windows file protection, and then make the application's backup and recovery; these files cannot be copied, backed up, and recovered. Because you don't have a file replacement mechanism supported by your system, if you do this, you will cancel the Windows file protection.

In order to prevent such operations, we added a few APIs in the system.

WFP API

The first API is SfcgetNextProtectedFile. A list of all protected or protected files can be obtained. You can reply to this API at an null value to get a list of protected files.

Bool WinApi sfcgetnextprotectedFile

(In Handle rpchandle, in pprotected_file_data protfiledata);

//

// This feature will list protected files

//

Void ListProtectedFiles (HWND HWND)

{

HWND HWNDLIST;

Protected_file_data pfd;

Int iCount;

Char szfilename [260];

Ilen;

RECT RT;

HWndList = getWindow (hwnd, gw_child);

IF (hwndlist == null)

{

GetClientRect (hwnd, & rt);

// Create a "list" control for the first time

HWndList = CREATEWINDOW ("ListBox", NULL,

WS_CHILD | WS_VISIBLE | LBS_STANDARD | LBS_NOINTEGRALHEIGHT |

LBS_USETABSTOPS,

0, 20, RT.right, RT.BOTTOM-40,

HWnd,

NULL,

Hinst,

NULL);

}

Else

SendMessage (Hwndlist, LB_RESETCONTENT, 0, 0);

ZeromeMory (& PFD, SIZEOF (protected_file_data);

ICOUNT = 0;

While (g_pfnsfcgetnextprotectedfile (null, & pfd)! = 0)

{

/ / Convert Wchar to ANSI for this "ANSI application"

Ilen = widechartomultibyte (CP_ACP, NULL, PFD.FILENAME, WCSLEN (PFD.FileName),

SZFileName, 260, NULL, NULL

SZFileName [Ilen] = '/ 0';

SendMessage (HWndList, LB_ADDString, 0, (LPARAM) SZFileName);

ICOUNT ;

}

}

Another more direct API is SFCISFileProtacected. The API can be more convenient to call most applications, and answer the following questions: "Take a look at this file, is it protected?" But remember that it needs to point to the full path to this file. You cannot just simply specify NTS.sys, but you need to give the path to the position where nts.sys is located. If you pass this file to the API, it will say: "Yes, this file is protected", or "This is not a protected file." This API needs to be used when you do any backup or recovery operation. You can call this API if you want any installation settings or may update a system file. If you want to place a target file in the system directory, you need to call this API before doing this, to avoid cancel the Windows file protection. The next version of Windows Installer (released with Windows 2000) will check before the replication file is checked, so WFP will not be initiated unexpectedly. Bool WinAPI SfcisfileProtected (In Handle Rpchandle, In LPCWSTR PROTFILENAME);

//

// This function uses the "file" to open the dialog to get the file name from the user and check if it is protected.

Void CheckfileForProtection (HWND HWND)

{

OpenFileName OpenFileName;

Char Szfile [MAX_PATH] = "/ 0";

Char Szsystem32 [MAX_PATH];

STRCPY (SZFILE, "");

ZeromeMory (& OpenFileName);

// Fill the OpenFileName structure to support templates and hooks.

OpenFileName.lstructSize = sizeof (OpenFileName);

OpenFileName.hwndowner = hwnd;

OpenFileName.hinstance = hinst;

OpenFileName.lpstrfile = SZFILE;

OpenFileName.nmaxFile = sizeof (SZFILE);

OpenFileName.lpstitle = "SELECT A FILE";

OpenFileName.Flags = OFN_FILEMUSTEXIST

IF (g_pfnshgetfolderpath! = null)

g_pfnshgetfolderpath (NULL, CSIDL_SYSTEM, NULL, NULL, SZSYSTEM32);

Else

Szsystem32 [0] = '/ 0';

OpenFileName.lpstrinitialDir = szsystem32;

// Call the public dialog function.

IF (& OpenFileName))

{

// Check the file

Wchar wzfilename [260];

Ilen;

Ilen = MultibytetowideChar (CP_ACP, NULL, SZFILE, STRLEN (SZFILE), WZFILENAME, 260);

WZFileName [Ilen] = '/ 0';

IF (g_pfnsfcisfileprotected (null, wzfilename) == true) {

MessageBox (hwnd, "is protected", szfile, mb_ok);

}

Else

MessageBox (HWnd, "IS Not Protected", SZFILE, MB_OK;

}

Component check

We have found that another reason that can't be installed on Windows 2000 is the component check function. Obviously, each version of our operating system consists of multiple different components. These components include TAPI, MAPI, Microsoft DirectX (R), and the like. We found what components are in what components, and whether there is a component to make your own assumption. The application is assumed because of the presence of the A component, because the version 2 of a component is exist and the version 3 of the other component will also exist. If you need to use a component, you must check if this component is present in the system, and whether it is at the correct level.

In addition, developers also assume that there is no DirectX in Windows NT. Sometimes a statement is true, and the application also thinks it may be true during the preparation. Then when checking it, because the Windows 2000 has no DirectX, it will declare: "Oh, I can't run." But Windows 2000 has DirectX, this assumption is incorrect.

Another problem we have encountered is hard-coded issues, and the application will not be able to hardcode the path if the location is false, it is impossible to codize the path at all.

Another example is that Windows 2000 now contains TAPI (latest version TAPI 3.0) and DirectX (the latest version 7), not by default MAPI. In the past, it always believes that if the operating system is Windows NT, which should include MAPI. But the current situation is different. If you use a component, you must check if this component exists, and no assumptions are made according to platform or components.

Install file in wrong location

Another problem found in the installation is that people are placed in the location of the file error. If you upgrade some files placed somewhere, it doesn't matter; you can place them in the location of the user. However, some files need to be placed in the "Program Files" directory in the first installation.

Note that it is not necessarily C: / Program Files. Sometimes it is this directory, sometimes it is not. For example, in my machine is not. I usually leave the C partition to Windows 98, and install the Windows NT partition to other partitions.

We hope that you don't put your files as much as possible in any subdirectory such as the Windows directory, or System32. Although there is no harm of this, we often hope you, so we can't completely ban this practice, but we now hope that all files in the system are more organized. We have discovered that users deeply feel a headache for hundreds of documents in the System32 directory, and they can't delete them. Every time you hear people say this: "Every year, you must clean up the system and start reloading Windows from the beginning. Uninstalling and cleaning procedures have become the most popular application on the software market. We hope that the system remains in an orderly state and makes the operation process more simplified.

Possible, we do even want you to write some shared components elsewhere; Microsoft Visual Basic (R) is a better example in this regard. Many applications use this component. Old Visual Basic is always installed in the system directory, now we placed it in a specified folder of Program Files. If you want to find the location where the file should be placed, you can call a named SHGETFolderPath. SHGETFolderPath is an integral part of Windows 2000. It has also existed in the second edition of Windows 98. If you find that there is no this API in the system, you can distribute S HFolder.dll. The DLL will unlock the housing of this new API for SHGETFolderPath. This API understands the location where each special folder is in the system. You can find the API in the SDK. It is a very long list, which lists each folder you can consider.

Note that the old version of the platform only supports the following four CSLIDs. If you are looking for a specific directory, find that the directory does not exist, the SHGETFolderPath can create this directory for you, and the condition is that you have specified, but in the Windows 95, this process can only be followed. Four CSIDL is valid:

CSIDL_PERSONAL

CSIDL_AppLicationData

CSIDL_MYPICTURES

CSIDL_LOCAL_APPLICATIONDATA

The following code example shows the application of SHGETFolderPath; it is a very easy and easy to use API. One thing to pay attention to: If you want the code to run on all platforms (including the platforms such as SHGETFOLDERPATH with Windows 2000 and Windows 95 without SHGETFolderPath, the application must dynamic links with the implementation process in Shfolder.dll .

// ShgetFolderPath Can Work Everywhere Shfolder Is Installed.

HModule HMODSHFOLDER = loadingLibrary ("shfolder.dll");

IF (HMODSHFOLDER! = NULL)

{

(* (FarProc *) & g_pfnShgetFolderPath =

GetProcaddress (HMODSHFolder, "ShgetFolderPatha));

}

Else

g_pfnshgetfolderpath = null;

}

IF (g_pfnshgetfolderpath! = null)

g_pfnshgetfolderpath (NULL, CSIDL_SYSTEM, NULL, NULL, SZSYSTEM32);

Else

Szsystem32 [0] = '/ 0';

OpenFileName.lpstrinitialDir = szsystem32;

Security problem

Finally, as the last issue of setting and installation, we will discuss several security issues that occur with Windows 2000:

Advanced users should install the entire system-wide application. We have found that some applications can only be installed by administrators. For locked machines, companies still want many different users, or two or three users in one day can be shared; or all employees can use this system for a certain day. They just don't want anyone to be arbitrarily changed by administrator privileges, for what they want. Many customers require advanced users (not only administrators) to complete the installation of the application. Another application can be installed for yourself (rather than anyone in the system). If I want to play a game, I should be able to install the game, and don't let anyone else in the system use this game. But remember that non-advanced users cannot write things to the "Program Files" directory; the user cannot write HKEY_LOCAL_MACHINE. In the installation process, you should open HKEY_LOCAL_MACHINE to see if there is any write permission to it, and then make it a statement: "You cannot write to the site; if you want this app for personal use only?" A security issue is the default server permissions. If you are trying to install server applications or services, use non-privileged service accounts (meaning, you do not use the local system account, and no account established as a member of the local administrator group), the account is basically It is impossible to have the privileges required to actually run the service. In Windows 2000, the permissions owned by non-privileged users (actually non-privileged service accounts) are different from Windows NT 4.0. There is less authority with the former. For example, non-privileged users cannot write anywhere anywhere in the Windows system directory. If you have a running server, the server tries to make some operations, or trying to install certain things, but it may not have appropriate permissions. If you are running a server application, confirm that it has logged into the correct account and has all permissions required to run properly. Windows 2000 compatibility problem

The next question I want to discuss is called Windows 2000 compatibility issues, which refers to some changes to the Windows platform. The purpose is to promote the platform constant progress, and we provide users with more reliable The goal of the platform. These modifications will affect some applications running on Windows 2000.

Set the front desk window

We start with a fairly simple operation: set the front desk window. In fact, this change begins with Windows 98. It cannot be expected to simply use the application to call setForegroundWindow, and then your window can automatically change to the front desk. All of this is to prevent any worker options when anyone wants to jump to the forefront. You are trying to type, suddenly pop up a window, requiring some action. You may have a positive answer to something that doesn't understand anything at all, in the process of typing.

In order to prevent this, the application can be developed for the application for the application. In fact, these rules in Windows 98 already exist:

If your process is already a reception process, you can take the front desk window. If your process is just started by the front process, you can take the front desk. If your process receives the last input, it will become a front desk. If there is no front window at this time, you can take the front desk. If you are debugging the front desk process, everyone can take the front desk. If a reception timeout is locked (there is no action in the front desk lock in a certain period of time, and the response will not be responded), then others can get the front desk. If the current system menu is active, your application will not be able to get the front desk. This is mainly to prevent the appearance of the problem: you are using the "Start" menu, and along its branch menu is about to start an application, suddenly these menus disappear. This new rule in Windows 2000 can prevent this. Super hidden file

Another new feature added in Windows 2000 is called "Super Hidden Files). Here, the system will mark "System" and "Hide" attributes simultaneously. The file is still in the original position, we can also apply these files; just after you enter the Windows Explorer, these files will not be displayed. Even if you select "Show Hide Files", you cannot see them. There is a new check box in the property list of the folder, which will allow the user to see these files, but ordinary users do not select this option, so they cannot see these files.

Moreover, the system will no longer display those files in the Windows environment, most of which are based on the old files and similar files based on MS-DOS (R). In most cases, this has no effect on ordinary users; what they see will be a more concise system.

This is not a compatibility issue for 32-bit applications. Applications can see files in the General "Open File" dialog and open files smoothly, and the command line is still valid. If you use the DIR / ASH command that can view the super hidden file, all files will be seen.

The only compatibility problem is 16-bit applications, which will encounter a bit of trouble. This is mainly caused by invocating the INT21 of MS-DOS. If you require the system to find the hidden file, MS-DOS's int21 will only find hidden service files.

Partially hidden files:

MS-DOS system file, such as IO.DOS Office Quick Find file

NetBIOS

Netbios has always been part of Windows NT. From Windows 2000, this situation has changed. It is not a default configuration, and the user may set the system so that it does not load does not appear NetBIOS. If your application calls the API using NetBIOS in the system without NetBIOS, these applications will not work properly and return errors. For example, if you use a call such as NetServereNum, there is no NetBIOS in the running system, the error message will be returned. You must check all where you use NetBIOS calls to determine if they happen to the machine without NetBIOS and correctly handle it. Alternatively, it can be replaced with a non-NetBIOS call. Make sure your user knows that your system always needs NetBIOS and clearly notifies in the installer or version release instruction.

Need a new network .inf file

If you have any network devices (such as network drivers, transfer drivers, and some network file print providers, you need to confirm that there are new network .inf files needed in the system to support Windows 2000. Plug and play. These new files are used to use the Windows NT 4.0 upgrade from the beginning of the network device or by Windows NT 4.0 to Windows 2000. Because this format is compatible with Windows 98, you can use it before. In any case, you need to provide these files to the user immediately so that after the system is upgraded to Windows 2000, network devices can still be supported. Physical drive letter

If your application needs to access the hard drive and volume (such as a viral scanner) in a low mode, you will need to find physical drive numbers, and you must change the way the number is found. In the past, you may use a symbolic chain that the content returned by the symbol chain is similar to:

/ Device / HardDiskx / Partitiony

On some places you will find "HardDisk" and the following X, and see that it is a hard disk 2 or hard disk 3. And now, the symbol chain returns:

/ Device / HardDiskVolumez

Physical drive numbers will no longer appear anywhere in this symbolic chain. You need to replace with a pair of available IOCTLs. the first is:

IOCTL_STORAGE_GET_DEVICE_NUMBER

This IOCTL is only valid for a single physical drive. For example, if the drive is a C drive, even multiple partitions on one drive, the IOCTL will take effect. But for multi-volume collection, you need to use:

IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS

The IOCTL is also effective for Windows NT 4.0; found that physical drive numbers from the symbolic chain is always a bit dangerous: In the information that may be multi-drive sets, they only tell you the first drive.

Access tape drive

If your application uses a tape drive, you must change the way to access the tape drive. The new "Hierarchical Storage Management" applies a tool called "Removable Storage Manager), which is the main operation process as follows: Enter the server and confirm that a file has been long. Not accessed. It will say: "Let's go to the tape, if someone needs this file, we can find it back and let it get away from the tape." The user will wait a slight time, but you can get the file. This way, you can use a small drive that seems to be much larger.

Because "Removable Storage Manager" is running frequently on the server, your application is also trying to access the tape drive, so the application finds that the tape drive is always busy, the application will not control the tape drive. It is insufficient to discuss how to deal with this problem. It is recommended that you access the "Windows NT 5.0 storage application development process" in Microsoft.com "in Windows NT 5.0). In this article, you can approach how to deal with new tape drives. Before implementing this processing, take a time to browse the "Removable Storage Manager Program for Reference" in the SDK to learn how to write applications that can share tape drives with the removable storage manager. .

Mount display driver

If your application tries to "wedge" display device (for example, you have written a display driver, it will get all calls before you hand over to the original display driver), you need to change the operation mode. You have seen this application for this operation (remote control application is an example), in which the application gets the display driver command and send a call through the line and then performs a call locally. If you want to do this in Windows 2000, you must use the new "Display Driver Management Level, DDML) to mirror the output to the remote device. This will initiate multiple display drivers, which is the operation of the remote control application being in progress. This part of the documentation is included in the DDK of Windows 2000 Beta 3. Writing kernel mode

Microsoft has also taken another measures to enhance the reliability of the platform: Any program running in the kernel mode will actually have a write protected area in memory. If you have used some code segments or string paragraphs in your device driver, you will write some temporary content (such as annotations, etc.) where you are listed as read-only areas, which will be in Windows 2000. Not pass. We do not allow any content in kernel mode to hinder the protection functionality should have, as this will cause the system to crash.

We have found that many device drivers do not follow this rule of Windows 2000. By checking the device driver, the system will determine if the design objective of the device driver is used for Windows NT 4.0 instead of Windows 2000, this rule is not enforced. If so, it will lead to too many device drivers to work properly. For the device drivers written for Windows 2000 or have been upgraded so that the system will force the rule to be enforced on the Directs that work properly on Windows 2000.

Stack consumption increase

In order to illustrate several substantive problems in compatibility, we must understand that the stack space used by Windows 2000 is much larger than Windows NT 4.0. Since we use a unified executable program, the space occupied by Unicode is much more than ever, and we still have more strings or therefore cause the system to be more Multi-stack. We have found that some applications enhance performance by minimizing stack space. If you want to increase the running speed, this is undoubtedly a good idea: it is obvious that the less memory, the faster the speed is running. But unfortunately, they are now too small. As the system and the application are quickly used in stack space, the result is that the application crashes.

To confirm that there is the above problem in your application, you need to check the following settings: If you use the / stack-linker option in the link line, check this option; check in the compiler in the use of StackSize parameters or / f option Stacksize-.def file. You need to retrieve all of these contents to see if they are running on Windows 2000 and confirm that the stack space is not too small.

Win32 API changes

In Windows 2000, the Microsoft Win32 (R) API has many changes; we check several of them, found that there are some compatibility disorders caused in unintentional. The following is some changes that I often encountered during the Windows 2000 test.

We have to support a new input method in Windows 2000. To achieve this, some of the information in WPARAM is required, which is obtained through WM_KEYUP and WM_KEYDOWN messages. We ask you to pass WPARAM to transfer to TranslateMessage. If you don't do this, we will not be able to fully implement the function of this new input method. Another problem is on DS_SHELLFONT within the dialog structure. If you specify DS_SHELLFONT, you cannot change the font. We use Microsoft Shell DLG 2 as a font; you can change the size, but you can't change the shape.

In the OpenFileName Structure of the Open File dialog, the behavior of the initial directory has a small difference. If OpenFile does not find any file you want to find type, it will directly point to the "My Documents" folder by default.

GetWindowsDirectory returns the system directory for each user. If you are on the Terminal Server, you may find that you cannot get a real system directory, which will be a system directory that is set for specific users. There is a new GetWindowsSystemDirectory called, which can always return to the true system directory on the terminal server.

Application Stability Problem

Now, the stability of the application will now be discussed, these issues are derived from the changes that occur in Windows 2000, thereby discovering many errors that cause the application incompatibility in the implementation or detail of the application. However, what changes do will not destroy the application. Sometimes this problem occurs when the application runs rare in a rare manner.

Hard code path

The application generally uses the "hard code" reference method, so when Microsoft changes some parts of the system, the application will not work because of its content it is looking for, and the main culpricies here are hard code paths. . On Windows 2000 or even Windows NT 4.0, many things are moved. For example, on the "My Documents" folder on Windows 9x is just a folder in the C disk or D disk root directory, namely:

/ My documents

Windows NT moves it, and puts its respective folders in the Windows system directory below for each user. So in the following examples, even if the folder is named "Personal", it is actually "My Documents" folder on Windows NT 4.0.

% WINDIR% / Profiles / Kylemar / Personal

WINDOWS 2000 moves again to the location of the folder, so that it is no longer located in the system directory or under the root of the root. Windows 2000 puts it:

/ Documents and Settings / Kylemar / My Documents

As you can see, when the folder changes, if the hard code is still acting in it, there will be an error. In fact, in the managed environment, the "My Documents" folder may also be on the network drive. In order to avoid this, it is necessary to use ShgetFolderPath like we have discussed before, and ensure this in Windows 95, Windows 98 or any platform. In the default Windows 2000 case, you can find the correct location.

Long file name and long printer name

Since Windows 95 came out, we have been talking about long file names and printer names. Initially, we just ask the application to support these two; after upgrading to Windows 2000, we ask for programs to support them correctly. We have found that in many places, the app does not implement correct support for long file names. But this is not to say that these applications do not support them (even if there is a small number), but we discover some errors in supporting long file names. For example, there is an application that claims to implement support for long file names, providing a buffer for all 256 characters. But when we remove files and provide a longer path to the lookup file (about 50 characters), the program has collapsed. This indicates that although the app tells us that it has a long buffer, it is actually only available to a shorter buffer. This is just a simple error in the application; since we transferred the "My Documents" folder to "Documents and Settings" instead of placing it in the root directory or Windows system directory, you will often encounter such errors. . The path has a tendency to grow, and the current average path length is 60 to 70 characters, and no longer 30 to 40 characters. The use of long path name is exposed to more and more errors. Another problem found in the "Documents and Settings" folder is "Documents and Settings" written by many applications, which cannot be accessed normally. The application analyzes the directory, as long as the word "documents" is found, the program will think that the end of "My Documents" is considered. In this way, the application will be interrupted, while thinking "I found the word 'Documents', I have found 'My Documents'." This is certain.

Be sure to fully check the long file name support function and test it. You will find a quite long string in the Windows 2000 application specification (http://msdn.microsoft.com/certification/appspec.asp (English)), you can use it to confirm if the application can support the length correctly file name.

Heap management

Another application stability problem is derived from the changes to the heap management on the Windows NT platform. This is the most shocking problem I mentioned here. It has great dangers that can lead to various issues in your application. It is actually the same as we often encounter in the old C language: a pointer error or memory usage error occurs. But it is difficult to handle one of the problems.

In fact, this problem starts from Windows NT 4.0, Service Pack 4. We have changed the heap manager to make it efficient, faster, especially for computers with multiprocessors. WINDOWS 2000 has changed on this basis, so that the program that can run on Windows NT 4.0 is unable to run after installing Service Pack 4. Or the program that can be run in Service Pack 4, cars in Windows 2000, because we have made a lot of improvements to the work of the heap manager. Obviously, if you need to improve system performance, and speed up the running speed of the heap manager, it is still much more. We did not make changes to the API itself, and we did not logically change the heap of work, but we have made some subtle changes in the repetition method of blocks, allowing the misconduct in the application to expose.

In short, what we do is as follows: Previously, when a block was released, it will be included in the unused empty block list, at the end of the table, and finally it will be filtered again. Now, we will cache the blocks that are last used and put them at the top of the table. When you need another block, you can first adjust this block first. If you need to call back a block, you will generate a space, you will call the block just used, so you can keep yourself on the same page and improve the speed of the system. This is what we have encountered in C language design and C program development from the beginning. In fact, there is no way to better find these problems. You can use some business tools to find these questions. In addition, you need to test these software as much as possible on Windows 2000.

We have found that many applications have a pile of problems. The most common problem is to try to access the released memory. The result is that the application will allocate, which will read and write these blocks, then release these blocks, and then read and write these blocks. The danger of this practice is that the data is destroyed, and your app will crash. But because it resides in a piece or page that has been dominated, and because you are reading and writing blocks that allow you to write, it will not cause access to violation, but cause data damage. I am willing to lead to system crash, because this situation is easier to remedy, but it is difficult to say that any case may happen.

Another problem is: In order to get a more fully utilization of a page, the Windows 2000 and Service Pack 4 may also move this allocation area when you have reassigned a smaller block. . Many developers hold a suspicious optimization point. "If I reassign a smaller block than I specified by I originally specified, no one can point my pointer to me, I can redistribute, and believe it is no longer Moving pointer. Therefore, as long as I make it smaller, no one can move it. " This will result in a comprehensive error.

Call rule

The call rule issue is discussed below. In addition, you must use stdcall for all window procedures. Unfortunately, we have found that many applications do not use stdcall for its window, and the dialog process is also true. If you don't use stdcall, your program may not work properly. In Windows 95 and Windows 98, you can avoid this problem by using a C_DECL rule; in other words, if you only forgetting the C_DECL rule during the window, the system will not collapse.

We set a ribbon for this in Windows 2000, so we can capture them as much as possible. However, in the last week, I still found a mistake. It jumped out to me, "Yes, we have made these handles in place, and we try to handle standard calls, but because applications are not used Standard calls, we still have not intercepted them correctly. "If your window uses stdcall instead of other call rules, things will be much simpler.

We also found that some applications use the correct call rules, but not properly implemented, or the error in the compiler shows that there is no correct use of call rules, or the application will enter the registration process faster. Because we are carrying out further optimization, the purpose is to use registration content more stringent and make it less resources, run faster, and we have encountered many cases where applications are not compatible due to failure to strictly follow rules.

Non-buffered file file I / O

If you want to handle some file I / O without using the buffer provided by the system, you need to use the flag on create file file_flag_no_buffering (meaning, you can provide buffers yourself without using the system assigned to these read and write operations. ). You must confirm that the buffer passed to the ReadFile and WriteFile API has been properly aligned for the device. These have no difference in previous, however, we found that these alignment is slightly different on Windows 2000, especially in support for new ELTRA 66 IDE drives. So, you must confirm that the allocation buffer is correct. The easiest way to achieve this is to use Virtualalloc. Virtualalloc will always be aligned with the buffer, so it can always be correctly aligned regardless of the buffer size required by the device completion file I / O. Remember, when you do this, you must confirm that you are using a few times of the actual sector size of the I / O device when you read and write. You can get the sector size via GetDiskFreespace and make sure you only assign and read several times the size of these sectors. Large drive

Another problem related to the drive is to have some large drives. Obviously, the current drive is much larger than 4GB, in general, the available space is much more than 4GB. However, if you use getDiskFreespace, it will return a string of 32-bit values, which is not accurate, because the actual value is much more than, this situation will appear in many places. We have found that the number of disk space returned by the application is negative, thereby appearing a variety of problems.

You need to apply GetDiskFreespaceEx, which uses ularge_integer_ instead of int, so you can provide you with real data for available space.

Open another HKEY_CURRENT_USER

Some applications (especially some server applications) require information from other HKEY_CURRENT_USERs instead of their initial or current HKEY_CURRENT_USER. The problem is that the way HKEY_CURRENT_USER actually used is based on each process. The application will try to close HKEY_CURRENT_USER, simulate new users, then open HKEY_CURRENT_USER, and hope that they get the correct HKEY_CURRENT_USER. The problem is if this operation is performed using multiple threads, one of the threads may have been completed, and the other thread may be in the operation. You can't figure out which HKEY_CURRENT_USER is ending because the system will declare the second open "" I have opened HKEY_CURRENT_USER, I used the one in the cache. "This operation has quite dangerous. In order to improve this situation, we have added a new, named RegOpenCurrentuser, with this API, you can implement an analog process correctly to get the true hkey_current_user.

Check bit (BIT) logo

Another low-level C class problem: We have found that an application is checked when a bit flag is checked, rather than actually checking if a particular bit is present. We will add a flag in all versions of Windows 2000 and Windows 2000, so you need to make sure you check the bit, not whether it is equal. We have added owner graphics that do not focus values ​​and acceleration values, so that they have different types of drawing parameters. The following is the way to check the bit mark:

The order of if (fitemstate & ods_focus) message

We have been telling developers to express some specific meaning or rely on the order of messages or rely on the order of the application to receive messages. This is reliable. We even discover some applications depend on the order of messages in some multi-threaded applications. For example, it may happen: there is a thread to turn off, then a message is issued to the main message, then the other thread is turned off, and a message is issued. The application may send the message to the order of threads. We have changed the operation of the thread plan program. Ideally, they complete the release of the message, will send the message to the queue in order to process, but the actual situation is not. If you try it, it will find that the order of the message is inconsistent with the order of thread off, thereby various issues. Also emphasized, if you need to rely on the order of the message (especially in the case of cross thread), you don't want to think that the message itself is a synchronization method, and add your own synchronization mechanism.

Multiple monitors

Starting with Windows 98, Windows has the ability to handle multiple monitors. Windows 2000 is the first platform with this ability, Windows NT-based platform. A big problem: You must confirm that your application can correctly handle the negative coordinates and oversized coordinates or behave as oversized coordinates. If multiple monitors are set, the main monitor is on the right side of the sub-monitor, the deputy monitor will be completely in the negative coordinate area. If your application calls a window that should be in the deputy monitor, the application wants to maximize the window, assume that the application cannot handle the multi-monitor system correctly, which will move the window throughout the window due to the current coordinates Main display. This should not occur. If you need a positioning window, you must test the application in the multi-display system, confirm that these negative coordinates can be handled correctly. This should be processed so for a large-scale coordinate. You need to use the new system target shown in the figure to ensure that the window is placed at its location.

Difference between Windows platforms

I will discuss the last type of problem (more than other issues): The basic difference between the Windows platform. Windows 2000 is based on WinSows NT. We recognize that a large number of users will upgrade their Windows 9x to Windows 2000. We have been testing some applications, move them from Windows 9x to the Windows 2000 platform. You will find a lot of information about this issue in the magazine article and SDK. You need to make sure your app is not closely to the Windows 9x platform, but it should be closely to the Windows NT platform.

Applications with strict restrictions

The first target strict restriction is that the API used by the application can only be implemented on the Windows 9x platform, and cannot be implemented in Windows NT. The Tool Help API I often use is an example. In Windows 2000 we can already support Tool Help API to some extent, but you will find that there is a large number of APIs in Windows 9x have not found the way to upgrade to Windows NT. There is no truly possible way to solve this problem. You can use the .csv file in the SDK, this file is actually just a spreadsheet, which tells you about any API: Where can be implemented, where is it, how to work, in addition to this other information. Another way is to effectively test the application to ensure that your application can be migrated between Windows 98 and Windows NT platforms to ensure they can run. This method may be much simpler, and it is much better.

You need to pay attention to the following facts; the Windows NT platform uses a full 32-bit coordinate system in its GDI call, while Windows 9x is 16 bits. Be sure to know these differences. In fact, all the handles in Windows NT are completely 32 bits. Some developers tried to take advantage of the following facts: The handle in Windows 9x is 32 bits, but only 16 bits. If you use this on Windows NT, the consequences will be very bad. General replacement

There are many applications that have many applications in the application replacement process will also fall into dysfunction. The way Windows 9x can be called "Flat Thunk": it allows 16-bit applications to transfer 32-bit applications, allowing 32-bit applications to be transferred directly into a 16-bit component, or 16-bit applications program. Windows 2000 does not support this feature, especially without supporting 32-bit applications directly to 16-bit applications. Ways used in Windows 2000 and Windows NT can be called "generic tunk": General Replacement allows 16-bit applications to be transferred to 32-bit components, and the 16-bit application is allowed to initiate a calling process for 32-bit components, Then call the 16-bit application by 32-bit components without supporting 16-bit components directly from 32-bit code, which cannot take effect. You can only start the 32-bit call from 16 bits, which cannot be seen. In addition, it is necessary to remember a point for the replacement process: the basic process model between Windows 9X and Windows NT is different. You can see some differences from a general replacement. The easiest way is to transplant 16-bit components to 32-bit components. You need to have a clear understanding of the replacement of these two platforms.

转载请注明原文地址:https://www.9cbs.com/read-8132.html

New Post(0)