Best windows questions in December 2011

Python HTTPS against Azure service management API fails on Windows

12 votes

I've recently extended a Python API for the Windows Azure storage APIs (PyAzure) to include support for the service management APIs. See https://github.com/bmb/pyazure.

I'm using a HTTPSClientAuthHandler like the one suggested in using pyOpenSSL to create urllib custom opener. On Linux, with various versions of Python 2.6 and 2.7 this works well. However, Windows is another story. All requests against the Azure management host address fail with:

[Errno 10054] An existing connection was forcibly closed by the remote host

Which I think, is the socket errno 10054 "Connection reset by peer", in drag.

This doesn't appear to be a problem in my API code (unless the client cert authentication method I'm using is bogus somehow), but something lower-level. I can reproduce the issue without urllib2 or httplib by simply setting up an SSL socket and sending the same HTTP request down the pipe as urllib2 would, e.g. to list the valid Azure data centre locations:

>>> import socket, ssl, sys
>>> sys.version
'2.7.1 (r271:86832, Nov 27 2010, 17:19:03) [MSC v.1500 64 bit (AMD64)]'

>>> s = ssl.wrap_socket(socket.socket(), certfile='c:\\users\\blair\\research\\clouds\\azure\\BlairBethwaiteAzure1.pfx.pem')
>>> s.connect(('management.core.windows.net',443))
>>> s.send("GET /SUBSCRIPTION_ID/locations HTTP/1.1\r\nAccept-Encoding: identity\r\nX-Ms-Version: 2011-10-01\r\nHost: management.core.windows.net\r\nConnection: close\r\nUser-Agent: Python-urllib/2.6\r\n\r\n")
202

>>> s.read()
Traceback (most recent call last):
c:\Users\blair\research\clouds\azure\pyazure\<ipython-input-63-3306c981d8a7>
in <module>()
----> 1 s.read()

C:\Python27\lib\ssl.pyc in read(self, len)
   136
   137         try:
--> 138             return self._sslobj.read(len)
   139         except SSLError, x:
   140             if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:


error: [Errno 10054] An existing connection was forcibly closed by the remote host

Replace SUBSCRIPTION_ID above, with your Azure subscription ID. The exception is raised ~45s after calling SSLSocket.read. The cert is a properly formatted PEM file including both the private key and certificate, it was converted from the pfx (in Ubuntu 10.04) using:

openssl pkcs12 -in pfxfile -out pemfile -nodes

I don't think it matters here, but I also tried unix2dos-ing the PEM file, to no avail though. I get the same behaviour even when I don't provide any cert, but doing that on Linux results in a proper API error from the server:

'HTTP/1.1 403 Forbidden\r\nContent-Length: 0\r\nServer: Microsoft-HTTPAPI/2.0\r\nDate: Thu, 01 Dec 2011 13:59:29 GMT\r\nConnection: close\r\n\r\n'

This has been independently verified by another person using Windows 7 (same as me). It's not a client-side firewall issue - the same code works in a NAT-ed Linux VM running on the same host.

I'm stumped. Would really appreciate any help folks here might be able to provide...

Update: This appears to be related to the underlying SSL implementation in Python. CPython 2.7.1 has the error behaviour as shown above, but I've since tested and had success with ActiveState Python (both 2.7 and 2.6), e.g.:

>>> import sys, socket, ssl
>>> sys.version
'2.7.1 (r271:86832, Feb  7 2011, 11:30:38) [MSC v.1500 32 bit (Intel)]'
>>> s = ssl.wrap_socket(socket.socket(), certfile='\\\\VBOXSVR\\azure\\BlairBethwaiteAzure1.pfx.pem')
>>> s.connect(('management.core.windows.net',443))
>>> s.send('GET /SUBSCRIPTION_ID/locations HTTP/1.1\r\nAccept-Encoding: identity\r\nX-Ms-Version: 2011-10-01\r\nHost: management.core.windows.net\r\nUser-Agent: Python-urllib/2.6\r\n\r\n')
183

