OCS-NG_Windows_Agent_Setup_x64.nsi 75.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
################################################################################
## Open Computer and Software Inventory Next Generation
## Copyright (C) 2010 OCS Inventory NG Team. All rights reserved.
## Web: http://www.ocsinventory-ng.org
##
## This code is open source and may be copied and modified as long as the source
## code is always made freely available.
## Please refer to the General Public Licence http://www.gnu.org/ or Licence.txt
################################################################################

setcompressor /SOLID lzma

; HM NIS Edit Wizard helper defines
14
!define PRODUCT_NAME "OCS Inventory NG Agent"
Charlene Auger's avatar
Charlene Auger committed
15
!define OLD_PRODUCT_NAME "OCS Inventory Agent"
Charlène Auger's avatar
Charlène Auger committed
16
!define PRODUCT_VERSION "2.9.1.0"
17
!define PRODUCT_PUBLISHER "OCS Inventory NG Team"
18
19
20
!define PRODUCT_WEB_SITE "http://www.ocsinventory-ng.org"
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\OCSInventory.exe"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
Charlene Auger's avatar
Charlene Auger committed
21
!define OLD_PRODUCT_UNINST_KEY "Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\${OLD_PRODUCT_NAME}"
22
23
24
25
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
!define PRODUCT_SERVICE_NAME "OCS Inventory Service"
!include "FileFunc.nsh"
!include "WordFunc.nsh"
26
!include "WinVer.nsh"
Charlene Auger's avatar
Charlene Auger committed
27
!include "x64.nsh"
28
29
30
31
!insertmacro GetTime
!insertmacro WordReplace
;!insertmacro un.GetParent
;!insertmacro GetParent
32

Charlène Auger's avatar
Charlène Auger committed
33
34
35
; Define Visual Studio Path
!define VC_PATH "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Redist\MSVC\14.28.29910\x64"

36
; Use Modern UI
37
38
39
40
41
!include "MUI.nsh"
ICON "install-ocs.ico"
; MUI Settings
!define MUI_HEADERIMAGE
!define MUI_WELCOMEPAGE_TITLE_3LINES
Charlene Auger's avatar
Charlene Auger committed
42
!define MUI_HEADERIMAGE_BITMAP "OCS-48.bmp" ; optional
43
!define MUI_ABORTWARNING
44
45
!define MUI_ICON "install-ocs.ico"
!define MUI_UNICON "uninstall-ocs.ico"
46
!define MUI_COMPONENTSPAGE_SMALLDESC
47
48
49
50
; Welcome page
!insertmacro MUI_PAGE_WELCOME
; License page
!insertmacro MUI_PAGE_LICENSE "..\license.txt"
51
52
; Select install type page
!insertmacro MUI_PAGE_COMPONENTS
53
54
55
56
; Server, proxy and agent option pages
Page custom AskServerOptions ValidateServerOptions ""
Page custom AskProxyOptions ValidateProxyOptions ""
Page custom AskAgentOptions ValidateAgentOptions ""
57
Page custom AskAgent2Options ValidateAgent2Options ""
58
59
; Where to save inventory result when /LOCAL is used
Page custom AskLocalInventory ValidateLocalInventory ""
60
61
62
63
64
; Directory page
!insertmacro MUI_PAGE_DIRECTORY
; View before start page
!insertmacro MUI_PAGE_INSTFILES
; Finshed page
65
!define MUI_FINISHPAGE_RUN_TEXT "Start OCS Inventory NG Systray Applet"
66
!define MUI_FINISHPAGE_RUN "$INSTDIR\OcsSystray.exe"
67
68
69
70
71
72
73
!insertmacro MUI_PAGE_FINISH
; Confirl before uninstall
!insertmacro MUI_UNPAGE_INSTFILES
; Language files
!insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "French"

74
;Request application privileges for Windows Vista or higher ('user' or 'admin')
dliroulet's avatar
dliroulet committed
75
RequestExecutionLevel admin
76
77
78
79
80

InstType /NOCUSTOM
InstType "Network inventory"
InstType "Local inventory"

81
; Setup log file
82
!define SETUP_LOG_FILE "$exedir\OCS-Windows-Agent-Setup-x64.log"
83
84
85
86
87
88
89
90
91
92
93
94
95
!define Service_Time_Out "10"


; MUI end ------
VIProductVersion "${PRODUCT_VERSION}"
VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "${PRODUCT_NAME}"
VIAddVersionKey /LANG=${LANG_ENGLISH} "Comments" "Setup ${PRODUCT_NAME}"
VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "${PRODUCT_PUBLISHER}"
VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalTrademarks" "${PRODUCT_WEB_SITE}"
VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "Distributed under GNU GPL Version 2 Licence"
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "${PRODUCT_NAME}"
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "${PRODUCT_VERSION}"

Charlene Auger's avatar
Charlene Auger committed
96
BRANDINGTEXT "OCS Inventory NG"
97
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
98
OutFile "OCS-Windows-Agent-Setup-x64.exe"
Charlène Auger's avatar
Charlène Auger committed
99
InstallDir "$PROGRAMFILES64\OCS Inventory Agent"
Charlene Auger's avatar
Charlene Auger committed
100
InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
101
102
103
104
105
106
107
108
109
110
ShowUnInstDetails show

#####################################################################
# Global variables
#####################################################################
var /GLOBAL logBuffer ; To complete the setup log file
var /GLOBAL OcsService ; To store if service was previously installed (TRUE) or not (FALSE)
var /GLOBAL OcsNoSplash ; To store if setup must display spash screen (FALSE) or not (TRUE)
var /GLOBAL OcsUpgrade ; To store if /UPGRADE option used (TRUE) or not (FALSE)
var /GLOBAL installSatus ; To store installation status
111
112
var /GLOBAL OcsLocal ; To store folder where to write local inventory file

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
#####################################################################
# GetParameters
# input, none
# output, top of stack (replaces, with e.g. whatever)
# modifies no other variables.
#####################################################################
Function GetParameters
	Push $R0
	Push $R1
	Push $R2
	Push $R3
	StrCpy $R2 1
	StrLen $R3 $CMDLINE
	;Check for quote or space
	StrCpy $R0 $CMDLINE $R2
	StrCmp $R0 '"' 0 +3
	StrCpy $R1 '"'
	Goto loop
	StrCpy $R1 " "
