Wednesday, December 29, 2010

How to start a new process de-elevated after installation

I was trying to launch an application at the end of an installation I’ve created with Visual Studio. My problem was that the installation is running with elevated privileges as administrator (UAC) and I want the application to run as a normal user.

One problem with the application that was launched by the installer was that when reading and writing to the registry it ended up at HKEY_USERS\.DEFAULT instead of HKEY_CURRENT_USER. I noticed that the process was run by NT AUTHORITY\SYSTEM instead of the expected COMPUTERNAME\USERNAME. This will also cause problems if you want to open a webpage after the installation and there is no current Web Browser running.

I knew how to elevate the process using the verb runas.

p.StartInfo.UseShellExecute = true; p.StartInfo.Verb = "runas";

But I could not find any way to use the verb to de-elevate. I searched for a solution online but could only find convoluted ways like using CreateProcessAsUserW, Code Injection in the shell process or using the task scheduler to register a task to run as the currently logged on desktop user.

I found this post and tried using the User Account Control Helpers to no avail for some reason.

Process p = UacHelpers.UserAccountControl.CreateProcessAsStandardUser("notepad.exe", "");

Eventually I came up with this simple C# code thinking it might do the trick. It actually runs the new program with reduced permissions but not as the intended user. This could be useful in other situations though.

Process p = new Process(); p.StartInfo.FileName = "runas.exe"; p.StartInfo.WindowStyle = ProcessWindowStyle.Normal; p.StartInfo.Arguments = "/trustlevel:0x20000 notepad.exe"; p.Start();

Unfortunately it didn’t help me here.

I then turned back to the UacHelpers source code and commented out these rows because I noticed that the process was not really elevated from the start so I did not want the simple way to start the process.

//if (!IsCurrentProcessElevated) //{ // return Process::Start(exePath, arguments); //}

Using this trick it was possible to have an application like my setup that runs with administrator privileges (thanks to UAC) to start another process with standard user privileges and as the expected user.

For more details on the subject see also Aaron Margosis’ WebLog.

Please comment if this helps you or if you have any related suggestions on better approach.

Monday, December 20, 2010

Error 1001. InstallUtilLib.dll: Unknown error.

During uninstallation this error can show up: Error 1001. InstallUtilLib.dll: Unknown error.

The solution can be to installing a newer version of .NET Framework.

Thursday, December 16, 2010

Error 1001 The specified service does not exist as an installed service

If you run into this problem trying to uninstall an application that includes as service like JTB FlexReport this post might help.

Error 1001. An exception occurred while uninstalling. This exception will be ignored and the uninstall will continue. However the application might not be fully uninstalled after the uninstall is complete. --> The specified service does not exist as an installed service

Still the uninstallation rolls back.

Try repair of the installation and then uninstall again.

Another workaround can be to manually install the service like this:
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe" "C:\Program Files\JTB World\JTB FlexReport\JTBFlexServ.exe"
alternatively depending on what .NET Framework version you have installed:
"C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe" "C:\Program Files\JTB World\JTB FlexReport\JTBFlexServ.exe"

Other indications of this problem can be seen in the Event Viewer.

“The description for Event ID 11001 from source MsiInstaller cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.

If the event originated on another computer, the display information had to be saved with the event.

The following information was included with the event:

Product: JTB FlexReport Core Service -- Error 1001. Error 1001. An exception occurred while uninstalling. This exception will be ignored and the uninstall will continue. However, the application might not be fully uninstalled after the uninstall is complete. --> The specified service does not exist as an installed service (NULL) (NULL) (NULL) (NULL) (NULL) the message resource is present but the message is not found in the string/message table”

Followed by this Information Event ID 11725: Product: JTB FlexReport Core Service -- Removal failed.

If uninstalling still fails try msizap. It's an unsupported utility that lets you browse and remove stuff from the MSI registry. It won't actually uninstall, just clean things up.
Search for MsiZap.exe on  http://www.microsoft.com or at http://msdn.microsoft.com/en-us/library/aa370523.aspx

See also Error 1001. The specified service already exists

Monday, December 13, 2010

SSMPropEditor paid for itself on its first use

