WTF is going on! Corrupt value that is never assigned

Adam D. Ruppe via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Jul 13 18:01:09 PDT 2017


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.



More information about the Digitalmars-d-learn mailing list