LiveCode

Command prompt blocking policies and the shell function

This week I had a report of an application locking up while executing the shell function. Actually it was executing shell(“ipconfig /all”) in my modification of Ken Ray’s GetMACAddress function to return the machine’s LAN ip.

System administrators tend to like to turn things off so normal human beings can’t make a mess of their nice machines. One thing they can do is set a Windows registry entry to disable cmd.exe for the user. So by checking HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\System\DisableCMD”=dword:1 we can find out if cmd.exe is disabled for the current user. What this does is when cmd.exe is run it opens the console but all you get is a blocked by admin message and no command prompt. If Bill would just change this so it stopped cmd.exe from launching at all then we wouldn’t have such a problem. LiveCode is therefore able to run cmd.exe and just sits there waiting for it to terminate but it never does.

So I wrote a safer shell function to check for this situation and also possible execution errors from hash rules and renaming of cmd.exe etc. If the registry setting is there it will attempt to execute the command directly using process commands rather than via shell.

<span class="storage storage_type storage_type_handler storage_type_handler_rev">function</span><span> safeShell pCommand</span>
<span>   </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- assume the shellCommand has been set appropriately</span>
<span>   </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">hideConsoleWindows</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="keyword keyword_control keyword_control_rev">true</span>
<span>   </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">set</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">itemDel</span><span> </span><span class="keyword keyword_control keyword_control_rev">to</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"\"</span>
<span>   </span><span class="keyword keyword_control keyword_control_rev">if</span><span> </span><span class="keyword keyword_control keyword_control_rev">item</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">-</span><span class="constant constant_numeric constant_numeric_rev">1</span><span> </span><span class="keyword keyword_control keyword_control_rev">of</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="support support_command support_command_rev">shellCommand</span><span> </span><span class="keyword keyword_control keyword_control_rev">is</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"cmd.exe"</span><span> </span><span class="keyword keyword_control keyword_control_rev">AND</span><span> \ </span>
<span>          </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">charToNum</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span class="entity entity_name entity_name_handler entity_name_handler_rev">queryRegistry</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\System\DisableCMD"</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">))</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">=</span><span> </span><span class="constant constant_numeric constant_numeric_rev">1</span><span> then</span>
<span>      </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- don't use cmd.exe because shell() won't return</span>
<span>      </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- don't revert to command.com because there seems to be a problem in the engine</span>
<span>      </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">return</span><span> executeProcess</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span>pCommand</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span>
<span>   </span><span class="keyword keyword_control keyword_control_rev">else</span>
<span>      </span><span class="keyword keyword_control keyword_control_rev">try</span>
<span>         </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- still check for empty if your are expecting a result</span>
<span>         </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- because there's no execution error on os x</span>
<span>         </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">return</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">shell</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">(</span><span>pCommand</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">)</span>
<span>      </span><span class="keyword keyword_control keyword_control_rev">catch</span><span> e</span>
<span>         </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- execution error on windows shellCommand doesn't exist</span>
<span>         </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- hopefully this catches hash rule blocks</span>
<span>         </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">return</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"Error executing command"</span>
<span>      </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">try</span>
<span>   </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span>
<span class="keyword keyword_control keyword_control_rev">end</span><span> safeShell</span>


<span class="storage storage_type storage_type_handler storage_type_handler_rev">function</span><span> executeProcess pProcess</span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">,</span><span>pElevate</span>
<span>   </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">local</span><span> tReturn</span>
<span>   </span><span class="keyword keyword_control keyword_control_rev">if</span><span> pElevate then</span>
<span>      </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">open</span><span> </span><span class="keyword keyword_control keyword_control_rev">elevated</span><span> </span><span class="keyword keyword_control keyword_control_rev">process</span><span> pProcess </span><span class="keyword keyword_control keyword_control_rev">for</span><span> </span><span class="support support_command support_command_rev">text</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">read</span>
<span>   </span><span class="keyword keyword_control keyword_control_rev">else</span>
<span>      </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">open</span><span> </span><span class="keyword keyword_control keyword_control_rev">process</span><span> pProcess </span><span class="keyword keyword_control keyword_control_rev">for</span><span> </span><span class="support support_command support_command_rev">text</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">read</span>
<span>   </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span>
<span>   </span><span class="keyword keyword_control keyword_control_rev">repeat</span><span> </span><span class="keyword keyword_control keyword_control_rev">forever</span>
<span>      </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev"># Loop until there are no more lines to read.</span>
<span>      </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">read</span><span> </span><span class="keyword keyword_control keyword_control_rev">from</span><span> </span><span class="keyword keyword_control keyword_control_rev">process</span><span> pProcess </span><span class="keyword keyword_control keyword_control_rev">for</span><span> </span><span class="constant constant_numeric constant_numeric_rev">1</span><span> </span><span class="keyword keyword_control keyword_control_rev">line</span>
<span>      </span><span class="keyword keyword_control keyword_control_rev">if</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">result</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">=</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">""</span><span> </span><span class="keyword keyword_control keyword_control_rev">or</span><span> </span><span class="keyword keyword_control keyword_control_rev">the</span><span> </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">result</span><span> </span><span class="keyword keyword_operator keyword_operator_symbolic keyword_operator_symbolic_rev">=</span><span> </span><span class="string string_quoted string_quoted_double string_quoted_double_transcript">"timed out"</span><span> then</span>
<span>         </span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_rev">-- something to add</span>
<span>         </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">put</span><span> it </span><span class="keyword keyword_control keyword_control_rev">after</span><span> tReturn</span>
<span>      </span><span class="keyword keyword_control keyword_control_rev">else</span>
<span>         </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">close</span><span> </span><span class="keyword keyword_control keyword_control_rev">process</span><span> pProcess</span>
<span>         </span><span class="entity entity_name entity_name_handler entity_name_handler_rev">return</span><span> tReturn</span>
<span>      </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">if</span>
<span>   </span><span class="keyword keyword_control keyword_control_rev">end</span><span> </span><span class="keyword keyword_control keyword_control_rev">repeat</span>
<span class="keyword keyword_control keyword_control_rev">end</span><span> executeProcess</span>