I got this comment from a customer today: “We work across a network drive which really slows sheet set manager down, your product has already paid for itself on it's first use.”

If you use AutoCAD’s Sheet Set Manager you might find that some tasks can be very time consuming and tedious.

Say you have Properties that holds information for sheet revisions like the revision, date, name and revision description. If you now have a bunch of sheets that you want to update to a new revision you need to do it one by one within SSM.

SSMPropEditor comes to help making it possible to select one, many or all sheets in a sheet set and update all properties at once. Even if the revisions are different they can easily be incremented automatically to the next revision number.

Contact us to get a time limited license file for free or purchase with a price per license of only 25 EUR or less depending on the total number of licenses purchased.

JTB FlexReport reporting by project and IP

Work is progressing to improve JTB FlexReport our application and license usage report solution with the functionality to report usage by project. The module JTB Process Monitor will be used for this purpose as a client needs to be running on each computer that will be monitored to allow the user to assign a project for each running session of an application.

In the example above it is specified that that when AutoCAD, AutoCAD LT and Revit are started a dialog box will be showed asking about what project that session should be on.

This does also work when the client is offline like a laptop typically is and when connected to the network the Process Monitor client will report to the server the usage.

After that it will be possible to create reports on how many hours users have been using different application for each project.

Another news for next JTB FlexReport version is that host IP (both IPv4 and IPv6) will be recorded so it for example can be used to create host groups based on IP. One group could be IP numbers starting with 192 and another group IP numbers starting with 172.

Work is also progressing to support LM-X, Sentinel, Safenet, HASP, Elan network license systems.

If you’re interested in beta testing any of these coming features Contact us and let us know what you’re interested in and as soon as the beta is ready we will let you know.

If you instead want a free trial of the current released version of JTB FlexReport Contact us for a license to activate the time limited fully functional version.

Sunday, December 12, 2010

Windows Live Writer 2011 picture quality bug

I became aware of this bug today that happens with WLW 2011.

In some cases when an image is added the quality is not perfect as expected. Below is what it look like at first showing a blurry result.

For now there seems to at least be some workaround and that is to click on Original picture size or change the size a bit and back to the size it should be.

I have been able to reproduce this by having resized a large image to a smaller size and then used the Set to default button. The problem as seen in the image above is that even images that are inserted in original size are affected.

I hope Microsoft can release a fix for this and some of the other known bugs soon.

  • Link to source picture problem: Sometimes when I have pictures set to link to source picture I find that the published picture on the blog is with no link and cannot be clicked on to open up the larger version of the picture.
  • Windows Live Writer 2011 bug and wish describing a problem with QAT.
  • Clear formatting button is clearing some of the formatting on the whole post and not just the selection. The description says: “Change the selection to plain text by clearing all of the formatting. One thing I found is if some of the paragraphs in the post are centered and I select a link that I pasted in that has another HTML style like Heading 5 and press Clear formatting all centered paragraphs are aligned to the left.
  • There are unsaved changes to this post problem

Note also that A new build (15.4.3508.1109) of Windows Live Writer 2011 was released December 1, 2010 and can be downloaded from explore.live.com/windows-live-writer.

If you have any wishes for WLW features or bug fixes leave a comment on Microsoft’s Aaron’s Live Writer Blog.

Thursday, December 9, 2010

Automated uninstallation of AutoCAD with VBScript

This will completely remove AutoCAD 2011 and related plug-ins.

The VBScript will detect and uninstall 32-bit or 64-bit versions of English AutoCAD 2011 and language pack.  It will also provide the option to uninstall the following plug-ins (if found):

  • AutoCAD 2011 Subscription Advantage Pack
  • AutoCAD WS plug-in for AutoCAD 2011
  • AutoCAD 2011 VBA Enabler

If you have multiple AutoCAD 2011-based products installed, these modules may be in use by more than just AutoCAD 2011.  Do not uninstall them if they could be in use elsewhere.

The VBScript will then remove folders and registry keys related to the uninstalled product and plug-ins.

See KB: TS16077500