loop:
	IntOp $R2 $R2 + 1
	StrCpy $R0 $CMDLINE 1 $R2
	StrCmp $R0 $R1 get
	StrCmp $R2 $R3 get
	Goto loop
get:
	IntOp $R2 $R2 + 1
	StrCpy $R0 $CMDLINE 1 $R2
	StrCmp $R0 " " get
	StrCpy $R0 $CMDLINE "" $R2
	Pop $R3
	Pop $R2
	Pop $R1
	Exch $R0
FunctionEnd

#####################################################################
# GetParameterValue
# Chris Morgan<cmorgan@alum.wpi.edu> 5/10/2004
# -Updated 4/7/2005 to add support for retrieving a command line switch
#  and additional documentation
#
# Searches the command line input, retrieved using GetParameters, for the
# value of an option given the option name.  If no option is found the
# default value is placed on the top of the stack upon function return.
#
# This function can also be used to detect the existence of just a
# command line switch like /OUTPUT  Pass the default and "/OUTPUT"
# on the stack like normal.  An empty return string "" will indicate
# that the switch was found, the default value indicates that
# neither a parameter or switch was found.
#
# Inputs - Top of stack is default if parameter isn't found,
#  second in stack is parameter to search for, ex. "/OUTPUT="
# Outputs - Top of the stack contains the value of this parameter
#  So if the command line contained /OUTPUT=somedirectory, "somedirectory"
#  will be on the top of the stack when this function returns
#
# USAGE:
#  Push "/OUTPUT="       ; push the search string onto the stack
#  Push "DefaultValue"   ; push a default value onto the stack
#  Call GetParameterValue
#  Pop $2
#  MessageBox MB_OK "Value of OUTPUT parameter is '$2'"
#####################################################################
Function GetParameterValue
	Exch $R0  ; get the top of the stack(default parameter) into R0
	Exch      ; exchange the top of the stack(default) with
			; the second in the stack(parameter to search for)
	Exch $R1  ; get the top of the stack(search parameter) into $R1

	;Preserve on the stack the registers used in this function
	Push $R2
	Push $R3
	Push $R4
	Push $R5

	Strlen $R2 $R1      ; store the length of the search string into R2

	Call GetParameters  ; get the command line parameters
	Pop $R3             ; store the command line string in R3

	# search for quoted search string
	StrCpy $R5 '"'      ; later on we want to search for a open quote
	Push $R3            ; push the 'search in' string onto the stack
	Push '"$R1'         ; push the 'search for'
	Call StrStr         ; search for the quoted parameter value
	Pop $R4
	StrCpy $R4 $R4 "" 1   ; skip over open quote character, "" means no maxlen
	StrCmp $R4 "" "" next ; if we didn't find an empty string go to next

	# search for non-quoted search string
	StrCpy $R5 ' '      ; later on we want to search for a space since we
					  ; didn't start with an open quote '"' we shouldn't
					  ; look for a close quote '"'
	Push $R3            ; push the command line back on the stack for searching
	Push '$R1'          ; search for the non-quoted search string
	Call StrStr
	Pop $R4

	; $R4 now contains the parameter string starting at the search string,
	; if it was found
next:
	StrCmp $R4 "" check_for_switch ; if we didn't find anything then look for
								 ; usage as a command line switch
	# copy the value after $R1 by using StrCpy with an offset of $R2,
	# the length of 'OUTPUT'
	StrCpy $R0 $R4 "" $R2  ; copy commandline text beyond parameter into $R0
	# search for the next parameter so we can trim this extra text off
	Push $R0
	Push $R5            ; search for either the first space ' ', or the first
					  ; quote '"'
					  ; if we found '"/output' then we want to find the
					  ; ending ", as in '"/output=somevalue"'
					  ; if we found '/output' then we want to find the first
					  ; space after '/output=somevalue'
	Call StrStr         ; search for the next parameter
	Pop $R4
	StrCmp $R4 "" done  ; if 'somevalue' is missing, we are done
	StrLen $R4 $R4      ; get the length of 'somevalue' so we can copy this
					  ; text into our output buffer
	StrCpy $R0 $R0 -$R4 ; using the length of the string beyond the value,
					  ; copy only the value into $R0
	goto done           ; if we are in the parameter retrieval path skip over
					  ; the check for a command line switch

	; See if the parameter was specified as a command line switch, like '/output'
check_for_switch:
	Push $R3            ; push the command line back on the stack for searching
	Push '$R1'         ; search for the non-quoted search string
	Call StrStr
	Pop $R4
	StrCmp $R4 "" done  ; if we didn't find anything then use the default
	StrCpy $R0 ""       ; otherwise copy in an empty string since we found the
					  ; parameter, just didn't find a value

done:
	Pop $R5
	Pop $R4
	Pop $R3
	Pop $R2
	Pop $R1
	Exch $R0 ; put the value in $R0 at the top of the stack
FunctionEnd

#####################################################################
# This function try to find a string in another one
# Case insensitive
#####################################################################
Function StrStr
	Exch $R1 ; st=haystack,old$R1, $R1=needle
	Exch    ; st=old$R1,haystack
	Exch $R2 ; st=old$R1,old$R2, $R2=haystack
	Push $R3
	Push $R4
	Push $R5
	StrLen $R3 $R1
	StrCpy $R4 0
	; $R1=needle
	; $R2=haystack
	; $R3=len(needle)
	; $R4=cnt
	; $R5=tmp
