Jump to content

Windows NT 4.0 api wrapper


Recommended Posts

Hello everyone, in the last past few months I have been working on a windows nt 4.0 api wrapper which can run softwares designed for new windows's version. I'm writing the functions in inline assembly (I'm using ida) and C. (There is also some code from reactos and wine). There are some issues with certain softwares, some don't load at all and some crash, so I can't release nothing for now. What are some software you use and you want to run on it? List me and I will try to get them work. Unfortunately firefox (the 3.5 version and newer), opera 12.18 and utorrent don't load even if I added the missing functions... They don't throw me any error, they simply don't load at all... Maybe I have to do something. I will investigate.

Here, there are some software that load.

Filezilla 3.8.1 (last version crashes, but I think I will be able to get it work)

6AAGYBm.png

vlc 2.2.0

MLQzoRW.png

last version of 7-zip

05HMzKL.png

last version of Sumatra (it's a little buggy but it reads pdf).

0Yjxe9S.png

  VLKv6Xq.png  

Link to comment
Share on other sites


List of software I would recommend

-Google Chrome 13 or earlier, maybe experiment with BWC's older Chrome tool. Apparently this once even worked on 9x w/ KernelEx, sadly it's unknown which version allowed Google Chrome to run and which version.
-Dooble Browser 1.4.0 (Last version working with w2k, Qt4 based)
-Qupzilla 1.6.6 or earlier (Qt4)

Link to comment
Share on other sites

6 hours ago, roytam1 said:

Thats nice, looks promising. :)

Thanks, I hope I will be able to release something soon.

2 hours ago, ~♥Aiko♥Chan♥~ said:

List of software I would recommend

-Google Chrome 13 or earlier, maybe experiment with BWC's older Chrome tool. Apparently this once even worked on 9x w/ KernelEx, sadly it's unknown which version allowed Google Chrome to run and which version.
-Dooble Browser 1.4.0 (Last version working with w2k, Qt4 based)
-Qupzilla 1.6.6 or earlier (Qt4)

Ok I will try to get them work.

EDIT: I have tried Qupzilla 1.6.6 for now and it loads,although the characters are a little messy (I will work on it in these days) .

RF4nzQ9.png

Edited by junior600
Link to comment
Share on other sites

2 hours ago, junior600 said:

Thanks, I hope I will be able to release something soon.

Ok I will try to get them work.

EDIT: I have tried Qupzilla 1.6.6 for now and it loads,although the characters are a little messy (I will work on it in these days) .

RF4nzQ9.png

Seems font width measuring API returning 0 here. This happens when I port QtWeb to NT4.

BTW will you do the same for but NT 3.51? It seems more interesting (and challenging, as missing Winsock2)

Edited by roytam1
Link to comment
Share on other sites

2 hours ago, Dibya said:

roytam1 you may help him regarding the api

Keep working . Best of luck .

It is different approach here.

For porting Qt4 back to NT4, I dug older version of Qt and find add back removed logic for older windows(NT4 and 95 here).

For Example:

diff -u5rwB --exclude=Makefile --exclude='Makefile.*' --exclude='*.prl' qt-everywhere-opensource-src-4.8.5/src/gui/text/qfontengine_win.cpp QtWeb/src/qt/src/gui/text/qfontengine_win.cpp
--- qt-everywhere-opensource-src-4.8.5/src/gui/text/qfontengine_win.cpp	2013-06-07 08:17:00.000000000 +0800
+++ QtWeb/src/qt/src/gui/text/qfontengine_win.cpp	2013-06-19 11:30:42.627875000 +0800
@@ -398,10 +398,23 @@
 #if defined(Q_WS_WINCE)
     GetCharWidth32(hdc, glyph, glyph, &width);
 #else
     if (ptrGetCharWidthI)
         ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
+    else {
+        GLYPHMETRICS gm;
+        DWORD res = GDI_ERROR;
+        MAT2 mat;
+        mat.eM11.value = mat.eM22.value = 1;
+        mat.eM11.fract = mat.eM22.fract = 0;
+        mat.eM21.value = mat.eM12.value = 0;
+        mat.eM21.fract = mat.eM12.fract = 0;
+        res = GetGlyphOutline(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX|GGO_NATIVE, &gm, 0, 0, &mat);
+        if (res != GDI_ERROR) {
+            width = gm.gmCellIncX;
+        }
+    }
 #endif
 }
 
 void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
 {
@@ -651,11 +664,11 @@
         0
 };
 
 static const int char_table_entries = sizeof(char_table)/sizeof(ushort);
 
