On Friday, 14 July 2017 at 00:33:12 UTC, FoxyBrown wrote:
What I'm trying to do is fairly straightforward but I've wasted nearly 2 days on it.

//added this so it would all compile
import core.sys.windows.windows;
import core.stdc.stdio;
import core.stdc.stdlib;
import std.stdio;
import std.conv;
import std.array;

pragma(lib, "advapi32");

struct ServiceData
{
    wstring Name;
    wstring LongName;
    int Type;
    int State;
    int ControlsAccepted;
    int Win32ExitCode;
    int SpecificExitCode;
    int CheckPoint;
    int WaitHint;
    int ProcessId;
    int Flags;
}

auto cstr2dstr(wchar* cstr)
{
        import std.array;
        auto str = appender!wstring;
        auto len = lstrlen(cstr);
        str.reserve(len);
        
        for(int i = 0; i < len; i++)
                str.put(cstr[i]);

        return str.data;
}


auto EnumServices()
{
        import core.stdc.stdlib, std.traits;
        ServiceData[] servicesList;

auto buf = malloc(50000); // Gets changed later, even though never an assignment
        auto buf2 = buf; // does not change
auto schSCManager = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
    if (NULL == schSCManager)
    {
        printf("OpenSCManager failed (%d)\n", GetLastError());
        return servicesList;
    }
                
        DWORD dwBytesNeeded, dwCount, lpResumeHandle, resume, totalCount;
auto servicesType = (SERVICE_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER | SERVICE_WIN32 | SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS);

        int cnt = 0;            
        auto res = 0;
        do
    {
// Manually copy over data, this is because EnumSErvicesStatus adds data at end of array for some odd ball reason making it difficult to build the correct array sequentially
                for(int i = 0; i < dwCount; i++)
                {
                        ENUM_SERVICE_STATUS_PROCESS x;
                        ServiceData d;
auto s = cast(ENUM_SERVICE_STATUS_PROCESS*)(buf + i*ENUM_SERVICE_STATUS_PROCESS.sizeof);
//                    before buf is of correct value
                        d.Name = cstr2dstr(s.lpServiceName);
                // added these to copy the rest of the fields
                        d.LongName = cstr2dstr(s.lpDisplayName);
                        d.tupleof[2 .. $] = s.ServiceStatusProcess.tupleof;
// after buf is invalid, yet buf is never assigned

 // added this so it actually appends to array
servicesList ~= d;

                }

                
res = EnumServicesStatusEx(schSCManager, SC_ENUM_TYPE.SC_ENUM_PROCESS_INFO, servicesType, SERVICE_STATE_ALL, cast(ubyte*)buf, 50000, &dwBytesNeeded, &dwCount, &resume, null); if (ERROR_MORE_DATA != GetLastError()) { printf("Error enumerating services."); break; }
        } while (res == 0);

        
        foreach(s; servicesList)
        {
writeln(s.Name, " - ", s.LongName, " - ", s.Type, " = ", s.State);
        }


        return servicesList;
}

void main() {
        EnumServices();
}

----


I only modified a few lines in there but it works for me on win64.

Reply via email to