What is the Maximum length that a Windows Registry Key name can be? - windows-vista

I'm writing a very long registry Key name (it's a list of programs for a combined uninstall) and I think it's too big.
What's the max size the key can be (in characters) ?
(The smallest maximum among Win xp, vista, 7 since it'll need to work on all of them)

Key Name: 255 characters
Value name: 16,383 characters
Value: Available memory (latest format)
or 1 MB (standard format)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724872%28v=vs.85%29.aspx

According to this support article, it is 255 characters.

here's a key that's longer than 255:
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\DeviceClasses{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}##?#STORAGE#VOLUME#_??_USBSTOR#DISK&VEN_LEXAR&PROD_USB_FLASH_DRIVE&REV_1100#AANL1B891R5GCDV6&0#{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}#
I found this when I was writing a tool to search all keys in the registry. I created a buffer that was 256 which caused a stack corruption exception.
When I tried to view this key using regedit I noticed it shows an arrow indicating there are subkeys but won't respond when clicked on. I only guess at the final '#' key because other keys in that area end with it.
When I doubled the buffer everything went smoothly.

Related

RegEnumValue returns different buffer size in Vista compatibility mode

I have a very weird issue when my application is run under "Windows Vista Compatibility mode" (right-click the EXE, enable compatibility mode and select windows vista).
The issue is the return buffer length value from the "RegEnumValue" function returns a different value.
For example, with a registry value of "Zoom Player MAX" (15 characters):
With compatibility mode diabled, RegEnumValue's "lpcbData" field return a value of 16 (including the trailing null termination).
With compatibility mode enabled, RegEnumValue's "lpcbData" field return a value of 15 (doesn't include the trailing null termination).
Is there a work-around/patch for this that doesn't require changing my string conversion code?
It should not matter. When reading from the Registry using low-level classic functions, you must be able to handle strings with and without null-terminators:
Beware of non-null-terminated registry strings
The easy way to do this is to secretly allocate one extra character that you don't tell the API about when reading, and then append the '\0' character to the end of however many characters it returns.
Newer functions like RegGetValue() handle this for you.

VB6 MSComm, ports above 127 return 8002

I have a simple function that checks if we have open ports on the system, I would test ports from 1 to 256. For some odd reason when I have device at port over 127 system returns error 8002. This is very odd because when I use a different C++ application to check connection device is found and is available for reading.
This issue is related to the MSComm32.OCX, which has a limit on how many ports are available. I need to increase this limit to 256. I found a list of instruction below, but I wasn't able to find "3D 10 00" in the MSComm32.OCX file, this was on Windows 8 PC. However, on Windows XP MSComm32.OCX did contain "3D 10 00", i quickly found the string and added a new byte "FF" and deleted byte "10" using http://mh-nexus.de/en/hxd/ and saved it as a new file.
First you copy the file MSCOMM32.OCX to a safe place.
1. Obtain a HEX editor.
2. Open de file MSCOMM32.OCX
3. Find the string "3D 10 00"
4. There should be only one. This string is unique.
5. Change the string to "3D FF 00"
6. Save the file.
I don't know if this will help in your case, but you will be unable to edit the original ocx file using this procedure. You can only edit the file after it has been registered. The original is the "cookie cutter" from which all registered files are descended and it has a completely different structure. The registered file will have the "3D 10 00" sequence in it and can be modified. It would be nice if the original could be modified since all new instances would then have the modified upper port limit already in them, but Microsoft made sure that won't work.

After CreateProcessWithLogonW switch language with alt shift stops working

I encountered a strange problem:
When our application spawns child process with CreateProcessWithLogonW
switch language with alt-shift stops working in the windows of the new process.
What might be the problem? The OS is XP SP3. The same setup is ok on Win 7.
Additional thing I discovered: This problem only occurs on Win XP Hebrew.
On English XP it works fine.
As Hans Passant has said CreateProcessWithLogonW requires the LOGON_WITH_PROFILE to be set as dwLogonFlags which is the fourth argument of the function in order to load the user registry hive into HKEY_USERS. This will ensure that access to information in the HKEY_CURRENT_USER registry key will produce results that are consistent with a normal interactive logon.
Alternately you can call the LoadUserProfile function beforecalling CreateProcessWithLogonW.
Registry settings you will want to verify exist for the user whose profile you are loading include
[HKEY_CURRENT_USER\Keyboard Layout\Toggle]
"Hotkey"="3"
"Language Hotkey"="3"
"Layout Hotkey"="3"
[HKEY_CURRENT_USER\Keyboard Layout\Preload]
"1"="00000809"
"2"="e00e0804"
[HKEY_CURRENT_USER\Software\Microsoft\CTF\LangBar]
"ShowStatus"=dword:00000000"
The values of [HKEY_CURRENT_USER\Keyboard Layout\Toggle] are
1 Key Sequence enabled; use Left-ALT+SHIFT to switch between locales.
2 Key Sequence enabled; use CTRL+SHIFT to switch between locales.
3 Key Sequences disabled.
4 If the default locale is Thai, the accent grave key toggles input locales; otherwise key sequences are disabled.
The values of [HKEY_CURRENT_USER\Keyboard Layout\Preload] are listed here under the KeyName column.
The values of [HKEY_CURRENT_USER\Software\Microsoft\CTF\LangBar] are
0 Floating on desktop
4 Docked on the taskbar
3 when set to Hidden which is the default.
Relevant resources include
Similar Stack Overflow Question
CreateProcessWithLogonW function MSDN Reference
Managed CreateProcessWithLogonW