>>> s.read(4096)
'HTTP/1.1 200 OK\r\nContent-Length: 908\r\nContent-Type: application/xml; charset=utf-8\r\nServer: Microsoft-HTTPAPI/2.0\r\nx-ms-request-id: 08ca048cda6b445da6b3a8f3e4890197\r\nDate: Fri, 02 Dec 2011 03:02:14 GMT\r\n\r\n<Locations xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Location><Name>Anywhere US</Name><DisplayName>Anywhere US</DisplayName></Location><Location><Name>South Central US</Name><DisplayName>South Central US</DisplayName></Location><Location><Name>North Central US</Name><DisplayName>North Central US</DisplayName></Location><Location><Name>Anywhere Europe</Name><DisplayName>Anywhere Europe</DisplayName></Location><Location><Name>North Europe</Name><DisplayName>North Europe</DisplayName></Location><Location><Name>West Europe</Name><DisplayName>West Europe</DisplayName></Location><Location><Name>Anywhere Asia</Name><DisplayName>Anywhere Asia</DisplayName></Location><Location><Name>Southeast Asia</Name><DisplayName>Southeast Asia</DisplayName></Location><Location><Name>East Asia</Name><DisplayName>East Asia</DisplayName></Location></Locations>'

And as expected my API works too:

ActivePython 2.6.7.20 (ActiveState Software Inc.) based on
Python 2.6.7 (r267:88850, Jun 27 2011, 13:20:48) [MSC v.1500 64 bit (AMD64)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyazure import pyazure
>>> pa = pyazure.PyAzure(subscription_id=SUBSCRIPTION_ID, management_cert_path='c:\\users\\blair\\research\\clouds\\azure\\BlairBethwaiteAzure1.pfx.pem')
>>> list(pa.wasm.list_locations())
['Anywhere US', 'South Central US', 'North Central US', 'Anywhere Europe', 'North Europe', 'West Europe', 'Anywhere Asia', 'Southeast Asia', 'East Asia']

The Lib\ssl.py files in CPython2.7 and ActivePython2.7 are identical, so I guess this must be due to some difference in the underlying C libs, perhaps a bug in CPython. Any gurus out there?

I haven't been able to pin down a definitive explanation for this, but after a bit of trial and error I'm confident of where the issue lays...

Short answer: it's the ssl implementation in the http://www.python.org/ Windows bundle. Use ActiveState Python instead.

Long Answer: The Windows CPython distributions available from http://www.python.org/download/ bundle quite an old version of OpenSSL (0.9.8l), compared with the ActiveState Python distributions which are based on CPython but (amongst other things) provide regular updates to 3rd party inclusions such as OpenSSL (currently 0.9.8r).

I downloaded Windows binaries of OpenSSL and tested via the openssl s_client interface, e.g.:

openssl s_client -connect management.core.windows.net:443 -cert /home/blair/nimrod-dev/BlairBethwaiteAzure1.pfx.pem

The current version works, as expected. Unfortunately it seems difficult to get one's hands on old OpenSSL binaries for Windows, perhaps not surprising given it is a security library... But anyway, I built 0.9.8l from source under Ubuntu 10.04 and found that it hangs after sending a HTTP request down the pipe, presumably the server silently dropped the connection for some reason:

blair@venus-vm:~/Downloads/openssl-0.9.8l/apps$ ./openssl s_client -connect management.core.windows.net:443 -cert ./BlairAzure.pem 
CONNECTED(00000003)
depth=2 /CN=Microsoft Internet Authority
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/CN=management.core.windows.net
   i:/DC=com/DC=microsoft/DC=corp/DC=redmond/CN=Microsoft Secure Server Authority
 1 s:/DC=com/DC=microsoft/DC=corp/DC=redmond/CN=Microsoft Secure Server Authority
   i:/CN=Microsoft Internet Authority
 2 s:/CN=Microsoft Internet Authority
   i:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGhDCCBWygAwIBAgIKFnL3ogAIAAIjlDANBgkqhkiG9w0BAQUFADCBizETMBEG
CgmSJomT8ixkARkWA2NvbTEZMBcGCgmSJomT8ixkARkWCW1pY3Jvc29mdDEUMBIG
CgmSJomT8ixkARkWBGNvcnAxFzAVBgoJkiaJk/IsZAEZFgdyZWRtb25kMSowKAYD
VQQDEyFNaWNyb3NvZnQgU2VjdXJlIFNlcnZlciBBdXRob3JpdHkwHhcNMTEwNjE2
MDg0MjI3WhcNMTMwNjE1MDg0MjI3WjAmMSQwIgYDVQQDExttYW5hZ2VtZW50LmNv
cmUud2luZG93cy5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCS
Z9PTUqQLh5keX/IRJ6JxaQkVBIy/iyoCIx2Y0zy5F5tll8CRydGzFDjXMLWEG425
EuuRDQrBgQnmVtlZ2t42QfIRBSvfJheZVh8k27g/tH5wpchZ47gxxatUKsVJ84P8
Me2S0RP9xtk3P14dVqTDJIhUC3k8JYdBiTTtk64EB5Dbq8sxEtjVb/68XDgTZKek
te/vqWSW/KcduKEjsfjOwNSM9UbYrFOTbelac+mf/L+CluAJpYAlIhOMUP2afy5e
tYIg6zK04pDNjPjizpfN3xrGX7NRY16kaafrdqJQixfmEVlMDN8FsXLWDweXWfMM
XRh4vuAVb6tA9wBkPDhZAgMBAAGjggNMMIIDSDALBgNVHQ8EBAMCBLAwHQYDVR0l
BBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMHgGCSqGSIb3DQEJDwRrMGkwDgYIKoZI
hvcNAwICAgCAMA4GCCqGSIb3DQMEAgIAgDALBglghkgBZQMEASowCwYJYIZIAWUD
BAEtMAsGCWCGSAFlAwQBAjALBglghkgBZQMEAQUwBwYFKw4DAgcwCgYIKoZIhvcN
AwcwHQYDVR0OBBYEFEaKqx6Auvu3fvHS6KqQl8KXoOoAMB8GA1UdIwQYMBaAFAhC
49tOEWbztQjFQNtVfDNGEYM4MIIBCgYDVR0fBIIBATCB/jCB+6CB+KCB9YZYaHR0
cDovL21zY3JsLm1pY3Jvc29mdC5jb20vcGtpL21zY29ycC9jcmwvTWljcm9zb2Z0
JTIwU2VjdXJlJTIwU2VydmVyJTIwQXV0aG9yaXR5KDgpLmNybIZWaHR0cDovL2Ny
bC5taWNyb3NvZnQuY29tL3BraS9tc2NvcnAvY3JsL01pY3Jvc29mdCUyMFNlY3Vy
ZSUyMFNlcnZlciUyMEF1dGhvcml0eSg4KS5jcmyGQWh0dHA6Ly9jb3JwcGtpL2Ny
bC9NaWNyb3NvZnQlMjBTZWN1cmUlMjBTZXJ2ZXIlMjBBdXRob3JpdHkoOCkuY3Js
MIG/BggrBgEFBQcBAQSBsjCBrzBeBggrBgEFBQcwAoZSaHR0cDovL3d3dy5taWNy
b3NvZnQuY29tL3BraS9tc2NvcnAvTWljcm9zb2Z0JTIwU2VjdXJlJTIwU2VydmVy
JTIwQXV0aG9yaXR5KDgpLmNydDBNBggrBgEFBQcwAoZBaHR0cDovL2NvcnBwa2kv
YWlhL01pY3Jvc29mdCUyMFNlY3VyZSUyMFNlcnZlciUyMEF1dGhvcml0eSg4KS5j
cnQwPwYJKwYBBAGCNxUHBDIwMAYoKwYBBAGCNxUIg8+JTa3yAoWhnwyC+sp9geH7
dIFPg8LthQiOqdKFYwIBZAIBCjAnBgkrBgEEAYI3FQoEGjAYMAoGCCsGAQUFBwMC
MAoGCCsGAQUFBwMBMCYGA1UdEQQfMB2CG21hbmFnZW1lbnQuY29yZS53aW5kb3dz
Lm5ldDANBgkqhkiG9w0BAQUFAAOCAQEAsqHBR/JxRnGQMTXxJzCau49dDgeum1JH
heA38lzsoUaRELHxxrQZskjSqc0HrI7cnJPSipWQseDDwKtLwXzukCdZNk84u7xo
uHa7/dmxo1m+z353HSvEr85ZE2mzwF6qmwGMmvvVzIJ94M8fcN55yoF64vQsAWFF
k2QJC9ccb8eDoTs5NX4ntpz02xf8eEBQ5yKZySfi3+oFJEUnLmXcvHTTMl/1N/NI
fWiKIZ9PDTBlPxL5kNJ/aDGIgiqCi7Vm7KfjvWSFhopUPtVeeItgW9wMLEkuQsw6
sViSbU50CMPWTJAslLZgCju6cxszgpLl19xrgNteHRw2HouwTTsJnA==
-----END CERTIFICATE-----
subject=/CN=management.core.windows.net
issuer=/DC=com/DC=microsoft/DC=corp/DC=redmond/CN=Microsoft Secure Server Authority
---
No client certificate CA names sent
---
SSL handshake has read 4691 bytes and written 450 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES128-SHA
    Session-ID: <SNIP>
    Session-ID-ctx: 
    Master-Key: <SNIP>
    Key-Arg   : None
    Start Time: 1324443511
    Timeout   : 300 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
---
GET /<SUBSCRIPTION_ID>/locations HTTP/1.1
Accept-Encoding: identity
X-Ms-Version: 2011-10-01
Host: management.core.windows.net
Connection: close

Under newer and even slightly older (e.g., Ubuntu10.04's 0.9.8e) OpenSSLs the server responds to the request with the expected:

<Locations xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Location><Name>Anywhere US</Name><DisplayName>Anywhere US</DisplayName></Location><Location><Name>South Central US</Name><DisplayName>South Central US</DisplayName></Location><Location><Name>Anywhere Europe</Name><DisplayName>Anywhere Europe</DisplayName></Location><Location><Name>West Europe</Name><DisplayName>West Europe</DisplayName></Location><Location><Name>Anywhere Asia</Name><DisplayName>Anywhere Asia</DisplayName></Location><Location><Name>Southeast Asia</Name><DisplayName>Southeast Asia</DisplayName></Location><Location><Name>East Asia</Name><DisplayName>East Asia</DisplayName></Location><Location><Name>North Central US</Name><DisplayName>North Central US</DisplayName></Location><Location><Name>North Europe</Name><DisplayName>North Europe</DisplayName></Location></Locations>

But with OpenSSL 0.9.8l I get nothing.

Programmatically determine user who last modified file on Windows?

8 votes

I've been tasked with writing a simple command line utility in C# that will monitor a directory on a server that several users will be accessing to copy/cut/paste/view data. I used FileSystemWatcher to do this but it's lacking a couple features.

Is it possible to determine the user or at least the computer name from where the file is being accessed/modified?

(Note: This doesn't have to be with FileSystemWatcher, I'm looking for ANY way to do this.)

I don't think you'll be able to monitor this from C# directly. Not without the help of the host operating system anyway. Windows and NTFS allow you to audit a particular directory and log the accesses in the Security event log for the host machine (so the server hosting the share would have to audit, not the client).

From KB310399 - How to audit user access of files, folders, and printers in Windows XP

Auditing User Access of Files, Folders, and Printers

The audit log appears in the Security log in Event Viewer. To enable this feature:

  1. Click Start, click Control Panel, click Performance and Maintenance, and then click Administrative Tools.
  2. Double-click Local Security Policy.
  3. In the left pane, double-click Local Policies to expand it.
  4. In the left pane, click Audit Policy to display the individual policy settings in the right pane.
  5. Double-click Audit object access.
  6. To audit successful access of specified files, folders and printers, select the Success check box.
  7. To audit unsuccessful access to these objects, select the Failure check box.
  8. To enable auditing of both, select both check boxes.
  9. Click OK.

Specifying Files, Folders, and Printers to Audit

After you enable auditing, you can specify the files, folders, and printers that you want audited. To do so:

  1. In Windows Explorer, locate the file or folder you want to audit. To audit a printer, locate it by clicking Start, and then clicking Printers and Faxes.
  2. Right-click the file, folder, or printer that you want to audit, and then click Properties.
  3. Click the Security tab, and then click Advanced.
  4. Click the Auditing tab, and then click Add.
  5. In the Enter the object name to select box, type the name of the user or group whose access you want to audit. You can browse the computer for names by clicking Advanced, and then clicking Find Now in the Select User or Group dialog box.
  6. Click OK.
  7. Select the Successful or Failed check boxes for the actions you want to audit, and then click OK.
  8. Click OK, and then click OK.

The process is similar for the server operating systems and Windows Vista/Windows 7. If you go this route, you can have the C# program read the event log (See EventLog class) to look for the data you want.

Note: Starting with vista you must be and (UAC elevated if needed) administrator to read them from code.

What's the purpose of registering window classes?

7 votes

What's the purpose of registering a window class via WNDCLASSEX and RegisterClassEx() when creating a window in a Windows API application?

The separation of window attributes into CreateWindow() stuff and RegisterClass() stuff was done early on to enable the creation of uniformly-behaving windows. Dialog controls (buttons, listboxes, etc.) are a prime example - they all share a class. That means - they share a window procedure, that means - they share painting logic, input reactions, custom messages, notifications, etc.

On the app level, the most typical case when you have many windows of the same class is documents within a multiple-document interface. Sometimes people introduce app-specific controls. So the distinction serves its purpose.

How can I play a single tone or custom wave with Delphi?

6 votes

I looked up some code, seems like everything is creating some math function waves, but I want to a single tone, or a custom wave made with custom single tones.

I read this How can I generate continuous tones of varying frequencies?

Which is close to my answer. Assumin I'm gonna use waveOutWrite like in the above link, I can't seem to figure out how the amp/freq is calculated for each Sample in HWAVEOUT.

In the code from the link It's done like this: Samples[i] := round(vol*sin(omega*t));

Assuming I want a 15kHz freq single tone with some amp (does not matter which), how would a Sample[1] be calculated?

A continuous (in time) sine wave can be defined as A*sin(2*PI*f*t), where A is some amplitude, PI is, well, 3.14..., f is the tone frequency in Hertz and t is time in seconds.

Now, since you don't have continuous time, since your time is discrete, you substitute dt*i in place of t and get A*sin(2*PI*f*dt*i), where dt is the time between samples or 1/sample rate and i is the sample number. You can spell it out as A*sin(2*PI*(f/Fs)*i). Beware that once you choose a certain sample rate Fs (in samples/second or simply Hz), the highest tone can never be greater than Fs/2 Hz.

How to get application's Windows taskbar button to show progress of progress bar

6 votes

One of the features introduced in Windows 7 (or was it Vista?) is the capability of the taskbar button of an application to show the progress of a progress bar in that application. When I create a form and place a progress bar on it, it doesn't show up in the taskbar button, so I assume this isn't done automatically. How can I get Windows 7 to show the progress of a progress bar on the application's taskbar button?

It can be easily accomplished using the ITaskList3 COM Interface.

For using it in Delphi check the following link: Fun with the Windows 7 Taskbar

Also Check this link for complete article describing the features provided by ITaskList3 Windows 7: How to display progress bar on taskbar icon?

How to follow a .lnk file programmatically

6 votes

We have a network drive full of shortcuts (.lnk files) that point to folders and I need to traverse them programmatically in a C# Winforms app.

What practical options do I have?

Add IWshRuntimeLibrary as a reference to your project. Add Reference, COM tab, Windows Scripting Host Object Model.

Here is how I get the properties of a shortcut:

IWshRuntimeLibrary.IWshShell wsh = new IWshRuntimeLibrary.WshShellClass();
IWshRuntimeLibrary.IWshShortcut sc = (IWshRuntimeLibrary.IWshShortcut)wsh.CreateShortcut(filename);

The shortcut object "sc" has a TargetPath property.

Signed zero linux vs windows

5 votes

i am running a program in c++ on windows and on linux. the output is meant to be identical. i am trying to make sure that the only differences are real differences oppose to working inviorment differences. so far i have taken care of all the differences that can be caused by \r\n differences but there is one thing that i can't seem to figure out.

in the windows out put there is a 0.000 and in linux it is -0.000

does any one know what can it be that is making the difference?

thanx

Since in the IEEE floating point format the sign bit is separate from the value, you have two different values of 0, a positive and a negative one. In most cases it doesn't make a difference; both zeros will compare equal, and they indeed describe the same mathematical value (mathematically, 0 and -0 are the same). Where the difference can be significant is when you have underflow and need to know whether the underflow occurred from a positive or from a negative value. Also if you divide by 0, the sign of the infinity you get depends on the sign of the 0 (i.e. 1/+0.0 give +Inf, but 1/-0.0 gives -Inf). In other words, most probably it won't make a difference for you.

Note however that the different output does not necessarily mean that the number itself is different. It could well be that the value in Windows is also -0.0, but the output routine on Windows doesn't distinguish between +0.0 and -0.0 (they compare equal, after all).

How to get fully qualified domain name on windows in Delphi

5 votes

I need to get in Delphi a fully qualified domain name for a windows machine on a domain.

I've tried to use LookupAccountSid but it gives me only netbios domain name, in my case it is "intranet" but I need full "intranet.companyname.com"

Any Ideas?

Try the GetUserNameEx Windows API function.

const
  NameUnknown            = 0;
  NameFullyQualifiedDN   = 1;
  NameSamCompatible      = 2;
  NameDisplay            = 3;
  NameUniqueId           = 6;
  NameCanonical          = 7;
  NameUserPrincipal      = 8;
  NameCanonicalEx        = 9;
  NameServicePrincipal   = 10;
  NameDnsDomain          = 12;

function GetUserNameExString(ANameFormat: DWORD): string;
var
  Buf: array[0..256] of Char;
  BufSize: DWORD;
  GetUserNameEx: function (NameFormat: DWORD; lpNameBuffer: LPSTR;
    var nSize: ULONG): BOOL; stdcall;
begin
  Result := '';
  BufSize := SizeOf(Buf) div SizeOf(Buf[0]);
  GetUserNameEx := GetProcAddress(GetModuleHandle('secur32.dll'), 'GetUserNameExA');
  if Assigned(GetUserNameEx) then
    if GetUserNameEx(ANameFormat, Buf, BufSize) then
      Result := Buf;
end;

using the NameDnsDomain format for example, will result www.mydomain.com\user_name if you are logged into "www.mydomain.com" domain.

MySQL language bindings for D?

5 votes

Are there any existing, working MySQL language bindings for D (particularly D 2.0 under Windows) still being maintained, updated, or even remotely poked at? Dozens of google searches mostly only point to some code previously hosted at http://www.steinmole.de/d/ by one Manfred Hansen, but this site is now dead and no mirrored copies seem to exist anywhere.

I did manage to find this: http://code.google.com/p/mysql4d/ as well as another project called DDBI that apparently only works with D 1.0 and Tango. I am having trouble linking these, though.. more google searches indicate that I need to convert the libmysql.dll included with MySQL to a libmysql.lib using implib.exe, however the program seems to be failing for me:

>implib.exe /system libmysql.lib libmysql.dll     
Digital Mars Import Library Manager Version 7.6B1n
Copyright (C) Digital Mars 2000.  All Rights Reserved.
Error(10): Error: cannot read DLL input file

A google search for "cannot read DLL input file" reveals utter horror: zero results. Am I doing something completely wrong, or do I have some version of MySQL whose DLL can no longer be converted?

Versions:

DMD32 D Compiler v2.056
MySQL Ver 14.14 Distrib 5.5.8, for Win64 (x86)

There are several MySQL bindings, starting with this one: https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff/blob/master/mysql.d

But (IMHO) the most promising project is the native D implementation of the MySQL protocol. It can be found here: https://github.com/britseye .

For the one you tried above, you need the COFFIMPLIB tool to create an OMF version of the MySQL library libmysql.lib from the one distributed with MySQL for the libmySQL.dll file.