-#ifndef Q_CC_MINGW
+#if 0
 void QFontEngineWin::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
 {
     HDC hdc = shared_dc();
     SelectObject(hdc, hfont);
 
diff -u5rwB --exclude=Makefile --exclude='Makefile.*' --exclude='*.prl' qt-everywhere-opensource-src-4.8.5/src/gui/text/qfontengine_win_p.h QtWeb/src/qt/src/gui/text/qfontengine_win_p.h
--- qt-everywhere-opensource-src-4.8.5/src/gui/text/qfontengine_win_p.h	2013-06-07 08:17:00.000000000 +0800
+++ QtWeb/src/qt/src/gui/text/qfontengine_win_p.h	2013-06-18 18:25:51.918125000 +0800
@@ -106,11 +106,11 @@
     virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
     virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
 
     virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
 
-#ifndef Q_CC_MINGW
+#if 0
     virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
 #endif
 
     int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const;
     void getCMap();

And what junior600 has to do is that, adding missing API into wrapper so newer programs can run on NT4.

Edited by roytam1
Link to comment
Share on other sites

7 hours ago, roytam1 said:

Seems font width measuring API returning 0 here. This happens when I port QtWeb to NT4.

BTW will you do the same for but NT 3.51? It seems more interesting (and challenging, as missing Winsock2)

56 minutes ago, roytam1 said:

It is different approach here.

For porting Qt4 back to NT4, I dug older version of Qt and find add back removed logic for older windows(NT4 and 95 here).

For Example:


diff -u5rwB --exclude=Makefile --exclude='Makefile.*' --exclude='*.prl' qt-everywhere-opensource-src-4.8.5/src/gui/text/qfontengine_win.cpp QtWeb/src/qt/src/gui/text/qfontengine_win.cpp
--- qt-everywhere-opensource-src-4.8.5/src/gui/text/qfontengine_win.cpp	2013-06-07 08:17:00.000000000 +0800
+++ QtWeb/src/qt/src/gui/text/qfontengine_win.cpp	2013-06-19 11:30:42.627875000 +0800
@@ -398,10 +398,23 @@
 #if defined(Q_WS_WINCE)
     GetCharWidth32(hdc, glyph, glyph, &width);
 #else
     if (ptrGetCharWidthI)
         ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
+    else {
+        GLYPHMETRICS gm;
+        DWORD res = GDI_ERROR;
+        MAT2 mat;
+        mat.eM11.value = mat.eM22.value = 1;
+        mat.eM11.fract = mat.eM22.fract = 0;
+        mat.eM21.value = mat.eM12.value = 0;
+        mat.eM21.fract = mat.eM12.fract = 0;
+        res = GetGlyphOutline(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX|GGO_NATIVE, &gm, 0, 0, &mat);
+        if (res != GDI_ERROR) {
+            width = gm.gmCellIncX;
+        }
+    }
 #endif
 }
 
 void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
 {
@@ -651,11 +664,11 @@
         0
 };
 
 static const int char_table_entries = sizeof(char_table)/sizeof(ushort);
 
-#ifndef Q_CC_MINGW
+#if 0
 void QFontEngineWin::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
 {
     HDC hdc = shared_dc();
     SelectObject(hdc, hfont);
 
diff -u5rwB --exclude=Makefile --exclude='Makefile.*' --exclude='*.prl' qt-everywhere-opensource-src-4.8.5/src/gui/text/qfontengine_win_p.h QtWeb/src/qt/src/gui/text/qfontengine_win_p.h
--- qt-everywhere-opensource-src-4.8.5/src/gui/text/qfontengine_win_p.h	2013-06-07 08:17:00.000000000 +0800
+++ QtWeb/src/qt/src/gui/text/qfontengine_win_p.h	2013-06-18 18:25:51.918125000 +0800
@@ -106,11 +106,11 @@
     virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
     virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
 
     virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
 
-#ifndef Q_CC_MINGW
+#if 0
     virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
 #endif
 
     int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const;
     void getCMap();

And what junior600 has to do is that, adding missing API into wrapper so newer programs can run on NT4.

Thanks, for example qupzilla 1.6.6 requires only a missing function in gdi32 (GetCharABCWidthI) and for now I have redirected it to GetCharABCWidthW. I'm going to write the function and see if it will change something. BTW yes I have a plan to do something even for windows NT 3.51 in the future, but for now I will focus on windows NT 4.0 ;)

Link to comment
Share on other sites

1 hour ago, junior600 said:

Thanks, for example qupzilla 1.6.6 requires only a missing function in gdi32 (GetCharABCWidthI) and for now I have redirected it to GetCharABCWidthW. I'm going to write the function and see if it will change something. BTW yes I have a plan to do something even for windows NT 3.51 in the future, but for now I will focus on windows NT 4.0 ;)

Great, that will be fun :)