loop:
	StrCpy $R5 $R2 $R3 $R4
	StrCmp $R5 $R1 done
	StrCmp $R5 "" done
	IntOp $R4 $R4 + 1
	Goto loop
done:
	StrCpy $R1 $R2 "" $R4
	Pop $R5
	Pop $R4
	Pop $R3
	Pop $R2
	Exch $R1
FunctionEnd

#####################################################################
# This function try to find a string in another one, when uninstalling
# Case insensitive
#####################################################################
Function un.StrStr
	Exch $R1 ; st=haystack,old$R1, $R1=needle
	Exch    ; st=old$R1,haystack
	Exch $R2 ; st=old$R1,old$R2, $R2=haystack
	Push $R3
	Push $R4
	Push $R5
	StrLen $R3 $R1
	StrCpy $R4 0
	; $R1=needle
	; $R2=haystack
	; $R3=len(needle)
	; $R4=cnt
	; $R5=tmp
loop:
	StrCpy $R5 $R2 $R3 $R4
	StrCmp $R5 $R1 done
	StrCmp $R5 "" done
	IntOp $R4 $R4 + 1
	Goto loop
done:
	StrCpy $R1 $R2 "" $R4
	Pop $R5
	Pop $R4
	Pop $R3
	Pop $R2
	Exch $R1
FunctionEnd

#####################################################################
# This function write content of logBuffer variable in log file in
# a log file OcsAgentSetup.log located in install directory
#####################################################################
Function Write_Log
	; Save used register
	Push $R0
	ClearErrors
	strcpy $R0 $logBuffer -2
	Detailprint $R0
	; Is there something to write ?
	StrCmp $logBuffer "" WriteLog_end
	; Open log file
	FileOpen $R0 ${SETUP_LOG_FILE} a
	; Seek to end
	FileSeek $R0 END END
	IfErrors WriteLog_end
	; Write
	FileWrite $R0 "$logBuffer"
	StrCpy $logBuffer ""
	; Close file
	FileClose $R0
WriteLog_end:
	; Restore used register
	IfSilent 0 +2
	SLEEP 500
	Pop $R0
FunctionEnd

Function un.Write_Log
	; Save used register
	Push $R0
	ClearErrors
	; Is there something to write ?
	StrCmp $logBuffer "" WriteLog_end
	; Open log file
	FileOpen $R0 "$INSTDIR\uninst.log" a
	; Seek to end
	FileSeek $R0 END END
	IfErrors WriteLog_end
	; Write
	FileWrite $R0 "$logBuffer"
	StrCpy $logBuffer ""
	; Close file
	FileClose $R0
WriteLog_end:
	; Restore used register
	Pop $R0
FunctionEnd

#####################################################################
# This function parse command line arguments
#####################################################################
Function ParseCmd
	; Save used registers
	Push $R0
	Push $R1
	; Get command line paramaters
	Call GetParameters
	Pop $9

	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	; SERVER PROPERTIES
	; Server address
	Push "/SERVER="          ; push the search string onto the stack
	Push "http://ocsinventory-ng/ocsinventory"   ; push a default value onto the stack
	Call GetParameterValue
	Pop $R0
	WriteINIStr "$PLUGINSDIR\server.ini" "Field 7" "State" "$R0"
	; Remove parsed arg from command line
394
	${WordReplace} '$9' '/SERVER=$R0' "" "+" $R1
395
396
	StrCpy $9 $R1
	; Server credentials
397
398
399
400
    ${GetOptions} '$9' '/USER=' $R0
    IfErrors 0 +2
    ; No switch in command line, no user by default
    StrCpy $R0 ""
401
402
	WriteINIStr "$PLUGINSDIR\server.ini" "Field 8" "State" "$R0"
	; Remove parsed arg from command line
403
	${WordReplace} '$9' '/USER=$R0' "" "+" $R1
404
	StrCpy $9 $R1
405
406
407
408
    ${GetOptions} '$9' '/PWD=' $R0
    IfErrors 0 +2
    ; No switch in command line, no password by default
    StrCpy $R0 ""
409
410
	WriteINIStr "$PLUGINSDIR\server.ini" "Field 9" "State" "$R0"
	; Remove parsed arg from command line
411
	${WordReplace} '$9' '/PWD=$R0' "" "+" $R1
412
413
	StrCpy $9 $R1
	; Certificate validation
414
415
416
417
    ${GetOptions} '$9' '/SSL=' $R0
    IfErrors 0 +2
    ; No switch in command line, Certificate validation is required by default
    StrCpy $R0 "1"
418
419
	WriteINIStr "$PLUGINSDIR\server.ini" "Field 10" "State" "$R0"
	; Remove parsed arg from command line
420
	${WordReplace} '$9' '/SSL=$R0' "" "+" $R1
421
	StrCpy $9 $R1
422
423
424
    ${GetOptions} '$9' '/CA=' $R0
    IfErrors 0 +2
    StrCpy $R0 "cacert.pem"
425
426
	WriteINIStr "$PLUGINSDIR\server.ini" "Field 11" "State" "$R0"
	; Remove parsed arg from command line
427
	${WordReplace} '$9' '/CA=$R0' "" "+" $R1
428
429
430
431
	StrCpy $9 $R1
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	; PROXY PROPERTIES
	; Proxy type
432
433
434
435
    ${GetOptions} '$9' '/PROXY_TYPE=' $R0
    ; No switch in command line, No proxy by default
    IfErrors 0 +2
    StrCpy $R0 "0"
