Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8850945
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T13:01:11+00:00 2026-06-14T13:01:11+00:00

I need to use GetVolumeInformationW . For reasons uknown, I decided to load Kernel32.dll

  • 0

I need to use GetVolumeInformationW. For reasons uknown, I decided to load Kernel32.dll dynamically, resolve function address at runtime… Result is memory corruption problem and some strange side-effects of modifying stack. Though static version works like a charm and I can just stick with it and move on, I want to investigate the matter.

Source code is self-explaining (comment if you need some more information, full version can be found here):

#include <QtDebug>
#include <QByteArray>
#include <QLibrary>
#include <QDir>

static inline QString LAT1(const char *str, const int len = -1) {
    return QString::fromLatin1(str, len);
}

template <typename T>
static inline QByteArray createByteArray(const T *from, const int numElements) {
    return QByteArray(reinterpret_cast<const char*>(from), sizeof(T) * numElements);
}

// This one resolves functions from Kernel32.dll dynamically and uses standard types.
// (Dynamic linking.)
QByteArray fingerprintDynamic() {
    const uint32_t kMaxPath = 260 + 1;  // MAX_PATH + 1
    wchar_t path[kMaxPath]       = {0};
    wchar_t name[kMaxPath]       = {0};
    wchar_t fileSystem[kMaxPath] = {0};
    uint32_t serial = 0;
    uint32_t maximumComponentLength = 0;
    uint32_t fileSystemFlags = 0;

    QLibrary kernel32("kernel32");
    typedef uint32_t (*fnGetLastError)(void);
    typedef bool (*fnGetVolumeInformationW)(const wchar_t*, wchar_t*, uint32_t, uint32_t*, uint32_t*,
                                            uint32_t*, wchar_t*, uint32_t);
    fnGetVolumeInformationW GetVolumeInformationW = reinterpret_cast<fnGetVolumeInformationW>(kernel32.resolve("GetVolumeInformationW"));
    fnGetLastError GetLastError = reinterpret_cast<fnGetLastError>(kernel32.resolve("GetLastError"));

    if (!GetVolumeInformationW) {
        qWarning(LAT1("GetVolumeInformationW() not resolved: %1").arg(kernel32.errorString()).toLatin1().constData());
        return QByteArray();
    }
    else if (!GetLastError) {
        qWarning(LAT1("GetLastError() not resolved: %1").arg(kernel32.errorString()).toLatin1().constData());
        return QByteArray();
    }

    QDir::toNativeSeparators(QDir::rootPath()).toWCharArray(path);
    bool apiCall = GetVolumeInformationW(path, name, kMaxPath, &serial, &maximumComponentLength,
                                         &fileSystemFlags, fileSystem, kMaxPath);
    if (!apiCall)
        qWarning(LAT1("GetVolumeInformationW() failed: %1").arg(GetLastError()).toLatin1().constData());

    // At this point, fileSystem is correct and contains
    // L"NTFS"

    // ONLY HAPPENS IN DEBUG MODE
    //
    // After this call memory becomes corrupted. wcslen() is not a problem.
    // And createByteArray<>() is ok too, I believe.
    //size_t len;  // But if I change stack a bit (like uncomment this line),
                   // result will be correct, so I guess it's related to memory offset.
    return createByteArray<wchar_t>(fileSystem, wcslen(fileSystem));
}

void print(const QByteArray &bytes) {
    qDebug() << QString::fromWCharArray(reinterpret_cast<const wchar_t*>(bytes.constData()));
    qDebug() << bytes.size() << "bytes" << bytes.toHex();
    qDebug() << "";
}

int main(int, char**)
{    
    qDebug() << "dynamic";
    print(fingerprintDynamic());

    return 0;
}

Sample output:

// this is DEBUG build
dynamic 
"(?(" 
8 bytes "280052f828000400"

// this is RELEASE build
// (same with `size_t len` uncommenented before `return` in DEBUG)
dynamic 
"NTFS" 
8 bytes "4e00540046005300"

The question is: what is the reason of such behaviour? where’s my mistake is hiding?

I’m using g++.exe (GCC) 4.4.0, Qt 4.8.1 and Creator 2.5.2.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T13:01:12+00:00Added an answer on June 14, 2026 at 1:01 pm

    The problem is probably caused by a mismatch in the calling convention. GetVolumeInformationW() has calling convention WINAPI so change the function pointer type to:

    typedef BOOL (WINAPI *fnGetVolumeInformationW)(const wchar_t*,
                                                   wchar_t*,
                                                   uint32_t,
                                                   uint32_t*,
                                                   uint32_t*,
                                                   uint32_t*,
                                                   wchar_t*,
                                                   uint32_t);
    

    WINAPI is calling convention __stdcall, whereas the default is __cdecl.
    Note the return type is BOOL, and not bool.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have installed Matlab r2010a on my computer I need use the function xlsread
I'm working on a project that have the following need: use source ip address
I need use this method with three distinct classes: Orders, Customers, Suppliers public void
I need use this code: <%= button_tag :class => btn btn-primary do %> <%=
So, I need use this event so I can navigate trought blog posts. I
Need to use own imaged markers instead built-in pins. I have several questions. 1.
I need to use maps on running in a physical Android device, how do
I need to use the objdump and readelf commands in my application that runs
I need to use unix Style line endings (only LF) in Zend Studio 8/9
I need to use the javascript loop variable i in the loop block. for

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.