Windows Maximum Length of Key Container Name

Can anyone confirm that the maximum length of a key container name in Windows is 260 characters. I expect this to be the size because the value is stored as a file, but I have not found the specific answer as of yet.
In the meantime I'll see what trial and error I can do.
Updated:
I did trial and error with aspnet_reiis.exe and discovered that 260 is indeed the maximum length. 261 and above causes key creation failure.
I don't think there is one, or at least you shouldn't rely on there being one. From the documentation:
The key container name. This is a null-terminated string that identifies the key container to the CSP. This name is independent of the method used to store the keys. Some CSPs store their key containers internally (in hardware), some use the system registry, and others use the file system. When dwFlags is set to CRYPT_VERIFYCONTEXT, pszContainer must be set to NULL.
Piratically speaking you would probably be safe with 256 as that is the maximum length of both a file name and a registry key.

Why does the 260 character path length limit exist in Windows?

I have come up against this problem a few times at inopportune moments:
Trying to work on open source Java projects with deep paths
Storing deep Fitnesse wiki trees in source control
An error trying to use Bazaar to import my source control tree
Why does this limit exist?
Why hasn't it been removed yet?
How do you cope with the path limit?
And no, switching to Linux or Mac OS X is not a valid answer to this question ;)
Quoting this article https://learn.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation
Maximum Path Length Limitation
In the Windows API (with some exceptions discussed in the following paragraphs), the maximum length for a path is MAX_PATH, which is defined as 260 characters. A local path is structured in the following order: drive letter, colon, backslash, name components separated by backslashes, and a terminating null character. For example, the maximum path on drive D is "D:\some 256-character path string<NUL>" where "<NUL>" represents the invisible terminating null character for the current system codepage. (The characters < > are used here for visual clarity and cannot be part of a valid path string.)
Now we see that it is 1+2+256+1 or [drive][:\][path][null] = 260. One could assume that 256 is a reasonable fixed string length from the DOS days. And going back to the DOS APIs we realize that the system tracked the current path per drive, and we have 26 (32 with symbols) maximum drives (and current directories).
The INT 0x21 AH=0x47 says “This function returns the path description without the drive letter and the initial backslash.” So we see that the system stores the CWD as a pair (drive, path) and you ask for the path by specifying the drive (1=A, 2=B, …), if you specify a 0 then it assumes the path for the drive returned by INT 0x21 AH=0x15 AL=0x19. So now we know why it is 260 and not 256, because those 4 bytes are not stored in the path string.
Why a 256 byte path string, because 640K is enough RAM.
This is not strictly true as the NTFS filesystem supports paths up to 32k characters. You can use the win32 api and "\\?\" prefix the path to use greater than 260 characters.
A detailed explanation of long path from the .Net BCL team blog.
A small excerpt highlights the issue with long paths
Another concern is inconsistent behavior that would result by exposing long path support. Long paths with the \\?\ prefix can be used in most of the file-related Windows APIs, but not all Windows APIs. For example, LoadLibrary, which maps a module into the address of the calling process, fails if the file name is longer than MAX_PATH. So this means MoveFile will let you move a DLL to a location such that its path is longer than 260 characters, but when you try to load the DLL, it would fail. There are similar examples throughout the Windows APIs; some workarounds exist, but they are on a case-by-case basis.
The question is why does the limitation still exist. Surely modern Windows can increase the side of MAX_PATH to allow longer paths. Why has the limitation not been removed?
The reason it cannot be removed is that Windows promised it would never change.
Through API contract, Windows has guaranteed all applications that the standard file APIs will never return a path longer than 260 characters.
Consider the following correct code:
WIN32_FIND_DATA findData;
FindFirstFile("C:\Contoso\*", ref findData);
Windows guaranteed my program that it would populate my WIN32_FIND_DATA structure:
WIN32_FIND_DATA {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
//...
TCHAR cFileName[MAX_PATH];
//..
}
My application didn't declare the value of the constant MAX_PATH, the Windows API did. My application used that defined value.
My structure is correctly defined, and only allocates 592 bytes total. That means that i am only able to receive a filename that is less than 260 characters. Windows promised me that if i wrote my application correctly, my application would continue to work in the future.
If Windows were to allow filenames longer than 260 characters then my existing application (which used the correct API correctly) would fail.
For anyone calling for Microsoft to change the MAX_PATH constant, they first need to ensure that no existing application fails. For example, i still own and use a Windows application that was written to run on Windows 3.11. It still runs on 64-bit Windows 10. That is what backwards compatibility gets you.
Microsoft did create a way to use the full 32,768 path names; but they had to create a new API contract to do it. For one, you should use the Shell API to enumerate files (as not all files exist on a hard drive or network share).
But they also have to not break existing user applications. The vast majority of applications do not use the shell api for file work. Everyone just calls FindFirstFile/FindNextFile and calls it a day.
From Windows 10. you can remove the limitation by modifying a registry key.
Tip Starting in Windows 10, version 1607, MAX_PATH limitations have been removed from common Win32 file and directory functions. However, you must opt-in to the new behavior.
A registry key allows you to enable or disable the new long path behavior. To enable long path behavior set the registry key at HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled (Type: REG_DWORD). The key's value will be cached by the system (per process) after the first call to an affected Win32 file or directory function (list follows). The registry key will not be reloaded during the lifetime of the process. In order for all apps on the system to recognize the value of the key, a reboot might be required because some processes may have started before the key was set.
The registry key can also be controlled via Group Policy at Computer Configuration > Administrative Templates > System > Filesystem > Enable NTFS long paths.
You can also enable the new long path behavior per app via the manifest:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
</application>
You can mount a folder as a drive. From the command line, if you have a path C:\path\to\long\folder you can map it to drive letter X: using:
subst x: \path\to\long\folder
One way to cope with the path limit is to shorten path entries with symbolic links.
For example:
create a C:\p directory to keep short links to long paths
mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo
add C:\p\foo to your path instead of the long path
You can enable long path names using PowerShell:
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name LongPathsEnabled -Type DWord -Value 1
Another version is to use a Group Policy in Computer Configuration/Administrative Templates/System/Filesystem:
As to why this still exists - MS doesn't consider it a priority, and values backwards compatibility over advancing their OS (at least in this instance).
A workaround I use is to use the "short names" for the directories in the path, instead of their standard, human-readable versions. So e.g. for C:\Program Files\ I would use C:\PROGRA~1\ You can find the short name equivalents using dir /x.
As to how to cope with the path size limitation on Windows - using 7zip to pack (and unpack) your path-length sensitive files seems like a viable workaround. I've used it to transport several IDE installations (those Eclipse plugin paths, yikes!) and piles of autogenerated documentation and haven't had a single problem so far.
Not really sure how it evades the 260 char limit set by Windows (from a technical PoV), but hey, it works!
More details on their SourceForge page here:
"NTFS can actually support pathnames up to 32,000 characters in
length."
7-zip also support such long names.
But it's disabled in SFX code. Some users don't like long paths, since
they don't understand how to work with them. That is why I have
disabled it in SFX code.
and release notes:
9.32 alpha 2013-12-01
Improved support for file pathnames longer than 260 characters.
4.44 beta 2007-01-20
7-Zip now supports file pathnames longer than 260 characters.
IMPORTANT NOTE: For this to work properly, you'll need to specify the destination path in the 7zip "Extract" dialog directly, rather than dragging & dropping the files into the intended folder. Otherwise the "Temp" folder will be used as an interim cache and you'll bounce into the same 260 char limitation once Windows Explorer starts moving the files to their "final resting place". See the replies to this question for more information.
It does, and it is a default for some reason, but you could easily override it with this registry key:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"LongPathsEnabled"=dword:00000001
See: https://blogs.msdn.microsoft.com/jeremykuhne/2016/07/30/net-4-6-2-and-long-paths-on-windows-10/
Another way to cope with it is to use Cygwin, depending on what do you want to do with the files (i.e. if Cygwin commands suit your needs)
For example it allows to copy, move or rename files that even Windows Explorer can't. Or of course deal with the contents of them like md5sum, grep, gzip, etc.
Also for programs that you are coding, you could link them to the Cygwin DLL and it would enable them to use long paths (I haven't tested this though)

Resources