436
437
438
439
440
441
442
443
444
445
446
447
448
	${If} "$R0" == "1"
    	; HTTP proxy
	    StrCpy $0 "HTTP"
    ${ElseIf} "$R0" == "2"
        ; Socks 4 proxy
	    StrCpy $0 "Socks 4"
    ${ElseIf} "$R0" == "3"
    	; Socks 5 proxy
	    StrCpy $0 "Socks 5"
    ${Else}
	    ; No proxy
	    StrCpy $0 "None"
    ${EndIf}
449
450
	WriteINIStr "$PLUGINSDIR\proxy.ini" "Field 7" "State" "$0"
	; Remove parsed arg from command line
451
	${WordReplace} '$9' '/PROXY_TYPE=$R0' "" "+" $R1
452
453
	StrCpy $9 $R1
	; Proxy address
454
455
456
457
    ${GetOptions} '$9' '/PROXY=' $R0
    ; No switch in command line, No proxy address by default
    IfErrors 0 +2
    StrCpy $R0 ""
458
459
	WriteINIStr "$PLUGINSDIR\proxy.ini" "Field 8" "State" "$R0"
	; Remove parsed arg from command line
460
	${WordReplace} '$9' '/PROXY=$R0' "" "+" $R1
461
462
	StrCpy $9 $R1
	; Proxy port
463
464
465
466
    ${GetOptions} '$9' '/PROXY_PORT=' $R0
    ; No switch in command line, No proxy port by default
    IfErrors 0 +2
    StrCpy $R0 ""
467
468
	WriteINIStr "$PLUGINSDIR\proxy.ini" "Field 9" "State" "$R0"
	; Remove parsed arg from command line
469
	${WordReplace} '$9' '/PROXY_PORT=$R0' "" "+" $R1
470
471
	StrCpy $9 $R1
	; Proxy credentials
472
473
474
475
    ${GetOptions} '$9' '/PROXY_USER=' $R0
    ; No switch in command line, No proxy user by default
    IfErrors 0 +2
    StrCpy $R0 ""
476
477
	WriteINIStr "$PLUGINSDIR\proxy.ini" "Field 10" "State" "$R0"
	; Remove parsed arg from command line
478
	${WordReplace} '$9' '/PROXY_USER=$R0' "" "+" $R1
479
	StrCpy $9 $R1
480
481
482
483
    ${GetOptions} '$9' '/PROXY_PWD=' $R0
    ; No switch in command line, No proxy password by default
    IfErrors 0 +2
    StrCpy $R0 ""
484
485
	WriteINIStr "$PLUGINSDIR\proxy.ini" "Field 11" "State" "$R0"
	; Remove parsed arg from command line
486
	${WordReplace} '$9' '/PROXY_PWD=$R0' "" "+" $R1
487
488
489
490
	StrCpy $9 $R1
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	; AGENT AND SETUP PROPERTIES
	; Verbose log
491
492
493
494
    ${GetOptions} '$9' '/DEBUG=' $R0
    ; No switch in command line, No verbose log by default
    IfErrors 0 +2
    StrCpy $R0 "0"
495
496
	WriteINIStr "$PLUGINSDIR\agent.ini" "Field 4" "State" "$R0"
	; Remove parsed arg from command line
497
	${WordReplace} '$9' '/DEBUG=$R0' "" "+" $R1
498
	StrCpy $9 $R1
499
	; No Software
500
501
502
503
504
505
506
507
508
509
    ${GetOptions} '$9' '/NOSOFTWARE' $R0
    ; No switch in command line, Software inventory by default
    IfErrors 0 ParseCmd_NoSoft
    ; Scan for Software allowed
    WriteINIStr "$PLUGINSDIR\agent.ini" "Field 10" "State" "0"
    goto ParseCmd_NoSoft_End
ParseCmd_NoSoft:
   ; Never scan for Software
    WriteINIStr "$PLUGINSDIR\agent.ini" "Field 10" "State" "1"
ParseCmd_NoSoft_End:
510
511
	; No TAG
	Push "/NOTAG" ; push the search string onto the stack
512
	Push "1"      ; No TAG by default
513
514
515
516
517
518
519
520
521
    ${GetOptions} '$9' '/NOTAG' $R0
    IfErrors 0 ParseCmd_NoTag
    ; No switch in command line, NOTAG disabled by default
    WriteINIStr "$PLUGINSDIR\agent.ini" "Field 5" "State" "0"
    goto ParseCmd_NoTag_End
ParseCmd_NoTag:
    ; Never ask for TAG
    WriteINIStr "$PLUGINSDIR\agent.ini" "Field 5" "State" "1"
ParseCmd_NoTag_End:
522
	; Remove parsed arg from command line
523
	${WordReplace} '$9' '/NOTAG' "" "+" $R1
524
525
	StrCpy $9 $R1
	; /TAG="value"
526
527
528
    ${GetOptions} '$9' '/TAG=' $R0
    IfErrors 0 +2
    StrCpy $R0 ""
529
530
	WriteINIStr "$PLUGINSDIR\agent.ini" "Field 6" "State" "$R0"
	; Remove parsed arg from command line
531
	${WordReplace} '$9' '/TAG=$R0' "" "+" $R1
532
	StrCpy $9 $R1
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
	; /WMI_FLAG_MODE="value"
	${GetOptions} '$9' '/WMI_FLAG_MODE=' $R0
	IfErrors 0 +2
	StrCpy $R0 "COMPLETE"
	WriteINIStr "$PLUGINSDIR\agent2.ini" "Field 9" "State" "$R0"
	; Remove parsed arg from command line
	${WordReplace} '$9' '/WMI_FLAG_MODE=$R0' "" "+" $R1
	StrCpy $9 $R1
	; /DEFAULT_USER_DOMAIN="value"
	${GetOptions} '$9' '/DEFAULT_USER_DOMAIN=' $R0
	IfErrors 0 +2
	StrCpy $R0 ""
	WriteINIStr "$PLUGINSDIR\agent2.ini" "Field 4" "State" "$R0"
	; Remove parsed arg from command line
	${WordReplace} '$9' '/DEFAULT_USER_DOMAIN=$R0' "" "+" $R1
	StrCpy $9 $R1