BTW in NT4 MsgWaitForMultipleObjectsEx() API doesn't accept MWMO_INPUTAVAILABLE flag, which may cause problems with Qt4 programs.

I patched Qt4 with some changes in order to made it work in NT4:

diff -u5rwB --exclude=Makefile --exclude='Makefile.*' --exclude='*.prl' qt-everywhere-opensource-src-4.8.5/src/corelib/kernel/qeventdispatcher_win.cpp QtWeb/src/qt/src/corelib/kernel/qeventdispatcher_win.cpp
--- qt-everywhere-opensource-src-4.8.5/src/corelib/kernel/qeventdispatcher_win.cpp	2013-06-07 08:16:52.000000000 +0800
+++ QtWeb/src/qt/src/corelib/kernel/qeventdispatcher_win.cpp	2013-06-26 20:58:22.064500000 +0800
@@ -810,11 +810,11 @@
 
                 if (!filterEvent(&msg)) {
                     TranslateMessage(&msg);
                     DispatchMessage(&msg);
                 }
-            } else if (waitRet < WAIT_OBJECT_0 + nCount) {
+            } else if (waitRet >= WAIT_OBJECT_0 && waitRet < WAIT_OBJECT_0 + nCount) {
                 d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0));
             } else {
                 // nothing todo so break
                 break;
             }
@@ -830,13 +830,13 @@
             Q_ASSERT(nCount < MAXIMUM_WAIT_OBJECTS - 1);
             for (int i=0; i<(int)nCount; i++)
                 pHandles[i] = d->winEventNotifierList.at(i)->handle();
 
             emit aboutToBlock();
-            waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
+            waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE);
             emit awake();
-            if (waitRet < WAIT_OBJECT_0 + nCount) {
+            if (waitRet >= WAIT_OBJECT_0 && waitRet < WAIT_OBJECT_0 + nCount) {
                 d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0));
                 retVal = true;
             }
         }
     } while (canWait);
Edited by roytam1
Link to comment
Share on other sites

33 minutes ago, ~♥Aiko♥Chan♥~ said:

For Vanilla NT 4 (If you ever need to browse the internet on NT 4 for any reason)
The most suitable modern web browser for a Vanilla NT 4 is QTWeb 3.8.4

Here's something to resolve programs which won't display errors despite not working, ImportPatcher.41

Thats me ;)

Link to comment
Share on other sites

6 hours ago, ~♥Aiko♥Chan♥~ said:

For Vanilla NT 4 (If you ever need to browse the internet on NT 4 for any reason)
The most suitable modern web browser for a Vanilla NT 4 is QTWeb 3.8.4

Here's something to resolve programs which won't display errors despite not working, ImportPatcher.41

Well, I have tried ImportPatcher but it still doesn't work.There are no missing functions because I have added the missing ones. I think I need to update some existing functions like windows 98's kernelex does. I will work to it in these days. Yes, for now the best browser we can use is QtWeb 3.8.4 until I will be able to load the other browsers ;)

Edited by junior600
Link to comment
Share on other sites

4 minutes ago, Dibya said:

Well opera 12. 18 will be great

Yes, I'm going to get it work. BTW I have a question to people who are using windows 2000 with the last blackwingcat's kernel... Does qbittorrent 3.3.12 (last version) work? It loads on windows NT 4.0 but it hangs to the first screen "legal information". I read somewhere that QT5 isn't compatible even with windows 2000, is it true? Tracing the error with ollydbg, it says me "CreateWindow() for QEventDispatcherWin32 internal window failed".

Edited by junior600
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...