<|start_filename|>src/process.h<|end_filename|>
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

#ifndef SRC_PROCESS_H_
#define SRC_PROCESS_H_

#include <nan.h>
#include <windows.h>

struct Cpu {
  DWORD pid;
  double cpu;
  ULONGLONG initialProcRunTime;
  ULONGLONG initialSystemTime;
};

struct ProcessInfo {
  TCHAR name[MAX_PATH];
  DWORD pid;
  DWORD ppid;
  DWORD memory; // Reported in bytes
  TCHAR commandLine[4096];
};

enum ProcessDataFlags {
  NONE = 0,
  MEMORY = 1,
  COMMANDLINE = 2
};

void GetRawProcessList(ProcessInfo process_info[1024], uint32_t* process_count, DWORD* flags);

void GetProcessMemoryUsage(ProcessInfo process_info[1024], uint32_t* process_count);

void GetCpuUsage(Cpu cpu_info[1024], uint32_t* process_count, BOOL first_run);

#endif  // SRC_PROCESS_H_


<|start_filename|>src/process_worker.cc<|end_filename|>
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

#include "process_worker.h"

GetProcessesWorker::GetProcessesWorker(
    Nan::Callback* callback,
    DWORD* process_data_flags) 
      : AsyncWorker(callback),
        process_data_flags(process_data_flags) {
    process_info = new ProcessInfo[1024];
    process_count = new uint32_t;
}

GetProcessesWorker::~GetProcessesWorker() {
  delete[] process_info;
  delete process_count;
  delete process_data_flags;
}

void GetProcessesWorker::Execute() {
  GetRawProcessList(process_info, process_count, process_data_flags);
}

void GetProcessesWorker::HandleOKCallback() {
  Nan::HandleScope scope;
  // Transfer results into actual result object
  v8::Local<v8::Array> result = Nan::New<v8::Array>(*process_count);
  for (uint32_t i = 0; i < *process_count; i++) {
    v8::Local<v8::Object> object = Nan::New<v8::Object>();
    Nan::Set(object, Nan::New<v8::String>("name").ToLocalChecked(),
              Nan::New<v8::String>(process_info[i].name).ToLocalChecked());
    Nan::Set(object, Nan::New<v8::String>("pid").ToLocalChecked(),
              Nan::New<v8::Number>(process_info[i].pid));
    Nan::Set(object, Nan::New<v8::String>("ppid").ToLocalChecked(),
              Nan::New<v8::Number>(process_info[i].ppid));

    // Property should be undefined when memory flag isn't set
    if (MEMORY & *process_data_flags) {
      Nan::Set(object, Nan::New<v8::String>("memory").ToLocalChecked(),
              Nan::New<v8::Number>(process_info[i].memory));
    }

    if (COMMANDLINE & *process_data_flags) {
      Nan::Set(object, Nan::New<v8::String>("commandLine").ToLocalChecked(),
        Nan::New<v8::String>(process_info[i].commandLine).ToLocalChecked());
    }

    Nan::Set(result, i, Nan::New<v8::Value>(object));
  }

  v8::Local<v8::Value> argv[] = { result };
  Nan::AsyncResource resource("windows-process-tree:addon.HandleOKCallback");
  callback->Call(1, argv, &resource);
}