549
	; No service
550
551
552
553
554
555
556
557
558
    ${GetOptions} '$9' '/NO_SERVICE' $R0
    IfErrors 0 ParseCmd_NoService
    ; Register service autostart
    WriteINIStr "$PLUGINSDIR\agent.ini" "Field 7" "State" "0"
    goto ParseCmd_NoService_End
ParseCmd_NoService:
    ; Do not register service
	WriteINIStr "$PLUGINSDIR\agent.ini" "Field 7" "State" "1"
ParseCmd_NoService_End:
559
	; Remove parsed arg from command line
560
	${WordReplace} "$9" '/NO_SERVICE' "" "+" $R1
561
562
	StrCpy $9 $R1
	; No systray
563
564
565
566
567
568
569
570
571
    ${GetOptions} '$9' '/NO_SYSTRAY' $R0
    IfErrors 0 ParseCmd_NoSystray
    ; Register systray applet autostart
    WriteINIStr "$PLUGINSDIR\agent.ini" "Field 8" "State" "0"
    goto ParseCmd_NoSystray_End
ParseCmd_NoSystray:
    ; Do not register systray applet
	WriteINIStr "$PLUGINSDIR\agent.ini" "Field 8" "State" "1"
ParseCmd_NoSystray_End:
572
	; Remove parsed arg from command line
573
	${WordReplace} '$9' '/NO_SYSTRAY' "" "+" $R1
574
575
	StrCpy $9 $R1
	; Launch immediate inventory
576
577
578
579
580
581
582
583
584
    ${GetOptions} '$9' '/NOW' $R0
    IfErrors 0 ParseCmd_Now
    ; Do not launch inventory now
    WriteINIStr "$PLUGINSDIR\agent.ini" "Field 9" "State" "0"
    goto ParseCmd_Now_End
ParseCmd_Now:
    ; Immediately maunch inventory
	WriteINIStr "$PLUGINSDIR\agent.ini" "Field 9" "State" "1"
ParseCmd_Now_End:
585
	; Remove parsed arg from command line
586
	${WordReplace} '$9' '/NOW' "" "+" $R1
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
	StrCpy $9 $R1
	; Silent install option
	Push "$9"
	Push "/S"
	Call StrStr
	Pop $R0
	StrCpy $R1 $R0 3
	StrCmp "$R1" "/s" ParseCmd_Silent
	StrCmp "$R1" "/S " ParseCmd_Silent
	; Use normal interactive setup
	SetSilent normal
	Goto ParseCmd_Silent_end
ParseCmd_Silent:
	; Use silent setup
	SetSilent silent
	; Remove parsed arg from command line
603
	${WordReplace} '$9' '/S' "" "+" $R1
604
605
606
	StrCpy $9 $R1
ParseCmd_Silent_end:
	; No splash option
607
608
609
610
611
612
613
614
615
    ${GetOptions} '$9' '/NOSPLASH' $R0
    IfErrors 0 ParseCmd_NoSplash
	; Display spash screen
	StrCpy $OcsNoSplash "FALSE"
    goto ParseCmd_NoSplash_End
ParseCmd_NoSplash:
    ; Do not display spash screen
    StrCpy $OcsNoSplash "TRUE"
ParseCmd_NoSplash_End:
616
	; Remove parsed arg from command line
617
	${WordReplace} '$9' '/NOSPLASH' "" "+" $R1
618
619
	StrCpy $9 $R1
	; /UPGRADE switch to set deployment status
620
621
    ${GetOptions} '$9' '/UPGRADE' $R0
    IfErrors 0 ParseCmd_Upgrade
Charlène Auger's avatar
Charlène Auger committed
622
623
		; Do not write deployment status file
		StrCpy $OcsUpgrade "FALSE"
624
625
    goto ParseCmd_Upgrade_End
ParseCmd_Upgrade:
626
	; Write deployment status file
627
628
	StrCpy $OcsUpgrade "TRUE"
ParseCmd_Upgrade_End:
629
	; Remove parsed arg from command line
630
	${WordReplace} '$9' '/UPGRADE' "" "+" $R1
631
	StrCpy $9 $R1
dliroulet's avatar
dliroulet committed
632
	; Parse /LOCAL=
633
634
    ${GetOptions} '$9' '/LOCAL=' $R0
    IfErrors 0 ParseCmd_Local
Charlène Auger's avatar
Charlène Auger committed
635
636
		; Network enabled inventory
		SetCurInstType 0
637
638
639
640
641
642
643
644
645
    goto ParseCmd_Local_End
ParseCmd_Local:
	; Local inventory asked
	SetCurInstType 1
    SetShellVarContext Current
	StrCpy $INSTDIR "$TEMP\OCS Inventory Agent"
	StrCpy $OcsLocal "$R0"
	WriteINIStr "$PLUGINSDIR\local.ini" "Field 6" "State" "$R0"
ParseCmd_Local_End:
646
647
648
649
650
651
652
	; Restore used registers
	Pop $R1
	Pop $R0
FunctionEnd

#####################################################################
# This function try to stop service when installing/upgrading
653
# Service Key to stop is passed into top of stack
654
655
#####################################################################
Function StopService
656
657
	; Get service key
    Pop $9
658
659
	; Save used register
	Push $R0
660
	StrCmp $OcsService "TRUE" 0 stop_service_end_loop
661
	; Check service status
662
	StrCpy $logBuffer "Is Service <$9> running..."
663
	Call Write_Log
664
	services::IsServiceRunning "$9"
665
	Pop $0
dliroulet's avatar
dliroulet committed
666
	StrCpy $logBuffer "$0.$\r$\n"
