2014-12-31 34 views
5

Próbuję określić bieżącą strefę czasową dla systemu Windows. Poniższy fragment kodu jest (luźno) na podstawie odpowiedzi przez @MattJohnson w tym wątku: Getting local timezone identifier when OS display language is non-englishHKLM SYSTEM CurrentControlSet Control TimeZoneInformation TimeZoneKeyName jest uszkodzone?

using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(
            @"SYSTEM\CurrentControlSet\Control\TimeZoneInformation")) 
    { 
     if (registryKey != null) 
     { 
      string windowsTimeZoneId = registryKey.GetValue("TimeZoneKeyName") as string; 
      if (string.IsNullOrEmpty(windowsTimeZoneId)) 
      windowsTimeZoneId = registryKey.GetValue("StandardName") as string; 
      if (!string.IsNullOrEmpty(windowsTimeZoneId)) 
      { 
      int i = windowsTimeZoneId.IndexOf('\0'); 
      if (i != -1) 
       windowsTimeZoneId = windowsTimeZoneId.Remove(i); 
      return ConvertFromWindowsId(windowsTimeZoneId); 
      } 
     } 
    } 

Gdybym umieścić punkt przerwania na pierwszej linii „if (string.IsNullOrEmpty (windowsTimeZoneId))”, to to co widzę w Visual Studio debugera:

enter image description here

Co tu się dzieje? RegistryKey.GetValue() zwraca łańcuch w ramce, ale dlaczego nie wykrywa dwóch heksów 00 bajtów i kończy tam łańcuch?

Do tej pory testowałem to na dwóch moich komputerach. Wynika to z wersji 64-bitowej systemu Windows 7. Drugi, z systemem Windows 7 32-bitowym, jest taki sam, z tym że mówi, że długość zwracanego ciągu wynosi 128 znaków zamiast 127.

Patrząc na wpis rejestru z regedit.exe wygląda dobrze, pokazano tylko "Romansowy czas standardowy".

Trochę Googlingów zadało to pytanie. https://social.msdn.microsoft.com/Forums/sqlserver/en-US/eca7ad76-c910-46be-8fb9-876c7cde5c69/registry-read-time-zone-info-differ-when-code-build-on-40-framework-on-host-system-win-7-64-bit?forum=csharpgeneral W przeciwnym razie nie mogę znaleźć niczego.

Program jest tworzony przy pomocy Visual Studio 2012 i kierowania na .Net 2.0.

Jak widać, dodałem kod, aby uwzględnić ten "uszkodzony" wynik, ale mimo to byłbym wdzięczny, gdyby ktoś mógł mi wyjaśnić, co się tutaj dzieje, a może nawet jak uniknąć cały problem.

EDIT:

Program jest zbudowany z Visual Studio 2012 i .NET 2.0 kierowania.

Hmm, fabuła gęstnieje. To stwierdzenie nie było całkowicie poprawne. Przedstawiony powyżej kod powyższego kodu znajduje się w zespole biblioteki, który jest zbudowany w celu kierowania na .Net 2.0, ale był wywoływany z programu skierowanego do .Net 4.0. Teraz próbowałem wywoływać go z programu, który celuje w .Net 2.0, i nie ma problemu, RegistryKey.GetValue() po prostu zwraca "Romans standardowy czas". Wygląda więc na to, że ma on coś wspólnego z .Net Framework 4.0, co sugeruje post na MSDN.

EDIT 2 - Zaczynam myśleć, że jest to „normalne”

Jest to temat off-bit do SO, ale będę wdzięczny, jeśli ktoś by przyjrzeć się moim powiązanej delegowania nad na superużytkownika. com, skoro nie dostaję tam natychmiastowej satysfakcji, i chciałbym to rozwiązać, więc wiem, czy powinienem nadal panikować, czy nie. Dzięki.

https://superuser.com/questions/859031/possible-malware-modification-of-windows-registry-entry

+0

Bardzo interesujące szczegóły. Należy również pamiętać, że Romans standardowy obowiązuje w Europie - nie w Meksyku. Więc nie ma sposobu, aby to zrobić celowo, ponieważ wartości nie są powiązane w tym samym ciągu. –

+0

@Matt: Podejrzewam, że nadmiar danych jest losowy, tylko cokolwiek się stało w pamięci, gdy przydzielono bufor. Wygląda na to, że robi to sam system Windows; jeśli usuniemy nadmiarową zawartość, a następnie zmienię strefę czasową, pojawi się ona ponownie. Wygląda jak za każdym razem te same dane, ale nie próbowałem ponownie uruchomić komputera, aby sprawdzić, czy to wygląda inaczej. –

Odpowiedz

2

Kiedy ciąg lub wartość multi-ciąg jest ustawiony w rejestrze systemu Windows nie sprawdza semantykę; po prostu przechowuje dowolną zawartość binarną o długości określonej przez programistę. Oznacza to, że ciąg może być przedwcześnie zakończony znakiem NUL, lub odwrotnie, w ogóle nie zakończony znakiem NUL. (Przy okazji, ma to wpływ na bezpieczeństwo: podczas gdy nie wydaje mi się, że przedwczesne zakończenie zerowania może stanowić zagrożenie, natywny kod, który nie poradzi sobie z przypadkiem, w którym łańcuch nie jest zakończony znakiem null.)

Według Hansa (w jego usuniętej odpowiedzi) wersje .NET przed 4.x zignorowałyby dodatkowe dane, jeśli ciąg znaków zostanie przedwcześnie zakończony wartością NULL, podczas gdy 4.x zawiera go. Dlatego właśnie zauważyłeś problem dopiero po rozpoczęciu używania 4.x.

Co do tego, dlaczego ta konkretna wartość została przedwcześnie zniesiona, wydaje się, że to niedbalstwo ze strony Microsoftu. Jeśli usuniesz dodatkowe dane, a następnie zmienisz strefę czasową, dodatkowe dane pojawią się ponownie. Wygląda więc na to, że sam system Windows to robi. Dane wyglądają na losowe, więc nie sądzę, że są one zamierzone. W rzeczywistości może to technicznie stanowić podatność na ujawnienie danych, chociaż prawdopodobnie nie ma praktycznego wpływu.

Proponuję wyszukać wartość pustą i skrócić ciąg znaków, jeśli to konieczne. Mogą zaistnieć sytuacje, w których nie ma takiej sytuacji, np. Jeśli wpis został zmodyfikowany przez kod innej firmy, lub jeśli MS ostatecznie wyda aktualizację i rozwiąże problem lub, oczywiście, jeśli używasz programu. NET 2.x. Musisz więc zająć się obydwoma sprawami.

(Jeśli będę mieć czas, kiedy wrócę do pracy w przyszłym tygodniu, zainstaluję czystą kopię systemu Windows na maszynie wirtualnej i potwierdzę, że problem istnieje bez absolutnie żadnego oprogramowania innych firm. Jeśli tak, to rozważ zgłoszenie - wątpię, że MS wyda poprawkę, ale może zostać naprawione w przyszłej wersji systemu Windows.)

+0

Dziękuję bardzo za sprawdzenie tego i za dobre wyjaśnienie. Teraz znowu mogę spać spokojnie. (Odpowiedź Hansa bardzo mnie zdenerwowała i już miałem skontaktować się z nowym klientem i ostrzec ich, że mogłem nieumyślnie zainfekować ich około 300 komputerów niewykrywalnym wirusem, co sprawiłoby, że stałbym się bardzo popularny wśród nich). – RenniePet