ReactOS  0.4.12-dev-18-gf469aca
at.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS AT utility
3  * COPYRIGHT: See COPYING in the top level directory
4  * FILE: base/applications/cmdutils/at/at.c
5  * PURPOSE: ReactOS AT utility
6  * PROGRAMMERS: Eric Kohl <eric.kohl@reactos.org>
7  */
8 
9 #include <stdlib.h>
10 #include <stdio.h>
11 
12 #include <windef.h>
13 #include <winbase.h>
14 #include <winuser.h>
15 #include <wincon.h>
16 #include <winnls.h>
17 #include <lm.h>
18 
19 #include <conutils.h>
20 
21 #include "resource.h"
22 
23 
25 
26 
27 static
28 VOID
30 {
31  INT i;
32 
33  for (i = 0; i < 7; i++)
34  {
35  if (pszDaysOfWeekArray[i] != NULL)
37  }
38 }
39 
40 
41 static
42 BOOL
44 {
45  INT i, nLength;
46 
47  for (i = 0; i < 7; i++)
48  {
51  NULL,
52  0);
53 
56  nLength * sizeof(WCHAR));
57  if (pszDaysOfWeekArray[i] == NULL)
58  {
60  return FALSE;
61  }
62 
66  nLength);
67  }
68 
69  return TRUE;
70 }
71 
72 
73 static
74 BOOL
76  PWSTR pszTime,
77  PULONG pulJobHour,
78  PULONG pulJobMinute)
79 {
80  WCHAR szHour[3], szMinute[3], szAmPm[5];
81  PWSTR startPtr, endPtr;
82  ULONG ulHour = 0, ulMinute = 0;
83  INT nLength;
84 
85  if (pszTime == NULL)
86  return FALSE;
87 
88  startPtr = pszTime;
89 
90  /* Extract the hour string */
91  nLength = 0;
92  while (*startPtr != L'\0' && iswdigit(*startPtr))
93  {
94  if (nLength >= 2)
95  return FALSE;
96 
97  szHour[nLength] = *startPtr;
98  nLength++;
99 
100  startPtr++;
101  }
102  szHour[nLength] = L'\0';
103 
104  /* Check for a valid time separator */
105  if (*startPtr != L':')
106  return FALSE;
107 
108  /* Skip the time separator */
109  startPtr++;
110 
111  /* Extract the minute string */
112  nLength = 0;
113  while (*startPtr != L'\0' && iswdigit(*startPtr))
114  {
115  if (nLength >= 2)
116  return FALSE;
117 
118  szMinute[nLength] = *startPtr;
119  nLength++;
120 
121  startPtr++;
122  }
123  szMinute[nLength] = L'\0';
124 
125  /* Extract the optional AM/PM indicator string */
126  nLength = 0;
127  while (*startPtr != L'\0')
128  {
129  if (nLength >= 4)
130  return FALSE;
131 
132  if (!iswspace(*startPtr))
133  {
134  szAmPm[nLength] = *startPtr;
135  nLength++;
136  }
137 
138  startPtr++;
139  }
140  szAmPm[nLength] = L'\0';
141 
142  /* Convert the hour string */
143  ulHour = wcstoul(szHour, &endPtr, 10);
144  if (ulHour == 0 && *endPtr != UNICODE_NULL)
145  return FALSE;
146 
147  /* Convert the minute string */
148  ulMinute = wcstoul(szMinute, &endPtr, 10);
149  if (ulMinute == 0 && *endPtr != UNICODE_NULL)
150  return FALSE;
151 
152  /* Check for valid AM/PM indicator */
153  if (wcslen(szAmPm) > 0 &&
154  _wcsicmp(szAmPm, L"a") != 0 &&
155  _wcsicmp(szAmPm, L"am") != 0 &&
156  _wcsicmp(szAmPm, L"p") != 0 &&
157  _wcsicmp(szAmPm, L"pm") != 0)
158  return FALSE;
159 
160  /* Check for the valid minute range [0-59] */
161  if (ulMinute > 59)
162  return FALSE;
163 
164  if (wcslen(szAmPm) > 0)
165  {
166  /* 12 hour time format */
167 
168  /* Check for the valid hour range [1-12] */
169  if (ulHour == 0 || ulHour > 12)
170  return FALSE;
171 
172  /* Convert 12 hour format to 24 hour format */
173  if (_wcsicmp(szAmPm, L"a") == 0 ||
174  _wcsicmp(szAmPm, L"am") == 0)
175  {
176  if (ulHour == 12)
177  ulHour = 0;
178  }
179  else
180  {
181  if (ulHour >= 1 && ulHour <= 11)
182  ulHour += 12;
183  }
184  }
185  else
186  {
187  /* 24 hour time format */
188 
189  /* Check for the valid hour range [0-23] */
190  if (ulHour > 23)
191  return FALSE;
192  }
193 
194  if (pulJobHour != NULL)
195  *pulJobHour = ulHour;
196 
197  if (pulJobMinute != NULL)
198  *pulJobMinute = ulMinute;
199 
200  return TRUE;
201 }
202 
203 
204 static
205 BOOL
207  PWSTR pszId,
208  PULONG pulId)
209 {
210  PWSTR startPtr, endPtr;
211  ULONG ulId = 0;
212  BOOL bResult = FALSE;
213 
214  startPtr = pszId;
215  endPtr = NULL;
216  ulId = wcstoul(startPtr, &endPtr, 10);
217  if (endPtr != NULL && *endPtr == UNICODE_NULL)
218  {
219  bResult = TRUE;
220 
221  if (pulId != NULL)
222  *pulId = ulId;
223  }
224 
225  return bResult;
226 }
227 
228 
229 static
230 BOOL
232  PWSTR pszBuffer,
233  PULONG pulDaysOfMonth)
234 {
235  PWSTR startPtr, endPtr;
236  ULONG ulValue;
237 
238  if (wcslen(pszBuffer) == 0)
239  return FALSE;
240 
241  startPtr = pszBuffer;
242  endPtr = NULL;
243  for (;;)
244  {
245  ulValue = wcstoul(startPtr, &endPtr, 10);
246  if (ulValue == 0)
247  return FALSE;
248 
249  if (ulValue > 0 && ulValue <= 31)
250  *pulDaysOfMonth |= (1 << (ulValue - 1));
251 
252  if (endPtr != NULL && *endPtr == UNICODE_NULL)
253  return TRUE;
254 
255  startPtr = endPtr + 1;
256  endPtr = NULL;
257  }
258 
259  return FALSE;
260 }
261 
262 
263 static
264 BOOL
266  PWSTR pszBuffer,
267  PUCHAR pucDaysOfWeek)
268 {
269  PWSTR startPtr, endPtr;
270  INT nLength, i;
271 
272  if (wcslen(pszBuffer) == 0)
273  return FALSE;
274 
275  startPtr = pszBuffer;
276  endPtr = NULL;
277  for (;;)
278  {
279  endPtr = wcschr(startPtr, L',');
280  if (endPtr == NULL)
281  nLength = wcslen(startPtr);
282  else
283  nLength = (INT)((ULONG_PTR)endPtr - (ULONG_PTR)startPtr) / sizeof(WCHAR);
284 
285  for (i = 0; i < 7; i++)
286  {
287  if (nLength == wcslen(pszDaysOfWeekArray[i]) &&
288  _wcsnicmp(startPtr, pszDaysOfWeekArray[i], nLength) == 0)
289  {
290  *pucDaysOfWeek |= (1 << i);
291  break;
292  }
293  }
294 
295  if (endPtr == NULL)
296  return TRUE;
297 
298  startPtr = endPtr + 1;
299  endPtr = NULL;
300  }
301 
302  return FALSE;
303 }
304 
305 
306 static
307 VOID
309  DWORD dwError)
310 {
311  PWSTR pszBuffer = NULL;
312 
314  NULL,
315  dwError,
316  0,
317  (PWSTR)&pszBuffer,
318  0,
319  NULL);
320 
321  ConPrintf(StdErr, L"%s\n", pszBuffer);
322  LocalFree(pszBuffer);
323 }
324 
325 
326 static
327 VOID
329 {
330  WCHAR szBuffer[80];
331  INT i;
332 
333  for (i = 0; i < 79; i++)
334  szBuffer[i] = L'-';
335  szBuffer[79] = UNICODE_NULL;
336 
337  ConPrintf(StdOut, L"%s\n", szBuffer);
338 }
339 
340 
341 static
342 BOOL
344 {
346  WCHAR szYesBuffer[8];
347  WCHAR szNoBuffer[8];
348  WCHAR szInput[80];
349  DWORD dwOldMode;
350  DWORD dwRead = 0;
351  BOOL ret = FALSE;
352  HANDLE hFile;
353 
354  hInstance = GetModuleHandleW(NULL);
355  LoadStringW(hInstance, IDS_CONFIRM_YES, szYesBuffer, _countof(szYesBuffer));
356  LoadStringW(hInstance, IDS_CONFIRM_NO, szNoBuffer, _countof(szNoBuffer));
357 
358  ZeroMemory(szInput, sizeof(szInput));
359 
361  GetConsoleMode(hFile, &dwOldMode);
362 
364 
365  for (;;)
366  {
368 
369  ReadConsoleW(hFile, szInput, _countof(szInput), &dwRead, NULL);
370 
371  szInput[0] = towupper(szInput[0]);
372  if (szInput[0] == szYesBuffer[0])
373  {
374  ret = TRUE;
375  break;
376  }
377  else if (szInput[0] == 13 || szInput[0] == szNoBuffer[0])
378  {
379  ret = FALSE;
380  break;
381  }
382 
384  }
385 
386  SetConsoleMode(hFile, dwOldMode);
387 
388  return ret;
389 }
390 
391 
392 static
393 DWORD_PTR
395 {
397  DWORD_PTR JobTime;
398 
399  GetLocalTime(&Time);
400 
401  JobTime = (DWORD_PTR)Time.wHour * 3600000 +
402  (DWORD_PTR)Time.wMinute * 60000;
403 
404  return JobTime;
405 }
406 
407 
408 static
409 ULONG
411 {
413 
414  GetLocalTime(&Time);
415 
416  return 1UL << (Time.wDay - 1);
417 }
418 
419 
420 static
421 VOID
423  PWSTR pszBuffer,
424  INT cchBuffer,
425  WORD wHour,
426  WORD wMinute)
427 {
428  SYSTEMTIME Time = {0, 0, 0, 0, 0, 0, 0, 0};
429 
430  Time.wHour = wHour;
431  Time.wMinute = wMinute;
432 
435  &Time,
436  NULL,
437  pszBuffer,
438  cchBuffer);
439 }
440 
441 
442 static
443 INT
445  PWSTR pszComputerName,
446  ULONG ulJobId)
447 {
449  DWORD_PTR CurrentTime;
450  WCHAR szStatusBuffer[16];
451  WCHAR szScheduleBuffer[60];
452  WCHAR szTimeBuffer[16];
453  WCHAR szInteractiveBuffer[16];
454  WCHAR szDateBuffer[8];
455  INT i, nDateLength, nScheduleLength;
458 
459  Status = NetScheduleJobGetInfo(pszComputerName,
460  ulJobId,
461  (PBYTE *)&pBuffer);
462  if (Status != NERR_Success)
463  {
464  PrintErrorMessage(Status);
465  return 1;
466  }
467 
468  hInstance = GetModuleHandle(NULL);
469 
470  if (pBuffer->Flags & JOB_EXEC_ERROR)
471  LoadStringW(hInstance, IDS_ERROR, szStatusBuffer, _countof(szStatusBuffer));
472  else
473  LoadStringW(hInstance, IDS_OK, szStatusBuffer, _countof(szStatusBuffer));
474 
475  if (pBuffer->DaysOfMonth != 0)
476  {
477  if (pBuffer->Flags & JOB_RUN_PERIODICALLY)
478  LoadStringW(hInstance, IDS_EVERY, szScheduleBuffer, _countof(szScheduleBuffer));
479  else
480  LoadStringW(hInstance, IDS_NEXT, szScheduleBuffer, _countof(szScheduleBuffer));
481 
482  nScheduleLength = wcslen(szScheduleBuffer);
483  for (i = 0; i < 31; i++)
484  {
485  if (pBuffer->DaysOfMonth & (1 << i))
486  {
487  swprintf(szDateBuffer, L" %d", i + 1);
488  nDateLength = wcslen(szDateBuffer);
489  if (nScheduleLength + nDateLength <= 55)
490  {
491  wcscat(szScheduleBuffer, szDateBuffer);
492  nScheduleLength += nDateLength;
493  }
494  else
495  {
496  wcscat(szScheduleBuffer, L"...");
497  break;
498  }
499  }
500  }
501  }
502  else if (pBuffer->DaysOfWeek != 0)
503  {
504  if (pBuffer->Flags & JOB_RUN_PERIODICALLY)
505  LoadStringW(hInstance, IDS_EVERY, szScheduleBuffer, _countof(szScheduleBuffer));
506  else
507  LoadStringW(hInstance, IDS_NEXT, szScheduleBuffer, _countof(szScheduleBuffer));
508 
509  nScheduleLength = wcslen(szScheduleBuffer);
510  for (i = 0; i < 7; i++)
511  {
512  if (pBuffer->DaysOfWeek & (1 << i))
513  {
514  swprintf(szDateBuffer, L" %s", pszDaysOfWeekArray[i]);
515  nDateLength = wcslen(szDateBuffer);
516  if (nScheduleLength + nDateLength <= 55)
517  {
518  wcscat(szScheduleBuffer, szDateBuffer);
519  nScheduleLength += nDateLength;
520  }
521  else
522  {
523  wcscat(szScheduleBuffer, L"...");
524  break;
525  }
526  }
527  }
528  }
529  else
530  {
531  CurrentTime = GetTimeAsJobTime();
532  if (CurrentTime > pBuffer->JobTime)
533  LoadStringW(hInstance, IDS_TOMORROW, szScheduleBuffer, _countof(szScheduleBuffer));
534  else
535  LoadStringW(hInstance, IDS_TODAY, szScheduleBuffer, _countof(szScheduleBuffer));
536  }
537 
538  JobTimeToTimeString(szTimeBuffer,
539  _countof(szTimeBuffer),
540  (WORD)(pBuffer->JobTime / 3600000),
541  (WORD)((pBuffer->JobTime % 3600000) / 60000));
542 
543  if (pBuffer->Flags & JOB_NONINTERACTIVE)
544  LoadStringW(hInstance, IDS_NO, szInteractiveBuffer, _countof(szInteractiveBuffer));
545  else
546  LoadStringW(hInstance, IDS_YES, szInteractiveBuffer, _countof(szInteractiveBuffer));
547 
548  ConResPrintf(StdOut, IDS_TASKID, ulJobId);
549  ConResPrintf(StdOut, IDS_STATUS, szStatusBuffer);
550  ConResPrintf(StdOut, IDS_SCHEDULE, szScheduleBuffer);
551  ConResPrintf(StdOut, IDS_TIME, szTimeBuffer);
552  ConResPrintf(StdOut, IDS_INTERACTIVE, szInteractiveBuffer);
553  ConResPrintf(StdOut, IDS_COMMAND, pBuffer->Command);
554 
555  NetApiBufferFree(pBuffer);
556 
557  return 0;
558 }
559 
560 
561 static
562 INT
564  PWSTR pszComputerName)
565 {
567  DWORD dwRead = 0, dwTotal = 0;
568  DWORD dwResume = 0, i;
569  DWORD_PTR CurrentTime;
571 
572  WCHAR szScheduleBuffer[32];
573  WCHAR szTimeBuffer[16];
574  WCHAR szDateBuffer[8];
576  INT j, nDateLength, nScheduleLength;
577 
578  Status = NetScheduleJobEnum(pszComputerName,
579  (PBYTE *)&pBuffer,
581  &dwRead,
582  &dwTotal,
583  &dwResume);
584  if (Status != NERR_Success)
585  {
586  PrintErrorMessage(Status);
587  return 1;
588  }
589 
590  if (dwTotal == 0)
591  {
593  return 0;
594  }
595 
598 
599  hInstance = GetModuleHandle(NULL);
600 
601  for (i = 0; i < dwRead; i++)
602  {
603  if (pBuffer[i].DaysOfMonth != 0)
604  {
605  if (pBuffer[i].Flags & JOB_RUN_PERIODICALLY)
606  LoadStringW(hInstance, IDS_EVERY, szScheduleBuffer, _countof(szScheduleBuffer));
607  else
608  LoadStringW(hInstance, IDS_NEXT, szScheduleBuffer, _countof(szScheduleBuffer));
609 
610  nScheduleLength = wcslen(szScheduleBuffer);
611  for (j = 0; j < 31; j++)
612  {
613  if (pBuffer[i].DaysOfMonth & (1 << j))
614  {
615  swprintf(szDateBuffer, L" %d", j + 1);
616  nDateLength = wcslen(szDateBuffer);
617  if (nScheduleLength + nDateLength <= 19)
618  {
619  wcscat(szScheduleBuffer, szDateBuffer);
620  nScheduleLength += nDateLength;
621  }
622  else
623  {
624  wcscat(szScheduleBuffer, L"...");
625  break;
626  }
627  }
628  }
629  }
630  else if (pBuffer[i].DaysOfWeek != 0)
631  {
632  if (pBuffer[i].Flags & JOB_RUN_PERIODICALLY)
633  LoadStringW(hInstance, IDS_EVERY, szScheduleBuffer, _countof(szScheduleBuffer));
634  else
635  LoadStringW(hInstance, IDS_NEXT, szScheduleBuffer, _countof(szScheduleBuffer));
636 
637  nScheduleLength = wcslen(szScheduleBuffer);
638  for (j = 0; j < 7; j++)
639  {
640  if (pBuffer[i].DaysOfWeek & (1 << j))
641  {
642  swprintf(szDateBuffer, L" %s", pszDaysOfWeekArray[j]);
643  nDateLength = wcslen(szDateBuffer);
644  if (nScheduleLength + nDateLength <= 55)
645  {
646  wcscat(szScheduleBuffer, szDateBuffer);
647  nScheduleLength += nDateLength;
648  }
649  else
650  {
651  wcscat(szScheduleBuffer, L"...");
652  break;
653  }
654  }
655  }
656  }
657  else
658  {
659  CurrentTime = GetTimeAsJobTime();
660  if (CurrentTime > pBuffer[i].JobTime)
661  LoadStringW(hInstance, IDS_TOMORROW, szScheduleBuffer, _countof(szScheduleBuffer));
662  else
663  LoadStringW(hInstance, IDS_TODAY, szScheduleBuffer, _countof(szScheduleBuffer));
664  }
665 
666  JobTimeToTimeString(szTimeBuffer,
667  _countof(szTimeBuffer),
668  (WORD)(pBuffer[i].JobTime / 3600000),
669  (WORD)((pBuffer[i].JobTime % 3600000) / 60000));
670 
672  L" %6lu %-21s %-11s %s\n",
673  pBuffer[i].JobId,
674  szScheduleBuffer,
675  szTimeBuffer,
676  pBuffer[i].Command);
677  }
678 
679  NetApiBufferFree(pBuffer);
680 
681  return 0;
682 }
683 
684 
685 static
686 INT
688  PWSTR pszComputerName,
689  ULONG ulJobHour,
690  ULONG ulJobMinute,
691  ULONG ulDaysOfMonth,
692  UCHAR ucDaysOfWeek,
693  BOOL bInteractiveJob,
694  BOOL bPeriodicJob,
695  PWSTR pszCommand)
696 {
697  AT_INFO InfoBuffer;
698  ULONG ulJobId = 0;
700 
701  InfoBuffer.JobTime = (DWORD_PTR)ulJobHour * 3600000 +
702  (DWORD_PTR)ulJobMinute * 60000;
703  InfoBuffer.DaysOfMonth = ulDaysOfMonth;
704  InfoBuffer.DaysOfWeek = ucDaysOfWeek;
705  InfoBuffer.Flags = (bInteractiveJob ? 0 : JOB_NONINTERACTIVE) |
706  (bPeriodicJob ? JOB_RUN_PERIODICALLY : 0);
707  InfoBuffer.Command = pszCommand;
708 
709  Status = NetScheduleJobAdd(pszComputerName,
710  (PBYTE)&InfoBuffer,
711  &ulJobId);
712  if (Status != NERR_Success)
713  {
714  PrintErrorMessage(Status);
715  return 1;
716  }
717 
718  ConResPrintf(StdOut, IDS_NEW_JOB, ulJobId);
719 
720  return 0;
721 }
722 
723 
724 static
725 INT
727  PWSTR pszComputerName,
728  ULONG ulJobId,
729  BOOL bForceDelete)
730 {
732 
733  if (ulJobId == (ULONG)-1 && bForceDelete == FALSE)
734  {
736  if (!Confirm())
737  return 0;
738  }
739 
740  Status = NetScheduleJobDel(pszComputerName,
741  (ulJobId == (ULONG)-1) ? 0 : ulJobId,
742  (ulJobId == (ULONG)-1) ? -1 : ulJobId);
743  if (Status != NERR_Success)
744  {
745  PrintErrorMessage(Status);
746  return 1;
747  }
748 
749  return 0;
750 }
751 
752 
753 int wmain(int argc, WCHAR **argv)
754 {
755  PWSTR pszComputerName = NULL;
756  PWSTR pszCommand = NULL;
757  ULONG ulJobId = (ULONG)-1;
758  ULONG ulJobHour = (ULONG)-1;
759  ULONG ulJobMinute = (ULONG)-1;
760  BOOL bDeleteJob = FALSE, bForceDelete = FALSE;
761  BOOL bInteractiveJob = FALSE, bPeriodicJob = FALSE;
762  BOOL bPrintUsage = FALSE;
763  ULONG ulDaysOfMonth = 0;
764  UCHAR ucDaysOfWeek = 0;
765  INT nResult = 0;
766  INT i, minIdx;
767 
768  /* Initialize the Console Standard Streams */
770 
771  if (!InitDaysOfWeekArray())
772  return 1;
773 
774  /* Parse the computer name */
775  i = 1;
776  minIdx = 1;
777  if (i < argc &&
778  argv[i][0] == L'\\' &&
779  argv[i][1] == L'\\')
780  {
781  pszComputerName = argv[i];
782  i++;
783  minIdx++;
784  }
785 
786  /* Parse the time or job id */
787  if (i < argc && argv[i][0] != L'/')
788  {
789  if (ParseTime(argv[i], &ulJobHour, &ulJobMinute))
790  {
791  i++;
792  minIdx++;
793  }
794  else if (ParseId(argv[i], &ulJobId))
795  {
796  i++;
797  minIdx++;
798  }
799  }
800 
801  /* Parse the options */
802  for (; i < argc; i++)
803  {
804  if (argv[i][0] == L'/')
805  {
806  if (_wcsicmp(argv[i], L"/?") == 0)
807  {
808  bPrintUsage = TRUE;
809  goto done;
810  }
811  else if (_wcsicmp(argv[i], L"/delete") == 0)
812  {
813  bDeleteJob = TRUE;
814  }
815  else if (_wcsicmp(argv[i], L"/yes") == 0)
816  {
817  bForceDelete = TRUE;
818  }
819  else if (_wcsicmp(argv[i], L"/interactive") == 0)
820  {
821  bInteractiveJob = TRUE;
822  }
823  else if (_wcsnicmp(argv[i], L"/every:", 7) == 0)
824  {
825  bPeriodicJob = TRUE;
826  if (ParseDaysOfMonth(&(argv[i][7]), &ulDaysOfMonth) == FALSE)
827  {
828  if (ParseDaysOfWeek(&(argv[i][7]), &ucDaysOfWeek) == FALSE)
829  {
830  ulDaysOfMonth = GetCurrentDayOfMonth();
831  }
832  }
833  }
834  else if (_wcsnicmp(argv[i], L"/next:", 6) == 0)
835  {
836  bPeriodicJob = FALSE;
837  if (ParseDaysOfMonth(&(argv[i][6]), &ulDaysOfMonth) == FALSE)
838  {
839  if (ParseDaysOfWeek(&(argv[i][6]), &ucDaysOfWeek) == FALSE)
840  {
841  ulDaysOfMonth = GetCurrentDayOfMonth();
842  }
843  }
844  }
845  else
846  {
847  bPrintUsage = TRUE;
848  nResult = 1;
849  goto done;
850  }
851  }
852  }
853 
854  /* Parse the command */
855  if (argc > minIdx && argv[argc - 1][0] != L'/')
856  {
857  pszCommand = argv[argc - 1];
858  }
859 
860  if (bDeleteJob == TRUE)
861  {
862  /* Check for invalid options or arguments */
863  if (bInteractiveJob == TRUE ||
864  ulJobHour != (ULONG)-1 ||
865  ulJobMinute != (ULONG)-1 ||
866  ulDaysOfMonth != 0 ||
867  ucDaysOfWeek != 0 ||
868  pszCommand != NULL)
869  {
870  bPrintUsage = TRUE;
871  nResult = 1;
872  goto done;
873  }
874 
875  nResult = DeleteJob(pszComputerName,
876  ulJobId,
877  bForceDelete);
878  }
879  else
880  {
881  if (ulJobHour != (ULONG)-1 && ulJobMinute != (ULONG)-1)
882  {
883  /* Check for invalid options or arguments */
884  if (bForceDelete == TRUE ||
885  pszCommand == NULL)
886  {
887  bPrintUsage = TRUE;
888  nResult = 1;
889  goto done;
890  }
891 
892  nResult = AddJob(pszComputerName,
893  ulJobHour,
894  ulJobMinute,
895  ulDaysOfMonth,
896  ucDaysOfWeek,
897  bInteractiveJob,
898  bPeriodicJob,
899  pszCommand);
900  }
901  else
902  {
903  /* Check for invalid options or arguments */
904  if (bForceDelete == TRUE ||
905  bInteractiveJob == TRUE ||
906  ulDaysOfMonth != 0 ||
907  ucDaysOfWeek != 0 ||
908  pszCommand != NULL)
909  {
910  bPrintUsage = TRUE;
911  nResult = 1;
912  goto done;
913  }
914 
915  if (ulJobId == (ULONG)-1)
916  {
917  nResult = PrintAllJobs(pszComputerName);
918  }
919  else
920  {
921  nResult = PrintJobDetails(pszComputerName,
922  ulJobId);
923  }
924  }
925  }
926 
927 done:
929 
930  if (bPrintUsage == TRUE)
932 
933  return nResult;
934 }
935 
936 /* EOF */
#define MAX_PREFERRED_LENGTH
Definition: lmcons.h:48
static int argc
Definition: ServiceArgs.c:12
NET_API_STATUS WINAPI NetScheduleJobDel(LPCWSTR ServerName, DWORD MinJobId, DWORD MaxJobId)
Definition: schedule.c:104
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
#define TRUE
Definition: types.h:120
#define IDS_DELETE_ALL
Definition: resource.h:5
static DWORD_PTR GetTimeAsJobTime(VOID)
Definition: at.c:394
int wmain(int argc, WCHAR **argv)
Definition: at.c:753
#define DWORD_PTR
Definition: treelist.c:76
static BOOL InitDaysOfWeekArray(VOID)
Definition: at.c:43
#define IDS_STATUS
Definition: resource.h:22
LPWSTR Command
Definition: lmat.h:27
__wchar_t WCHAR
Definition: xmlstorage.h:180
uint16_t * PWSTR
Definition: typedefs.h:54
#define LOCALE_SABBREVDAYNAME1
Definition: winnls.h:84
#define _countof(array)
Definition: fontsub.cpp:30
#define LOCALE_USER_DEFAULT
unsigned char * PUCHAR
Definition: retypes.h:3
#define iswdigit(_c)
Definition: ctype.h:667
BOOL WINAPI GetConsoleMode(HANDLE hConsoleHandle, LPDWORD lpMode)
Definition: console.c:1571
NET_API_STATUS WINAPI NetScheduleJobAdd(LPCWSTR ServerName, LPBYTE Buffer, LPDWORD JobId)
Definition: schedule.c:76
_In_ DWORD nLength
Definition: wincon.h:461
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define IDS_TODAY
Definition: resource.h:10
#define GetLocaleInfo
Definition: winnls.h:1154
#define ZeroMemory
Definition: winbase.h:1635
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:152
#define IDS_USAGE
Definition: resource.h:3
#define IDS_CONFIRM_INVALID
Definition: resource.h:29
static INT PrintJobDetails(PWSTR pszComputerName, ULONG ulJobId)
Definition: at.c:444
DWORD JobTime
Definition: lmat.h:23
Definition: shell.h:41
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
#define WCHAR
Definition: msvc.h:43
static BOOL ParseDaysOfMonth(PWSTR pszBuffer, PULONG pulDaysOfMonth)
Definition: at.c:231
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int32_t INT
Definition: typedefs.h:56
static char ** argv
Definition: ServiceArgs.c:11
#define NERR_Success
Definition: lmerr.h:5
#define IDS_YES
Definition: resource.h:16
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define ENABLE_ECHO_INPUT
Definition: wincon.h:77
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define IDS_NEXT
Definition: resource.h:13
GLenum GLclampf GLint i
Definition: glfuncs.h:14
HINSTANCE hInstance
Definition: charmap.c:20
static BOOL ParseTime(PWSTR pszTime, PULONG pulJobHour, PULONG pulJobMinute)
Definition: at.c:75
#define ConInitStdStreams()
Definition: stream.h:122
#define UNICODE_NULL
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleMode(HANDLE hConsoleHandle, DWORD dwMode)
Definition: console.c:1608
DWORD DaysOfMonth
Definition: lmat.h:24
static DWORD cchBuffer
Definition: fusion.c:83
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:400
#define INT(a)
Definition: assyntax.h:463
INT __cdecl ConPrintf(IN PCON_STREAM Stream, IN LPWSTR szStr,...)
Definition: outstream.c:520
WORD wMinute
Definition: winbase.h:875
smooth NULL
Definition: ftsmooth.c:416
PVOID pBuffer
static BOOL ParseId(PWSTR pszId, PULONG pulId)
Definition: at.c:206
#define IDS_NO
Definition: resource.h:17
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:276
#define STD_INPUT_HANDLE
Definition: winbase.h:264
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:404
NET_API_STATUS WINAPI NetScheduleJobGetInfo(LPCWSTR ServerName, DWORD JobId, LPBYTE *PointerToBuffer)
Definition: schedule.c:174
static BOOL ParseDaysOfWeek(PWSTR pszBuffer, PUCHAR pucDaysOfWeek)
Definition: at.c:265
#define IDS_CONFIRM_NO
Definition: resource.h:31
INT __cdecl ConResPrintf(IN PCON_STREAM Stream, IN UINT uID,...)
Definition: outstream.c:781
DWORD NET_API_STATUS
Definition: ms-dtyp.idl:91
Definition: lmat.h:14
#define IDS_TOMORROW
Definition: resource.h:11
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleW(IN HANDLE hConsoleInput, OUT LPVOID lpBuffer, IN DWORD nNumberOfCharsToRead, OUT LPDWORD lpNumberOfCharsRead, IN PCONSOLE_READCONSOLE_CONTROL pInputControl OPTIONAL)
Definition: readwrite.c:1176
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static VOID PrintHorizontalLine(VOID)
Definition: at.c:328
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
static INT DeleteJob(PWSTR pszComputerName, ULONG ulJobId, BOOL bForceDelete)
Definition: at.c:726
#define JOB_NONINTERACTIVE
Definition: lmat.h:11
NET_API_STATUS WINAPI NetScheduleJobEnum(LPCWSTR ServerName, LPBYTE *PointerToBuffer, DWORD PreferredMaximumLength, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle)
Definition: schedule.c:132
static VOID FreeDaysOfWeekArray(VOID)
Definition: at.c:29
Definition: lmat.h:22
#define swprintf(buf, format,...)
Definition: sprintf.c:56
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ENABLE_LINE_INPUT
Definition: wincon.h:76
#define StdErr
Definition: stream.h:77
#define IDS_OK
Definition: resource.h:19
#define IDS_TIME
Definition: resource.h:24
#define iswspace(_c)
Definition: ctype.h:669
#define IDS_NEW_JOB
Definition: resource.h:6
unsigned char UCHAR
Definition: xmlstorage.h:181
INT ConResPuts(IN PCON_STREAM Stream, IN UINT uID)
Definition: outstream.c:610
int ret
#define IDS_INTERACTIVE
Definition: resource.h:25
#define IDS_CONFIRM_QUESTION
Definition: resource.h:28
#define JOB_EXEC_ERROR
Definition: lmat.h:8
static const WCHAR L[]
Definition: oid.c:1087
#define IDS_COMMAND
Definition: resource.h:26
PWSTR pszDaysOfWeekArray[7]
Definition: at.c:24
uint32_t DWORD_PTR
Definition: typedefs.h:63
_In_ HANDLE hFile
Definition: mswsock.h:90
Status
Definition: gdiplustypes.h:24
#define GetTimeFormat
Definition: winnls.h:1157
UCHAR Flags
Definition: lmat.h:26
WORD wDay
Definition: winbase.h:873
static INT PrintAllJobs(PWSTR pszComputerName)
Definition: at.c:563
static VOID PrintErrorMessage(DWORD dwError)
Definition: at.c:308
NET_API_STATUS WINAPI NetApiBufferFree(LPVOID Buffer)
Definition: apibuf.c:43
#define GetModuleHandle
Definition: winbase.h:3641
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
WORD wHour
Definition: winbase.h:874
#define IDS_SCHEDULE
Definition: resource.h:23
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
unsigned int * PULONG
Definition: retypes.h:1
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
static VOID JobTimeToTimeString(PWSTR pszBuffer, INT cchBuffer, WORD wHour, WORD wMinute)
Definition: at.c:422
static ULONG GetCurrentDayOfMonth(VOID)
Definition: at.c:410
#define IDS_EVERY
Definition: resource.h:12
static BOOL Confirm(VOID)
Definition: at.c:343
#define IDS_ERROR
Definition: resource.h:18
#define JOB_RUN_PERIODICALLY
Definition: lmat.h:7
#define StdOut
Definition: stream.h:76
unsigned int ULONG
Definition: retypes.h:1
#define IDS_JOBS_LIST
Definition: resource.h:7
#define IDS_TASKID
Definition: resource.h:21
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:845
#define ULONG_PTR
Definition: config.h:101
#define IDS_NO_ENTRIES
Definition: resource.h:8
#define TIME_NOSECONDS
Definition: winnls.h:266
#define towupper(c)
Definition: wctype.h:99
static WORD DaysOfMonth(WORD wMonth, WORD wYear)
Definition: job.c:454
#define UL
Definition: tui.h:70
BYTE * PBYTE
Definition: pedump.c:66
#define IDS_CONFIRM_YES
Definition: resource.h:30
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394
static PLARGE_INTEGER Time
Definition: time.c:105
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
UCHAR DaysOfWeek
Definition: lmat.h:25
static INT AddJob(PWSTR pszComputerName, ULONG ulJobHour, ULONG ulJobMinute, ULONG ulDaysOfMonth, UCHAR ucDaysOfWeek, BOOL bInteractiveJob, BOOL bPeriodicJob, PWSTR pszCommand)
Definition: at.c:687