667
668
	Call Write_Log
	; Stop service
669
	StrCpy $logBuffer "Trying to stop Service <$9>..."
670
	Call Write_Log
671
	services::SendServiceCommand "stop" "$9" ; This command dies silently on Win9x
672
	Pop $0
673
674
675
	StrCpy $logBuffer "$0$\r$\n"
	Call Write_Log
	strcpy $1 0
676
stop_service_loop:
677
	intop $1 $1 + 1
678
	strcmp ${Service_Time_Out} $1 stop_service_time_out_reached
679
	sleep 950
680
	StrCpy $logBuffer "Is Service <$9> running..."
681
	Call Write_Log
682
	services::IsServiceRunning "$9"
683
	Pop $0
684
685
	StrCpy $logBuffer "$0 - Waiting 1 second(s) for Service to stop...$\r$\n"
	Call Write_Log
686
687
	strcmp $0 "YES" stop_service_loop stop_service_end_loop
stop_service_time_out_reached:
688
689
690
691
	StrCpy $logBuffer "Error time out reached while waiting for service stop!$\r$\n"
	Call Write_Log
	StrCpy $logBuffer "Will try to kill processes..$\r$\n"
	Call Write_Log
692
stop_service_end_loop:
Charlène Auger's avatar
Charlène Auger committed
693
694
695
696
697
698
699
700
701
702
703
704
705
706
	; KillProcDLL
	;	0 = Process was successfully terminated
	;	603 = Process was not currently running
	;	604 = No permission to terminate process
	;	605 = Unable to load PSAPI.DLL
	;	602 = Unable to terminate process for some other reason
	;	606 = Unable to identify system type
	;	607 = Unsupported OS
	;	632 = Invalid process name
	;	700 = Unable to get procedure address from PSAPI.DLL
	;	701 = Unable to get process list, EnumProcesses failed
	;	702 = Unable to load KERNEL32.DLL
	;	703 = Unable to get procedure address from KERNEL32.DLL
	;	704 = CreateToolhelp32Snapshot failed
707
	sleep 1000
708
709
710
711
712
	nsProcess::_FindProcess "OcsSystray.exe"
	StrCpy $logBuffer "Trying to find process OcsSystray.exe...Result: $R0$\r$\n"
	Call Write_Log
	sleep 1000
	nsProcess::_KillProcess  "OcsSystray.exe" $R0
713
	StrCpy $logBuffer "Trying to kill process OcsSystray.exe...Result: $R0$\r$\n"
714
	Call Write_Log
715
716
	; If OcsSystray killed, perhaps there is another process running under another user session,
	; So try to kill OcsSystray.exe until there no process or error detected
717
	StrCmp "$R0" "1" stop_service_end_loop
718
	sleep 1000
Charlène Auger's avatar
Charlène Auger committed
719
	KillProcDLL::KillProc "OcsService.exe" $R0
720
721
722
	StrCpy $logBuffer "Trying to kill process OcsService.exe...Result: $R0$\r$\n"
	Call Write_Log
	sleep 1000
Charlène Auger's avatar
Charlène Auger committed
723
	KillProcDLL::KillProc "OCSInventory.exe" $R0
724
725
726
	StrCpy $logBuffer "Trying to kill process OCSInventory.exe...Result: $R0$\r$\n"
	Call Write_Log
	sleep 1000
Charlène Auger's avatar
Charlène Auger committed
727
	KillProcDLL::KillProc "download.exe" $R0
728
729
730
731
	StrCpy $logBuffer "Trying to kill process download.exe...Result: $R0$\r$\n"
	Call Write_Log
	sleep 1000
	; For old agent using inst32.exe
Charlène Auger's avatar
Charlène Auger committed
732
	KillProcDLL::KillProc "inst32.exe" $R0
733
734
	StrCpy $logBuffer "Trying to kill process inst32.exe...Result: $R0$\r$\n"
	Call Write_Log
735
	sleep 1000
dliroulet's avatar
dliroulet committed
736
	StrCpy $logBuffer "Waiting 10 seconds for processes to terminate...$\r$\n"
737
738
	Call Write_Log
	sleep 10000
739
	${Locate} "C:\Program Files (x86)\OCS Inventory Agent" "/L=F /M=OCSInventory.exe" "FoundOldAgent"
740
741
742
743
	; Restore used register
	Pop $R0
FunctionEnd

Charlène Auger's avatar
Charlène Auger committed
744
745
746
747
748
749
750
751
752
Function FoundOldAgent
	StrCpy $logBuffer "OK $R0 $R8$\r$\n"
	Call Write_Log
	sleep 1000
	StrCpy $logBuffer "$0" StopLocate
	Call Write_Log
	sleep 1000

	;	If old agent detected remove all files
Charlene Auger's avatar
Charlene Auger committed
753
	StrCpy $logBuffer "Sarting Old ${PRODUCT_NAME} Version UNINSTALL in $R8...$\r$\n"
Charlène Auger's avatar
Charlène Auger committed
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
	Call Write_Log
	; Uninstall NT service
	nsExec::ExecToLog "$R8\ocsservice.exe -uninstall"
	; Remove startup links
	Delete /REBOOTOK "$SMSTARTUP\OCS Inventory NG Systray.lnk"
	; Remove files
	Delete /REBOOTOK "$R8\uninst.exe"
	StrCpy $logBuffer "Delete uninst.exe...$\r$\n"
	Call Write_Log
	Delete /REBOOTOK "$R8\zlib1.dll"
	StrCpy $logBuffer "Delete zlib...$\r$\n"
	Call Write_Log
	Delete /REBOOTOK "$R8\ZipArchive.dll"
	StrCpy $logBuffer "Delete zipArchive...$\r$\n"
	Call Write_Log
	Delete /REBOOTOK "$R8\uac.manifest"
	Delete /REBOOTOK "$R8\SysInfo.dll"
	Delete /REBOOTOK "$R8\ssleay32.dll"
	Delete /REBOOTOK "$R8\OcsWmi.dll"
	Delete /REBOOTOK "$R8\OcsSystray.exe"
	Delete /REBOOTOK "$R8\OcsService.exe"
	Delete /REBOOTOK "$R8\OCSInventory.exe"
	Delete /REBOOTOK "$R8\OcsSnmp.exe"
	Delete /REBOOTOK "$R8\libeay32.dll"
	Delete /REBOOTOK "$R8\libcurl.dll"
	Delete /REBOOTOK "$R8\download.exe"
	RMDir /r /REBOOTOK "$R8"
	StrCpy $logBuffer "Delete old repository...$\r$\n"
	Call Write_Log
	
	SetAutoClose true
