IMOFCompiler::CompileFile() Does Not Work with Some Unicode File Names (318590)



The information in this article applies to:

  • Microsoft Windows Management Instrumentation 1.5, when used with:
    • the operating system: Microsoft Windows 95
    • the operating system: Microsoft Windows 98
    • the operating system: Microsoft Windows 98 Second Edition
    • the operating system: Microsoft Windows NT
    • the operating system: Microsoft Windows 2000

This article was previously published under Q318590

SYMPTOMS

IMOFCompiler::CompileFile may not compile an .mof file if the FileName path parameter contains Japanese, Korean, or Chinese characters. This problem does not affect Microsoft Windows XP or later versions of Microsoft Windows.

CAUSE

IMOFCompiler (Mofd.dll) in Windows Management Instrumentation (WMI) version 1.5 converts the FileName parameter in the CompileFile method from Unicode to double-byte character set (DBCS) before it opens the .mof file. The wcstombs C run-time library function is used to perform this conversion.

By default, the C run-time library string functions (such as mbstowcs and wcstombs) use the "C" locale to perform Unicode and DBCS conversions. This is equivalent to using ANSI translations. Using ANSI translation rules can cause problems when you perform conversions involving Japanese, Korean, or Chinese DBCS characters.

For example, the following code uses the "C" locale (ANSI translation) to convert a command-line argument to Unicode. This may not work as expected if the system default code page is an Eastern language (such as Japanese Kanji--932):
mbstowcs(wFileName, argv[argc-1], MAX_PATH);
				
In the next example, the locale is set to the current default code page (for example, Japanese) before the command-line argument is converted to Unicode. The DBCS command-line argument is correctly converted to Unicode by using the conversion rules of the current locale:
setlocale(LC_ALL, "");
mbstowcs(wFileName, argv[argc-1], MAX_PATH);
				
IMOFCompiler in WMI 1.5 does not set the locale to the current system code page before converting the FileName path parameter to DBCS. This is also true for the Mofcomp utility. Mofcomp, which uses IMOFCompiler::CompileFile, does not set the locale before using mbstowcs to convert the DBCS FileName path argument to Unicode. Because Mofcomp and IMOFCompiler both use the same rules (ANSI) to convert the file name paths, conversion works correctly, even with Eastern languages. However, if a true Japanese Unicode file name path is passed to the WMI 1.5 version of IMOFCompiler (by using a third-party program), the compilation does not succeed.

STATUS

Microsoft has confirmed that this is a problem in the Microsoft products that are listed at the beginning of this article.

MORE INFORMATION

IMOFCompiler (Mofd.dll) on Windows XP and later versions of Windows is compiled for true Unicode support. This prevents the conversion issue for ANSI file name paths that is described in this article.

The following sample code demonstrates how to use IMOFCompiler across different operating systems and locales:
#define _WIN32_WINNT    0x0400

#include <windows.h>
#include <comdef.h>
#include <wbemidl.h>
#include <locale.h>    
#include <stdio.h>      
#include <stdlib.h>

void main(int argc, char** argv)
{
  WCHAR wFileName[MAX_PATH] = L"";

  IMofCompiler             *pComp = NULL;
  WBEM_COMPILE_STATUS_INFO *pInfo = NULL;

  //--- Check arguments and the Windows version ---

  if (argc != 2) return;

  OSVERSIONINFO osvi;
  ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  GetVersionEx((OSVERSIONINFO*)&osvi);

  //--- Convert a DBCS file name to Unicode ---

  if ((osvi.dwMajorVersion > 5) ||
      ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1)))
  {
    setlocale(LC_ALL,"");  // Windows XP or later needs the locale  
  }

  mbstowcs(wFileName, argv[argc-1], MAX_PATH);

  //--- Initialize DCOM ---
    
  CoInitializeEx(0, COINIT_MULTITHREADED);
  CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_NONE,
                       RPC_C_IMP_LEVEL_IMPERSONATE,
                       NULL, EOAC_NONE, NULL);

  //--- Get the compiler object (in-process COM server) ---
    
  DWORD dwRes = CoCreateInstance(CLSID_MofCompiler, 0,
                                 CLSCTX_INPROC_SERVER, 
                                 IID_IMofCompiler, (LPVOID *) &pComp);

  //--- Compile the .mof file ---
    
  if (dwRes == S_OK)
  {
    HRESULT hRes = pComp->CompileFile(wFileName, NULL, NULL, NULL, 
                                      NULL, WBEM_FLAG_DONT_ADD_TO_LIST, 
                                      0, 0, pInfo);

    if (hRes != WBEM_S_NO_ERROR)
    {
      printf("Compile Failed. Error code = 0x%X\n", hRes);
    }

    if (pComp) pComp->Release(); // Finished with compiler object
  }

  //--- Clean up DCOM ---

  CoUninitialize();
}
				
Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure, but they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements.

Modification Type:MajorLast Reviewed:6/17/2005
Keywords:kbenv kbfix kbprb KB318590