Click here to Skip to main content
15,896,153 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
Hello,

I'm writing a function which load a keyboardlayout using the registry. The whole programm works fine under a 32-Bit windows but it crash on a 64-Bit windows.

// headerfile

#define TYPEDEF_VK_TO_WCHARS(n) typedef struct _VK_TO_WCHARS##n { \
  BYTE  VirtualKey; \
  BYTE  Attributes; \
  WCHAR wch[n]; \
} VK_TO_WCHARS##n, *KBD_LONG_POINTER PVK_TO_WCHARS##n;

TYPEDEF_VK_TO_WCHARS(1)
TYPEDEF_VK_TO_WCHARS(2)
TYPEDEF_VK_TO_WCHARS(3)
TYPEDEF_VK_TO_WCHARS(4)
TYPEDEF_VK_TO_WCHARS(5)
TYPEDEF_VK_TO_WCHARS(6)
TYPEDEF_VK_TO_WCHARS(7)
TYPEDEF_VK_TO_WCHARS(8)
TYPEDEF_VK_TO_WCHARS(9)
TYPEDEF_VK_TO_WCHARS(10)

typedef struct _VK_TO_WCHAR_TABLE {
  PVK_TO_WCHARS1 pVkToWchars;
  BYTE           nModifications;
  BYTE           cbSize;
} VK_TO_WCHAR_TABLE, *KBD_LONG_POINTER PVK_TO_WCHAR_TABLE;

#define INIT_PVK_TO_WCHARS(i, n) \
if((pKbd->pVkToWcharTable[i].cbSize - 2) / 2 == n) \
  pVkToWchars##n = (PVK_TO_WCHARS##n)pKbd->pVkToWcharTable[i].pVkToWchars; \

  
// sourcefile
HINSTANCE loadKeyboardLayout() {
  PKBDTABLES pKbd;
  HINSTANCE kbdLibrary;
  KbdLayerDescriptor pKbdLayerDescriptor = NULL;

  char layoutFile[MAX_PATH];

  if (getKeyboardLayoutFile(layoutFile, sizeof(layoutFile)) == -1) return NULL;

  char systemDirectory[MAX_PATH];
  GetSystemDirectory(systemDirectory, MAX_PATH);

  char kbdLayoutFilePath[MAX_PATH];
  snprintf(kbdLayoutFilePath, MAX_PATH, "%s\\%s", systemDirectory, layoutFile);

  kbdLibrary = LoadLibrary(kbdLayoutFilePath);

  pKbdLayerDescriptor
      = (KbdLayerDescriptor) GetProcAddress(kbdLibrary, "KbdLayerDescriptor");

  if (pKbdLayerDescriptor != NULL) pKbd = pKbdLayerDescriptor();
  else return NULL;

  int i = 0;
  do {
    INIT_PVK_TO_WCHARS(i, 1) // crash at this line on an 64-Bit windows
    INIT_PVK_TO_WCHARS(i, 2)
    INIT_PVK_TO_WCHARS(i, 3)
    INIT_PVK_TO_WCHARS(i, 4)
    INIT_PVK_TO_WCHARS(i, 5)
    INIT_PVK_TO_WCHARS(i, 6)
    INIT_PVK_TO_WCHARS(i, 7)
    INIT_PVK_TO_WCHARS(i, 8)
    INIT_PVK_TO_WCHARS(i, 9)
    INIT_PVK_TO_WCHARS(i, 10)
    i++;
  } while (pKbd->pVkToWcharTable[i].cbSize != 0);
  return kbdLibrary;
}

int getKeyboardLayoutFile(char* layoutFile, DWORD bufferSize) {
  HKEY hKey;
  DWORD varType = REG_SZ;

  char kbdName[KL_NAMELENGTH];
  GetKeyboardLayoutName(kbdName);

  char kbdKeyPath[51 + KL_NAMELENGTH];
  snprintf(kbdKeyPath, 51 + KL_NAMELENGTH,
           "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s", kbdName);

  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR) kbdKeyPath, 0,
                   KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) return -1;

  if (RegQueryValueEx(hKey, "Layout File", NULL, &varType, (LPBYTE) layoutFile,
                      &bufferSize) != ERROR_SUCCESS) return -1;

  RegCloseKey(hKey);

  return 1;
}


I hope anyone can help me. :)


Regards cookieexploit
Posted
Updated 15-Jun-11 7:03am
v4
Comments
TRK3 14-Jun-11 15:15pm    
Are your layoutFile and bufferSize arguments valid/correct?
Albert Holguin 14-Jun-11 16:35pm    
I'm pretty sure I've used this call on a 64bit system without this result... Are you sure that's causing it? How did you determine that? Does the debugger offer any useful information?
HartzFear 15-Jun-11 12:53pm    
I Debug it and I've found anouther location of the error, sry my misstake. I'll add the other code to the question.
The whole code works fine under a 32-Bit windows and I'm new at the programming for a 64-Bit windows, so I hope you can tell me what im doing wrong.
Member 8375540 10-Nov-11 0:48am    
I've got the same problem. I tracked it back to pKbd->pVkToWcharTable being NULL after the call to pKbd = pKbdLayerDescriptor(). My code is 32 bit code running on 64 bit Win7. Does anyone know why the table would not get populated on 64 bit Win7. It works fine on 32-bit Win7.

1 solution

I recall reading of other users experiencing problems when porting 32 bit programs that rely on the registry to 64 bit machines, though have yet to bother to play with registry access on my win7 pc.

You should be stepping in Debug mode to determine which line fails. At the very, very least you should have tried a MessageBox every so often to gauge where your program is failing.

I'd think it be some trick with the registry access, though you'll find it with little trouble, I expect.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900