FunctionEnd

787
788
789
790
791
792
793
794
795
796
#####################################################################
# This function try to stop service when uninstalling
#####################################################################
Function un.StopService
	; Save used register
	Push $R0
	; Check service status
	StrCpy $logBuffer "Is ${PRODUCT_SERVICE_NAME} running..."
	Call un.Write_Log
	services::IsServiceRunning "${PRODUCT_SERVICE_NAME}"
797
	Pop $0
dliroulet's avatar
dliroulet committed
798
	StrCpy $logBuffer "$0.$\r$\n"
799
800
801
802
803
	Call un.Write_Log
	; Stop service
	StrCpy $logBuffer "Trying to stop ${PRODUCT_SERVICE_NAME}..."
	Call un.Write_Log
	services::SendServiceCommand "stop" "${PRODUCT_SERVICE_NAME}" ; This command dies silently on Win9x
804
	Pop $0
805
806
807
	StrCpy $logBuffer "$0$\r$\n"
	Call un.Write_Log
	strcpy $1 0
Charlene Auger's avatar
Charlene Auger committed
808
	un.stop_service_loop:
809
	intop $1 $1 + 1
810
	strcmp ${Service_Time_Out} $1 un.stop_service_time_out_reached 0
811
812
813
814
	sleep 950
	StrCpy $logBuffer "Is ${PRODUCT_SERVICE_NAME} running..."
	Call un.Write_Log
	services::IsServiceRunning "${PRODUCT_SERVICE_NAME}"
815
	Pop $0
816
817
	StrCpy $logBuffer "$0 - waiting 1 second(s) for service to stop...$\r$\n"
	Call un.Write_Log
818
	strcmp $0 "YES" un.stop_service_loop un.stop_service_end_loop
Charlene Auger's avatar
Charlene Auger committed
819
	un.stop_service_time_out_reached:
820
821
822
823
	StrCpy $logBuffer "Error time out reached while waiting for service stop!$\r$\n"
	Call un.Write_Log
	StrCpy $logBuffer "Will try to kill processes..$\r$\n"
	Call un.Write_Log
Charlene Auger's avatar
Charlene Auger committed
824
	un.stop_service_end_loop:
Charlène Auger's avatar
Charlène Auger committed
825
826
827
828
829
830
831
832
833
834
835
836
837
838
	; KillProcDLL
	;	0 = Process was successfully terminated
	;	603 = Process was not currently running
	;	604 = No permission to terminate process
	;	605 = Unable to load PSAPI.DLL
	;	602 = Unable to terminate process for some other reason
	;	606 = Unable to identify system type
	;	607 = Unsupported OS
	;	632 = Invalid process name
	;	700 = Unable to get procedure address from PSAPI.DLL
	;	701 = Unable to get process list, EnumProcesses failed
	;	702 = Unable to load KERNEL32.DLL
	;	703 = Unable to get procedure address from KERNEL32.DLL
	;	704 = CreateToolhelp32Snapshot failed
839
	sleep 1000
840
841
842
843
844
	nsProcess::_FindProcess "OcsSystray.exe"
	StrCpy $logBuffer "Trying to find process OcsSystray.exe...Result: $R0$\r$\n"
	Call un.Write_Log
	sleep 1000
	nsProcess::_KillProcess  "OcsSystray.exe" $R0
845
846
	StrCpy $logBuffer "Trying to kill process OcsSystray.exe...Result: $R0$\r$\n"
	Call un.Write_Log
847
848
	; If OcsSystray killed, perhaps there is another process running under another user session,
	; So try to kill OcsSystray.exe until there no process or error detected
849
	StrCmp "$R0" "1" un.stop_service_end_loop
850
	sleep 1000
Charlène Auger's avatar
Charlène Auger committed
851
	KillProcDLL::KillProc "OcsService.exe" $R0
852
853
854
	StrCpy $logBuffer "Trying to kill process OcsService.exe...Result: $R0$\r$\n"
	Call un.Write_Log
	sleep 1000
Charlène Auger's avatar
Charlène Auger committed
855
	KillProcDLL::KillProc "OCSInventory.exe" $R0
856
857
858
	StrCpy $logBuffer "Trying to kill process OCSInventory.exe...Result: $R0$\r$\n"
	Call un.Write_Log
	sleep 1000
Charlène Auger's avatar
Charlène Auger committed
859
	KillProcDLL::KillProc "download.exe" $R0
860
861
862
	StrCpy $logBuffer "Trying to kill process download.exe...Result: $R0$\r$\n"
	Call un.Write_Log
	sleep 1000
dliroulet's avatar
dliroulet committed
863
	StrCpy $logBuffer "Waiting 10 seconds for processes to terminate...$\r$\n"
864
865
	Call un.Write_Log
	sleep 10000
866
867
868
869
870
	; Restore used register
	Pop $R0
FunctionEnd

#####################################################################
871
# This function install service if needed
872
873
# Uses OcsService variable initialized in TestInstall function
#####################################################################
874
Function InstallService
875
876
	; Save used register
	Push $R0
