env.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include "nssm.h"
  2. /* Replace NULL with CRLF. Leave NULL NULL as the end marker. */
  3. int format_environment(TCHAR *env, unsigned long envlen, TCHAR **formatted, unsigned long *newlen) {
  4. unsigned long i, j;
  5. *newlen = envlen;
  6. if (! *newlen) {
  7. *formatted = 0;
  8. return 0;
  9. }
  10. for (i = 0; i < envlen; i++) if (! env[i] && env[i + 1]) ++*newlen;
  11. *formatted = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *newlen * sizeof(TCHAR));
  12. if (! *formatted) {
  13. *newlen = 0;
  14. return 1;
  15. }
  16. for (i = 0, j = 0; i < envlen; i++) {
  17. (*formatted)[j] = env[i];
  18. if (! env[i]) {
  19. if (env[i + 1]) {
  20. (*formatted)[j] = _T('\r');
  21. (*formatted)[++j] = _T('\n');
  22. }
  23. }
  24. j++;
  25. }
  26. return 0;
  27. }
  28. /* Strip CR and replace LF with NULL. */
  29. int unformat_environment(TCHAR *env, unsigned long envlen, TCHAR **unformatted, unsigned long *newlen) {
  30. unsigned long i, j;
  31. *newlen = 0;
  32. if (! envlen) {
  33. *unformatted = 0;
  34. return 0;
  35. }
  36. for (i = 0; i < envlen; i++) if (env[i] != _T('\r')) ++*newlen;
  37. /* Must end with two NULLs. */
  38. *newlen += 2;
  39. *unformatted = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *newlen * sizeof(TCHAR));
  40. if (! *unformatted) return 1;
  41. for (i = 0, j = 0; i < envlen; i++) {
  42. if (env[i] == _T('\r')) continue;
  43. if (env[i] == _T('\n')) (*unformatted)[j] = _T('\0');
  44. else (*unformatted)[j] = env[i];
  45. j++;
  46. }
  47. return 0;
  48. }
  49. /*
  50. Verify an environment block.
  51. Returns: 1 if environment is invalid.
  52. 0 if environment is OK.
  53. -1 on error.
  54. */
  55. int test_environment(TCHAR *env) {
  56. TCHAR path[PATH_LENGTH];
  57. GetModuleFileName(0, path, _countof(path));
  58. STARTUPINFO si;
  59. ZeroMemory(&si, sizeof(si));
  60. si.cb = sizeof(si);
  61. PROCESS_INFORMATION pi;
  62. ZeroMemory(&pi, sizeof(pi));
  63. unsigned long flags = CREATE_SUSPENDED;
  64. #ifdef UNICODE
  65. flags |= CREATE_UNICODE_ENVIRONMENT;
  66. #endif
  67. /*
  68. Try to relaunch ourselves but with the candidate environment set.
  69. Assuming no solar flare activity, the only reason this would fail is if
  70. the environment were invalid.
  71. */
  72. if (CreateProcess(0, path, 0, 0, 0, flags, env, 0, &si, &pi)) {
  73. TerminateProcess(pi.hProcess, 0);
  74. }
  75. else {
  76. unsigned long error = GetLastError();
  77. if (error == ERROR_INVALID_PARAMETER) return 1;
  78. else return -1;
  79. }
  80. return 0;
  81. }