I know that in Windows, the GUID is used by the Windows Installer to check for already installed products under the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ and other product-relevant information is stored using the compressed GUID in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\.
Yet a google search to figure out what the compressed GUID actually is and why both forms are being used for saving product-specific data in the registry database only revealed algorithms for converting from one form to another.
Apparently, the compressed GUID is calculated from merely changing the order of the characters in a specific way, giving me more confusion about why this is the compressed form and why it is used this way.
Additionally, some sources appear to refer to the GUID as the product code of the software product, and others specifically use the term product code as a synonym for the compressed GUID.
I do not have much knowledge of the inner workings of Windows and its installers, but hope that someone can enlighten me with the information I was unable to find. I apologize in advance for my mediocre English.
Not sure what you are doing, or why this is a problem for your scenario. However, the GUIDs you mention - the rearranged GUIDs with the braces and dashes removed - are actually referred to as Packed GUIDs. Then there are also Compressed GUIDs that are just 23 characters long that are primarily used to create Darwin descriptors - which are combinations of the product code GUID, a feature name, and a component code GUID. They are used for MSI's advertisement features. This is according to Bob Baker's book "Getting Started with InstallShield Developer and Windows Installer Setups".
As far as I recall the packed GUIDs are apparently used to make registry searches more efficient. I am unfamiliar with the exact technical details involved. Perhaps Bob or Rob of WiX can elaborate.
I have to run, not really an answer, I will look at it again later. Please elaborate your question with more details on what the problem actually is. As a summary it seems the collective comments suggest that this GUID concept is due to registry space saving, searching efficiency and obfuscation.
My advice (if I understand correctly): do not attempt to read packed or compressed GUIDs from the registry directly - rather go via the MSI API (COM / Win32) - which should have the features you need to do almost anything with MSI.
Some Links:
MSIEXEC -Embedding
MSI API Links (quite similar links):
Is MsiOpenProduct the correct way to read properties from an installed product?
Wix upgrade goes into maintenance mode and never does upgrade
how to find out which products are installed - newer product are already installed MSI windows
Is there an alternative to GUID when using msiexec to uninstall an application?
The packed guid is reportedly used to save space in the registry. It is used for component Ids, so once you start getting a million components on the system I assume they were worried about the extra space usage. It's also possible it was used to prevent people trawling the registry to look for Windows Installer items instead of using the APIs. It's an undocumented implementation detail, and if too many people got into habit of using the registry instead of using the APIs there would be issues if that implementation changed. So treat this as interesting information, not something to use in an application.
Darwin Descriptors are different - they are just an encoding of product code, component id, and feature name. They occur in various places where that combination of data is useful for loading COM servers, starting programs etc. Again, it's undocumented, but if you wanted to untangle them you could LoadLibrary on msi.dll and find and call MsiDecomposeDescriptorW with the right parameters.
Related
I am currently working on an application which will audit computers, and one of the things that it is mandatory for this app to achieve is to get the license key from the install of OEM windows and Retail Office, in order to retain this information for future purposes, such as re-installation and move from one machine to another (this part is more for office).
The requirement here is specifically NOT to use any apps that already find keys, this is a BIG no no for the project.
The goal is to have a comprehensive audit of the user's PC:
hardware info, software installed, user account name, pc name, domain currently used, workgroup, antivirus used, running processes, startup processes, and LICENSE KEYS. And it has to be custom tailored for this specific purpose, so retail apps are instantly out of the question.
Now I am very confident I can do everything myself. Frankly, I already did 50% of this. Where I am stuck is finding where the license keys are stored within windows.. It has been eluding me for a week now.. Internet searching only refers me to sites that offer the easy and lazy option of using a pre-made key finder.
Initially I thought that these would be somehow squirreled away in the registry, but a plaintext search of my own personal Office key returned a great big nothing. Which leaves me to wonder if these keys are stored in the registry, are they perhaps in there as HEX? Or encrypted?
Or if not, where could they be stored?
The literally used keys are not stored on the computer.
However the registry contains a value which is based on the original key. There is software (which you stated is "a big no no") which you can use to calculate the original key based on these values.
If you want to do this yourself then you might want to take a look at bytes 34 through 42 from HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\Current Version\DigitalProductId (for windows). Office uses something similar.
I need to use the reference to Microsoft Word 97 in my VB6 development project. (Its a long story - in a nutshell if I use ref to MSWord97 then I can support Word 97+).
I use Microsoft Word 2007 on my development machine. Ideally if I could get away with NOT installing Word97, that would be great.
In VB6 I tried to set a reference to C:\Software\Microsoft\Office97Pro\OFFICE\mso97.dll (path to software - not installed) but that didn't work. I then tried regsvr32 mso97.dll but that gave me the error: mso97.dll was loaded, but the DllRegisterServer entry point was not found.
Anyone know what I need to do to get this to work? Or will I need to install Word 97 on my machine for it to work?
It sounds like you basically want to do as suggested in Writing Automation clients for multiple Office versions but ignoring the advice about using late binding.
The type library involved is MSWORD8.OLB, but I can't recall whether there is any legitimate way to obtain it without Word 97 or an Office 97 Edition including Word. Offhand I'm not sure what the impact of registering this tylepib would have on your Word 2007 installation either, since they may well share many ClassID values.
In the VC++ article PRB: Automation of Office Using #import Can Fail if Multiple Versions of Office Are Installed Microsoft seems to suggest this can be a viable strategy as long as you reference the proper OLB. This is probably less of a problem for VB6 than in C++ because VB6 doesn't use the VC++ #import semantics for locating typelibs. Then again they may be referring to run-time behavior, since the explanation concludes by once more suggesting late binding.
The article WD: How to Obtain the Word for Windows Type Library offers links to the Word 6 and Word 7 typelibs (links may no longer be good) but none for Word 97, which they suggest you obtain by installing Word 97.
In any case it only sounds safe to use the constants, enums, etc. from Word 97 and use late binding for all of your objects. This "half a loaf" is better than nothing. You could still do your initial development with early-bound declarations to geet "Intellisense" assistance, then go back and change all of the early-bound object declarations to late-bound As Object and replacing Set X = New TYPE by the corresponding late-bound CreateObject() call, leaving the actual strong typing as a trailing comment. One could also use conditional compilation #If/#Else blocks to make flipping back to early binding easier later.
Since obtaining MSWORD8.OLB legitimately may be impossible today, you might also consider OFF: "Built-in Constants in Visual Basic for Applications" (WC0993) which offers a download containing VB .BAS modules defining the constants for many old versions of Word and other Office applications. The download link works - as of right now at least!
Since named constants are the primary reason for the typelibs (considering that only late binding is truly safe) this might not be a bad compromise. You can take the .BAS file you need, clean it up (bound to be some warts in there), and even convert it to a custom "Generic Word" TLB containing just those constants and enums with a little effort. For that matter somebody may already have done this work. I'd suggest you try a few searches before writing your own "VB .BAS to ODL/IDL" compiler though.
When adding a reference to your project, look for MS Word x.0 Object Library where x is the version of MS Word you want to work against. I believe you can reference a lower version than Word 2007 (version 12.0). Look for 8.0.
Our installed is occasionally detecting the wrong version of Windows. (It detects version via built in Wise installer function to detect System Info and doesn't say HOW it does this).
So, I'm looking for another way to detect the Windows version. The Wise installer is pretty limited in it's ability to call Windows API functions so reading from the Registry or a specific file would be easier (of course then I have to map the file version to the Windows version).
I found this discussion thread:
http://www.velocityreviews.com/forums/t513244-best-way-to-get-version-from-registry.html
But it had no citations. So I'm not sure how dependable it would be.
I understand you would rather not use the API, but if you don't trust what Wise gives you, it might be the only way to be sure:
GetVersionEx() http://msdn.microsoft.com/en-us/library/ms724451(v=VS.85).aspx
There is sample code (and many comments about alternate functions that might be closer to what you actually need) on the linked to page.
If you want a registry solution you can look at the key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion and check out the values for ProductVersion, CurrentVersion, CurrentBuild.
I need to guide me to lock my project against "unauthorized use" with a certain registration key which I will send it personally.
I also want to inform me if this lock method can break it with reverse engineer method.
I use visual basic for my project in visual studio 2010.
There is no general case method of preventing someone from reverse engineering your application. It is code, and therefore it is possible to analyze. This is exacerbated by tools such as Reflector, which take a .NET assembly and dump out a complete Visual Studio solution capable of building the given .NET assembly. A malicious user could simply dump your assembly, remove the licensing bits, and then recompile the assembly.
However, you can use a code obfuscation tool (i.e. Dotfuscator (disclaimer: PreEmptive Solutions is my employer)) to make your code confusing enough that it's extremely difficult to figure out where exactly the registration bits are located.
That said, merely obfuscating the code still doesn't protect you the way you're trying to be protected, because you want to embed a secret (that is, the registration code) in the binary. Code obfuscators can help with this (i.e. string encryption), but this is in general a weak area -- your program has to get the constant in cleartext at some point, therefore the method to get the cleartext must exist in your program somewhere. After all, there are cracks and things for Windows and pretty much every video game on the planet, despite the millions companies like Sony spend on anti-copying technology.
If you want to secure your project from re-engineering and reading then,
Try obfuscation for securing your application at CERTAIN level.
Product Key,
Before few months back our team was discussing about
"How to secure our Product from Illegal Copying,ReEng etc"
Following are the conclusions,
for re-eng - Obfuscation
Copying - Decided to create a Product key based on Some Client + Other Details(Harddisk#+BIOS#) and we maintained the separate database for it.
So its upto you,I mean how much you want to secure your application.
Since you mentioned that you will be separately sending product key then it can be any combination like CustomerName+Date etc.
Also some obfuscation tool provide the way to generate product key, don't remember the name.
I'm an application packager trying to make sense of how the COM registry keys (SelfReg) interrelate to the given .dll in Windows.
ProgID's, AppID's, TypeLibs, Extensions & Verbs are all tied around the CLSID right?
Do CLSID's always use Prog/App IDs or could you just have a file extension class?
Which bits are optional?
Some of it seems to be 'like a router' where there's the two interfaces (internal - .dll) and external (the extension etc).
How does this all fit? (The SDK documentation doesn't make sense to me)
I ask as this is all pivotal to application 'healing' with Windows Installer (which packagers are all 'big' on, but there's no nitty-gritty breakdowns since its a coder-thing really)
---Edit:
Am I safe in assuming that for what COM is registered, it must all link back to the CLSID and cannot be a 'dead-end'?
Verbs need extensions which need progid's...
What about the AppId's, TypeLibs and Interfaces? How do they interrelate?
The first thing to realise, is that COM dlls register themselves. They will put all the required entries into the correct places in the registry.
I think the answer to your central question about which bits are optional is probably that they are all optional for different types of objects. Automation objects require Prog/AppIDs if they are publicly creatable, but may not if they are only created internally, similarly a non- publicly creatable COM class can be listed.
Many COM objects that do not have automation interfaces (such as many of the COM classes microsoft uses internally in windows will not have any ProgId but will simply have an entry under their CLSID in HKCR\CLSID.
If I understand you correctly you are interested in this from a installer perspective. I would imagine that all you need do is ask the user to specify which dlls are selfregistering and then call
regsvr32 dllname.dll
or
exename.exe /Regserver
for a out of process server. If something goes wrong you just need to call the opposites.
regsvr32 /u dllname.dll
or
exename.exe /Unregserver
I hope that this answers your question.
I'd recommend the book Inside COM.
It wasn't the most up-to-date reference even during COM's heyday, but it explains the basics quite well, including all the registry goo. Plus, I bet you can get a used copy real cheap.
I know this isn't an answer, but remembering what the chapter about the registry looked like - a non-specific "how does it work" question will require a really, really long answer...
I used an answer cos the comments seem so limited. Not sure how SO will interpret this (maybe I'll be deemed mad for talking to myself?)
"how does it work" question will require a really, really long answer
Thanks - what I'm trying to acheive is an understanding of that without actually being a developer - this is because of the way packagers attempt to group the COM registry keys with the .dll (in the same component) so that application resiliency works.
This means 'trapping' the COM from the .dll's registration and associating it in the correct advertising tables (CLSID, AppID ...ad nauseum) to the component that holds the .dll. Sometimes this isn't easy to see and sometimes (I'm told) it can break the app from functioning. I'm told that the COM doesn't need to be complete (self-referential).
I'm still trying to get my head around it all.
Of course, if the packager captures all the information but doesn't associate the COM info to the .dll, the regkeys are still written at install-time, just the MSI doesn't baby-sit the application if things go wrong (which is almost never)