877
878
879
        ; check if NT service was previously installed
	StrCpy $logBuffer "Checking if service ${PRODUCT_SERVICE_NAME} is registered into Windows Service Manager..."
	Call Write_Log
880
881
882
        services::IsServiceInstalled "${PRODUCT_SERVICE_NAME}"
        Pop $R0
        ${If} "$R0" == "Yes"
883
            StrCpy $logBuffer "Yes$\r$\nService is installed, so unregistering ${PRODUCT_SERVICE_NAME} from Windows Service Manager..."
884
            Call Write_Log
885
886
887
	        nsExec::ExecToLog "$INSTDIR\OcsService.exe -uninstall"
	        Pop $R0
	        StrCpy $logBuffer "Result: $R0.$\r$\n"
dliroulet's avatar
dliroulet committed
888
	        Call Write_Log
889
        ${Else}
890
            StrCpy $logBuffer "No$\r$\nNo service installed, so no need to unregister ${PRODUCT_SERVICE_NAME} from Windows Service Manager.$\r$\n"
891
892
            Call Write_Log
        ${EndIf}
893
894
895
896
897
	; Check if NT service is required
	ReadINIStr $R0 "$PLUGINSDIR\agent.ini" "Field 7" "State"
	${If} $R0 == "1"
        ; Service must not be installed
            StrCpy $logBuffer "[/NO_SERVICE] used, so no need to register ${PRODUCT_SERVICE_NAME} into Windows Service Manager.$\r$\n"
898
899
            Call Write_Log
        ${Else}
900
901
        ; Service is required
            StrCpy $logBuffer "Registering ${PRODUCT_SERVICE_NAME} into Windows Service Manager..."
902
            Call Write_Log
903
904
905
    	    nsExec::ExecToLog "$INSTDIR\OcsService.exe -install"
    	    Pop $R0
	        StrCpy $logBuffer "Result: $R0.$\r$\n"
dliroulet's avatar
dliroulet committed
906
	        Call Write_Log
907
908
        ${EndIf}
	; Restore used register
909
910
911
	Pop $R0
FunctionEnd

912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928

#####################################################################
# This function install service if needed, and start it
# Uses OcsService variable initialized in TestInstall function
#####################################################################
Function StartService
	; Save used register
	Push $R0
    ; check if NT service was previously installed
    services::IsServiceInstalled "${PRODUCT_SERVICE_NAME}"
    Pop $R0
    ${If} "$R0" == "Yes"
        ; Start NT service
	    StrCpy $logBuffer "Starting ${PRODUCT_SERVICE_NAME}..."
	    Call Write_Log
	    services::SendServiceCommand "start" "${PRODUCT_SERVICE_NAME}" ; This command dies silently on Win9x
	    Pop $R0
dliroulet's avatar
dliroulet committed
929
	    StrCpy $logBuffer "$R0.$\r$\n"
930
931
932
933
934
935
936
	    Call Write_Log
	${EndIf}
	; Restore used register
    Pop $R0
FunctionEnd


937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
#####################################################################
# This function try to find if logged in user has admin rights
#####################################################################
Function IsUserAdmin
	Push $R0
	Push $R1
	Push $R2
	ClearErrors
	UserInfo::GetName
	IfErrors IsUserAdmin_Win9x
	; Assuming Windows NT
	Pop $R1
	UserInfo::GetAccountType
	Pop $R2
	StrCmp $R2 "Admin" 0 IsUserAdmin_Continue
	; Observation: I get here when running Win98SE. (Lilla)
	; The functions UserInfo.dll looks for are there on Win98 too,
	; but just don't work. So UserInfo.dll, knowing that admin isn't required
	; on Win98, returns admin anyway. (per kichik)
	; MessageBox MB_OK 'User "$R1" is in the Administrators group'
	StrCpy $R0 "true"
	Goto IsUserAdmin_end
IsUserAdmin_Continue:
	; You should still check for an empty string because the functions
	; UserInfo.dll looks for may not be present on Windows 95. (per kichik)
	StrCmp $R2 "" IsUserAdmin_Win9x
	StrCpy $R0 "false"
	;MessageBox MB_OK 'User "$R1" is in the "$R2" group'
	Goto IsUserAdmin_end
IsUserAdmin_Win9x:
	; comment/message below is by UserInfo.nsi author:
	; This one means you don't need to care about admin or
	; not admin because Windows 9x doesn't either
	;MessageBox MB_OK "Error! This DLL can't run under Windows 9x!"
	StrCpy $R0 "true"
IsUserAdmin_end:
	;MessageBox MB_OK 'User= "$R1"  AccountType= "$R2"  IsUserAdmin= "$R0"'
	Pop $R2
	Pop $R1
	Exch $R0
FunctionEnd

979

980
#####################################################################
dliroulet's avatar
dliroulet committed
981
# This function checks if service was previously installed
982
983
984
985
986
987
988
989
990
991
992
993
994
#####################################################################
Function TestInstall
	; Save used register
	Push $R0
	; Does service exist ?
	StrCpy $logBuffer "Trying to determine if service was previously installed..."
	Call Write_Log
	ClearErrors
	Services::IsServiceInstalled "${PRODUCT_SERVICE_NAME}"
	Pop $R0
    StrCmp "$R0" "No" TestInstall_No_Service
    ; Services is installed
	StrCpy $OcsService "TRUE"
dliroulet's avatar
dliroulet committed
995
	StrCpy $logBuffer "Yes.$\r$\n"
996
997
998
999
	Call Write_Log
	Goto TestInstall_Kill_Process
TestInstall_No_Service:
	StrCpy $OcsService "FALSE"
dliroulet's avatar
dliroulet committed
1000
	StrCpy $logBuffer "No.$\r$\n"