'============================================================================ ' Uninstall_ACAD_2011.vbs ' This script is designed to uninstall AutoCAD 2011 and remove installed plug-ins ' ' Copyright © 2010 by Autodesk, Inc. All Rights Reserved. ' ' You are hereby granted permission to use, copy and modify this ' software without charge, provided you do so exclusively for ' your own use or for use by others in your organization in the ' performance of their normal duties, and provided further that ' the above copyright notice appears in all copies and both that ' copyright notice and the limited warranty and restricted rights ' notice below appear in all supporting documentation. ' ' Incorporation of any part of this software into other software, ' except when such incorporation is exclusively for your own use ' or for use by others in your organization in the performance of ' their normal duties, is prohibited without the prior written ' consent of Autodesk, Inc. ' ' Copying, modification and distribution of this software or any ' part thereof in any form except as expressly provided herein is ' prohibited without the prior written consent of Autodesk, Inc. ' ' AUTODESK PROVIDES THIS SOFTWARE "AS IS" AND WITH ALL FAULTS. ' AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF ' MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, ' INC. DOES NOT WARRANT THAT THE OPERATION OF THE SOFTWARE ' WILL BE UNINTERRUPTED OR ERROR FREE. ' ' Restricted Rights for US Government Users. This software ' and Documentation are provided with RESTRICTED RIGHTS for US ' US Government users. Use, duplication, or disclosure by the ' Government is subject to restrictions as set forth in FAR ' 12.212 (Commercial Computer Software-Restricted Rights) and ' DFAR 227.7202 (Rights in Technical Data and Computer Software), ' as applicable. Manufacturer is Autodesk, Inc., 111 McInnis ' Parkway, San Rafael, California 94903. ' '============================================================================ Option Explicit On Error Resume Next dim bProdFound, b64bitOS, bRemovePlugins dim strInstallFolder, strProductName, strMainProductName dim strTitle, strMsg dim languageCode, languageAbbv dim heroProductPrefix, heroProductSuffix dim objShell dim intMsgRet dim x64products(4) dim x86products(4) const HKEY_CURRENT_USER = &H80000001 const HKEY_LOCAL_MACHINE = &H80000002 '============================================================================ ' set the GUID prefix and suffix for the main product being uninstalled heroProductPrefix = "{5783F2D7-9001" heroProductSuffix = "0060B0CE6BBA}" ' set the product language code and abbreviation ' English languageCode = "409" languageAbbv = "enu" '============================================================================ ' initialize the arrays with the GUIDs and names for all products we may need to uninstall ' AutoCAD 2011 English (x64) x64products(0) = heroProductPrefix & "-0" & languageCode & "-0102-" & heroProductSuffix ' AutoCAD 2011 English language pack (x64) x64products(1) = heroProductPrefix & "-0" & languageCode & "-1102-" & heroProductSuffix ' AutoCAD 2011 Subscription Advantage Pack (x64) x64products(2) = "{ADF5CB42-ACFD-41EF-0133-871E54505C1D}" ' AutoCAD WS plug-in for AutoCAD 2011 (x64) x64products(3) = "{BF780694-C47E-4122-0196-B89B22F3387C}" ' AutoCAD 2011 VBA Enabler (x64) x64products(4) = "{68519E09-4927-46AE-01E2-8D60D0CF41BC}" ' AutoCAD 2011 English (x86) x86products(0) = heroProductPrefix & "-0" & languageCode & "-0002-" & heroProductSuffix ' AutoCAD 2011 English language pack (x86) x86products(1) = heroProductPrefix & "-0" & languageCode & "-1002-" & heroProductSuffix ' AutoCAD 2011 Subscription Advantage Pack (x86) x86products(2) = "{42E572CC-6D4C-4A3E-B937-7594D36B2B44}" ' AutoCAD WS plug-in for AutoCAD 2011 (x86) x86products(3) = "{B96F1390-23DD-4002-B183-EF0560D784E9}" ' AutoCAD 2011 VBA Enabler (x86) x86products(4) = "{ED7DFC69-2B9A-4A1F-9F50-8AB89B688EBA}" 'initialize status variants bProdFound = False b64bitOS = False bRemovePlugins = False ' start by determing if we have a valid product installed Set objShell = CreateObject("Wscript.Shell") ' look for the x64 version first bProdFound = getProductInfo(x64products(0), False) b64bitOS = bProdFound ' if we didn't find it, look for the x86 version if bProdFound = False then bProdFound = getProductInfo(x86products(0), False) end if ' if we found an installed product, report it and get uninstall confirmation if bProdFound then strTitle = "AutoCAD 2011 Uninstall Script" strMainProductName = strProductName ' get approval to uninstall AutoCAD intMsgRet = uninstallACAD2011WarningMsg() ' if the user approved uninstall, proceed if intMsgRet = vbYes Then ' get approval to uninstall plugins intMsgRet = uninstallPluginsWarningMsg() ' if the user did not cancel the whole operation, proceed if intMsgRet <> vbCancel then if intMsgRet = vbYes Then bRemovePlugins = True end if if b64bitOS = True then uninstallProducts(x64products) else uninstallProducts(x86products) end if deleteProductFolders() deleteProductRegKeys() strMsg = strMainProductName & " Uninstall Complete." & Vbcrlf & Vbcrlf & _ "We recommend restarting your system to help ensure complete cleanup." intMsgRet = msgbox(strMsg, vbOkonly+VBExclamation, strTitle) end if end if Else strMsg = "No installation of AutoCAD 2011 was found." intMsgRet = msgbox(strMsg, vbOkonly+VBExclamation, strTitle) end if '============================================================================ ' uninstall each product code it finds '============================================================================ function uninstallProducts(aProductList) dim pos, retVal dim installer : Set installer = nothing dim strGUID, strModuleName Const msiUILevelBasic = 3 '/qb Const msiUILevelHideCancel = 32 '/! Const msiInstallStateAbsent = 2 On Error Resume Next Err.Clear Set installer = CreateObject("WindowsInstaller.Installer") installer.UILevel = msiUILevelBasic + msiUILevelHideCancel for pos = 0 to UBound(aProductList) strGUID = aProductList(pos) retVal = getProductInfo(strGUID, True) if retVal = True then strModuleName = strProductName if installer.productstate (strGUID) > 0 Then ' if the user did not approve removal of plug-ins, bail if pos > 1 and bRemovePlugins = False then Exit For end If 'WScript.Echo "Uninstalling " & strGUID & Vbcrlf & Vbcrlf & strModuleName installer.ConfigureProduct strGUID, 65535, msiInstallStateAbsent if Err.Number <> 0 then WScript.Echo "Error uninstalling " & strModuleName & Vbcrlf & Vbcrlf & _ "Error: " & Err.Number & " - " & Err.Description Err.Clear Else 'WScript.Echo "Uninstalled " & strModuleName end if end if end if next set installer = Nothing end function '============================================================================ ' delete folders '============================================================================ function deleteProductFolders() dim pos dim loopCtr dim sUsrProfile dim productFolders(6) dim objFileSys On Error Resume Next Set objFileSys = CreateObject("Scripting.FileSystemObject") 'Expand Environment sUsrProfile = objShell.ExpandEnvironmentStrings("%UserProfile%") ' actual installation location as retrieved from registry productFolders(0) = strInstallFolder ' windows vista/win7 related AutoCAD program paths productFolders(1) = "C:\ProgramData\Autodesk\AutoCAD 2011\R18.1\" & languageAbbv productFolders(2) = sUsrProfile & "\AppData\Local\Autodesk\AutoCAD 2011\R18.1\" & languageAbbv productFolders(3) = sUsrProfile & "\AppData\Roaming\Autodesk\AutoCAD 2011\R18.1\" & languageAbbv ' windows XP related AutoCAD program paths productFolders(4) = sUsrProfile & "\Application Data\Autodesk\AutoCAD 2011\R18.1\" & languageAbbv productFolders(5) = sUsrProfile & "\Local Settings\Application Data\Autodesk\AutoCAD 2011\R18.1\" & languageAbbv productFolders(6) = "C:\Documents and Settings\All Users\Application Data\Autodesk\AutoCAD 2011\R18.1\" & languageAbbv Err.Clear for pos = 0 to UBound(productFolders) loopCtr = 0 ' delete the folder within a 30-second loop to account for system lock issues do While objFileSys.FolderExists(productFolders(pos)) And loopCtr < 6 objFileSys.DeleteFolder productFolders(pos), True if Err.Number <> 0 then WScript.Echo "Folder not deleted: " & productFolders(pos) & Vbcrlf & Vbcrlf & _ "Error: " & Err.Number & " - " & Err.Description Err.Clear WScript.Sleep 5000 ' sleep 5 seconds loopCtr = loopCtr + 1 Else 'WScript.Echo "Folder deleted: " & productFolders(pos) end if Loop next Set objFileSys = Nothing end function '============================================================================ ' delete registry keys for the specific installed product and language '============================================================================ function deleteProductRegKeys() dim pos dim HKCURegKeys(3) dim HKLMRegKeys(3) HKCURegKeys(0) = "Software\Autodesk\AutoCAD\R18.1\ACAD-9001:" & languageCode HKCURegKeys(1) = "Software\Autodesk\AutoCAD\R18.1\AutoCAD 2011 Subscription Advantage Pack" HKCURegKeys(2) = "Software\Autodesk\AutoCAD\R18.1\AutoCAD 2011 VBA Enabler" HKCURegKeys(3) = "Software\Autodesk\AutoCAD\R18.1\AutoCAD WS plug-in for AutoCAD 2011" HKLMRegKeys(0) = "Software\Autodesk\AutoCAD\R18.1\ACAD-9001:" & languageCode ' the following modules are English-only so the language code is hard-coded HKLMRegKeys(1) = "Software\Autodesk\AutoCAD 2011 Subscription Advantage Pack:409" HKLMRegKeys(2) = "Software\Autodesk\AutoCAD 2011 VBA Enabler:409" HKLMRegKeys(3) = "Software\Autodesk\AutoCAD WS plug-in for AutoCAD 2011:409" ' delete the AutoCAD product reg keys deleteRegKey HKEY_CURRENT_USER, HKCURegKeys(0) deleteRegKey HKEY_LOCAL_MACHINE, HKLMRegKeys(0) ' delete the AutoCAD EULA reg key deleteRegKey HKEY_LOCAL_MACHINE, "Software\Autodesk\AutoCAD 2011 - English" if bRemovePlugins then for pos = 1 to UBound(HKCURegKeys) deleteRegKey HKEY_CURRENT_USER, HKCURegKeys(pos) deleteRegKey HKEY_LOCAL_MACHINE, HKLMRegKeys(pos) next end if end function '============================================================================ ' delete registry key '============================================================================ sub deleteRegKey(rootKey, delKey) dim strComputer, strRootKey dim objRegistry : set objRegistry = Nothing strComputer = "." On Error Resume Next Err.Clear if rootKey = HKEY_CURRENT_USER then strRootKey = "HKCU\" else strRootKey = "HKLM\" end if Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &_ strComputer & "\root\default:StdRegProv") if regKeyFound(strRootKey & delKey & "\") Then objRegistry.DeleteKey rootKey, delKey if Err.Number <> 0 then WScript.Echo "DeleteKey failed: " & delKey & Vbcrlf & Vbcrlf & _ "Error: " & Err.Number & " - " & Err.Description Err.Clear else 'Wscript.Echo "Deleted: " & strRootKey & delKey End If Else 'WScript.Echo "Key not found: " & strRootKey & delKey End If Set objRegistry = Nothing end sub '============================================================================ ' search for installed product and get the installation folder and name '============================================================================ function getProductInfo(prodCode, bNameOnly) dim strKeyPath, strValueName, strComputer dim objRegistry : set objRegistry = Nothing strComputer = "." Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &_ strComputer & "\root\default:StdRegProv") strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & prodCode ' determine if the product is installed if regKeyFound("HKLM\" & strKeyPath & "\") Then ' Get the name of the product being uninstalled strValueName = "DisplayName" objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strProductName if bNameOnly = False then strKeyPath = "SOFTWARE\Autodesk\AutoCAD\R18.1\ACAD-9001:" & languageCode if regKeyFound("HKLM\" & strKeyPath & "\") Then ' Get the actual installation location before uninstalling strValueName = "AcadLocation" objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strInstallFolder End If end if getProductInfo = True Else getProductInfo = False End If Set objRegistry = Nothing end function '============================================================================ ' returns true if a registry key exists '============================================================================ function regKeyFound(regkey) Dim retVal On Error Resume Next Err.Clear retVal = objShell.RegRead(regkey) if Err.Number <> 0 then 'WScript.Echo "Error reading key: " & regkey & Vbcrlf & Vbcrlf & _ ' "Error: " & hex(Err.Number) & " - " & Err.Description Err.Clear regKeyFound = False else regKeyFound = True End If end function '============================================================================ ' display the initial warning message and get OK to continue '============================================================================ function uninstallACAD2011WarningMsg() dim strMsg strMsg = "WARNING!" & Vbcrlf & Vbcrlf & _ strMainProductName & " is currently installed at" & Vbcrlf & _ strInstallFolder & Vbcrlf & Vbcrlf & _ "This script will remove " & strMainProductName & " and related folders and registry keys from your computer." & Vbcrlf & Vbcrlf & _ "This script should be run an as Administrator and we strongly recommend backing up any custom files before proceeding." & Vbcrlf & Vbcrlf & _ "Do you want to continue?" uninstallACAD2011WarningMsg = msgbox(strMsg, vbYesNo+VBExclamation, strTitle) end function '============================================================================ ' get the OK to uninstall plug-ins '============================================================================ function uninstallPluginsWarningMsg() dim strMsg strMsg = "This script can also remove the VBA Enabler," & Vbcrlf & _ "Subscription Advantage Pack, and WS Plug-in." & Vbcrlf & Vbcrlf & _ "These modules should NOT be uninstalled if they" & Vbcrlf & _ "are shared by another AutoCAD installation." & Vbcrlf & Vbcrlf & _ "Do you want to uninstall these modules?" uninstallPluginsWarningMsg = msgbox(strMsg, vbYesNoCancel+VBExclamation, strTitle) end function

Wednesday, December 8, 2010

The AutoCAD Network Administrator's Bible, 2011 Edition

David M. Stein that wrote the great Visual LISP Developer's Bible has put together The AutoCAD Network Administrator's Bible, 2011 Edition. Both available for Kindle devices and Kindle Reader apps (no Kindle needed, just the free Kindle for PC App).
Building AutoCAD 2011 network deployments, configuring folder and share permissions, customizing deployments, packaging tips, scripting tips, FlexLM and FlexNet Manager issues, including Single, Redundant, and Distributed server models, deployment using Microsoft System Center Configuration Manager 2007 R2, utilities for diagnostics and deployment management, troubleshooting tips and more! See also this Book Sample in PDF format.
You can get it on Amazon and I have no doubt that it can be worth it as David has a lot of experience deploying AutoCAD in a large enterprise.

Via Skatterbrainz Blog.

For more Learning Resources.

Tuesday, November 30, 2010

Autodesk University Virtual 2010

Right now I’m attending AU Virtual 2010 where the General Session keynote is running.

Here’s how we might be able to access space with the help of a microwave beam at 140 GHz.

More at Escape Dynamics

Inventor Fusion will be shipped along with AutoCAD for free. Via Deelip.com.

Factory Layout Optimization for AutoCAD is free to try via Autodesk Labs.

Factory Layout Optimization for AutoCAD Tech Preview

BIM

Autodesk TinkerBox seems like a fun game for iPad\iPhone\iPod that soon will be released.

Tinkerbox is an app that will be available for iPhone, iPod and iPad that is designed to bring engineering challenges and education to users of all ages in a 'game' like environment. There are various challenges, each one getting slightly tougher where users have to solve engineering problems like getting ball-bearings from one point to another using motors, plates, fasteners, rope, chains, conveyors etc. The intuitive interface allows you to drag and drop components from your toolbox into the working area to build a process. If you're not sure what something is or how it works, just use the interactive help to learn more about a motor for example. Via Autodesk Manufacturing Blog.

Autodesk TinkerBox

Some of the latest blog posts

Subscribe to RSS headline updates from:
Powered by FeedBurner

Contact Us | About JTB World | Subscribe to this blog
JTB World's website | Website General Terms of Use | Privacy Policy
^ Top of page

© 2004- JTB World. All rights reserved.